* Re: [PATCH v11 02/17] Add a new struct for device to manipulate external buffer.
From: Ben Hutchings @ 2010-09-27 13:41 UTC (permalink / raw)
To: xiaohui.xin; +Cc: netdev, kvm, linux-kernel, mingo, davem, herbert, jdike
In-Reply-To: <c6751a0126ef4d3d1ce75e596ccf9cebd9757052.1285385607.git.xiaohui.xin@intel.com>
On Sat, 2010-09-25 at 12:27 +0800, xiaohui.xin@intel.com wrote:
> From: Xin Xiaohui <xiaohui.xin@intel.com>
>
> Signed-off-by: Xin Xiaohui <xiaohui.xin@intel.com>
> Signed-off-by: Zhao Yu <yzhao81new@gmail.com>
> Reviewed-by: Jeff Dike <jdike@linux.intel.com>
> ---
> include/linux/netdevice.h | 22 +++++++++++++++++++++-
> 1 files changed, 21 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index fa8b476..ba582e1 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -530,6 +530,25 @@ struct netdev_queue {
> unsigned long tx_dropped;
> } ____cacheline_aligned_in_smp;
>
> +/* Add a structure in structure net_device, the new field is
> + * named as mp_port. It's for mediate passthru (zero-copy).
That belongs in the commit message.
> + * It contains the capability for the net device driver,
> + * a socket, and an external buffer creator, external means
> + * skb buffer belongs to the device may not be allocated from
> + * kernel space.
Who sets which fields in this structure? Can you make this a kernel-doc
comment specifying the use of each field?
Ben.
> + */
> +struct mpassthru_port {
> + int hdr_len;
> + int data_len;
> + int npages;
> + unsigned flags;
> + struct socket *sock;
> + int vnet_hlen;
> + struct skb_ext_page *(*ctor)(struct mpassthru_port *,
> + struct sk_buff *, int);
> + struct skb_ext_page *(*hash)(struct net_device *,
> + struct page *);
> +};
>
> /*
> * This structure defines the management hooks for network devices.
> @@ -952,7 +971,8 @@ struct net_device {
> struct macvlan_port *macvlan_port;
> /* GARP */
> struct garp_port *garp_port;
> -
> + /* mpassthru */
> + struct mpassthru_port *mp_port;
> /* class/net/name entry */
> struct device dev;
> /* space for optional device, statistics, and wireless sysfs groups */
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [GIT PULL net-2.6] vhost-net: last minute fix
From: Michael S. Tsirkin @ 2010-09-27 13:34 UTC (permalink / raw)
To: David Miller; +Cc: kvm, virtualization, netdev, linux-kernel
David,
The following tree includes a last minute bugfix for vhost-net.
It is on top of net-2.6. Please merge it for 2.6.36.
Thanks!
The following changes since commit 2cc6d2bf3d6195fabcf0febc192c01f99519a8f3:
ipv6: add a missing unregister_pernet_subsys call (2010-09-26 19:09:25 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git vhost-net
Michael S. Tsirkin (1):
vhost: fix log ctx signalling
drivers/vhost/vhost.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
^ permalink raw reply
* [PATCH] tproxy: check for transparent flag in ip_route_newports
From: Ulrich Weber @ 2010-09-27 13:31 UTC (permalink / raw)
To: davem; +Cc: netdev
as done in ip_route_connect()
Signed-off-by: Ulrich Weber <uweber@astaro.com>
---
include/net/route.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/net/route.h b/include/net/route.h
index bd732d6..7e5e73b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -199,6 +199,8 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
fl.fl_ip_sport = sport;
fl.fl_ip_dport = dport;
fl.proto = protocol;
+ if (inet_sk(sk)->transparent)
+ fl.flags |= FLOWI_FLAG_ANYSRC;
ip_rt_put(*rp);
*rp = NULL;
security_sk_classify_flow(sk, &fl);
--
1.7.1
^ permalink raw reply related
* Re: [PATCH -next 2/4] ip_gre: percpu stats accounting
From: Ben Hutchings @ 2010-09-27 13:29 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1285583707.23938.93.camel@edumazet-laptop>
On Mon, 2010-09-27 at 12:35 +0200, Eric Dumazet wrote:
> Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets.
>
> Other seldom used fields are kept in netdev->stats structure, possibly
> unsafe.
>
> This is a preliminary work to support lockless transmit path, and
> correct RX stats, that are already unsafe.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> net/ipv4/ip_gre.c | 138 +++++++++++++++++++++++++++++++-------------
> 1 file changed, 99 insertions(+), 39 deletions(-)
>
> diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
> index 5d6ddcb..de39b22 100644
> --- a/net/ipv4/ip_gre.c
> +++ b/net/ipv4/ip_gre.c
[...]
> @@ -377,7 +405,7 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
> if (parms->name[0])
> strlcpy(name, parms->name, IFNAMSIZ);
> else
> - sprintf(name, "gre%%d");
> + strcpy(name, "gre%d");
>
> dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
> if (!dev)
[...]
This is a valid fix, but doesn't belong in this patch!
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Ulrich Weber @ 2010-09-27 13:11 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1285347509.2503.357.camel@edumazet-laptop>
Hi Eric,
thanks for the correction! Searched through the log files and discovered
that the initial "Neighbor overflow" message was caused by an IPv6 ping
scan from the Internet.
rt_garbage_collect() is called from dst_alloc and rt_intern_hash. In any
case no routes will be freed if the total entries are smaller than
ipv4.route.gc_thresh.
neigh.default.gc_thresh is static while ipv4.route.gc_thresh is based on
system memory. Wouldn't it make sense to set neigh.default.gc_thresh
based on system memory too?
Cheers
Ulrich
--
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany
^ permalink raw reply
* [PATCH] ipv6: add IPv6 to neighbour table overflow warning
From: Ulrich Weber @ 2010-09-27 13:22 UTC (permalink / raw)
To: davem; +Cc: netdev
IPv4 and IPv6 have separate neighbour tables, so
the warning messages should be distinguishable.
Signed-off-by: Ulrich Weber <uweber@astaro.com>
---
net/ipv6/route.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d126365..614f83e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -670,7 +670,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
if (net_ratelimit())
printk(KERN_WARNING
- "Neighbour table overflow.\n");
+ "IPv6 Neighbour table overflow.\n");
dst_free(&rt->dst);
return NULL;
}
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] sunrpc: prompt for RPCSEC_GSS_KRB5 even if NFS_V4 is enabled
From: Uwe Kleine-König @ 2010-09-27 12:54 UTC (permalink / raw)
To: Trond Myklebust
Cc: linux-kernel, J. Bruce Fields, Neil Brown, David S. Miller,
Randy Dunlap, linux-nfs, netdev
In-Reply-To: <1285587572.19362.2.camel@heimdal.trondhjem.org>
Hi Trond,
On Mon, Sep 27, 2010 at 07:39:32AM -0400, Trond Myklebust wrote:
> On Mon, 2010-09-27 at 12:41 +0200, Uwe Kleine-König wrote:
> > NFS_V4 works fine without RPCSEC_GSS_KRB5 (even without CRYPTO).
> > This dependency was introduced in
> >
> > df486a2 (NFS: Fix the selection of security flavours in Kconfig)
> >
> > to fix a build failure as RPCSEC_GSS_KRB5 was thought to be needed for
> > NFS_V4. The fix didn't work completely as NFS_V4 didn't enforce CRYPTO
> > and so the select on RPCSEC_GSS_KRB5 didn't work in all situations (e.g.
> > arm/mx1_defconfig).
> >
> > This was rectified by
> >
> > 827e345 (SUNRPC: Fix the NFSv4 and RPCSEC_GSS Kconfig dependencies)
> >
> > but the magic for RPCSEC_GSS_KRB5 introduced by df486a2 wasn't reverted.
> >
> > Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > ---
> > Hello,
> >
> > after Trond sent me the patch that later ended in 827e345702 I suggested
> > to fold the patch below into it[1], but without reaction and success as I
> > noticed just now. :-(
> >
> > Best regards
> > Uwe
>
> That's because you completely fail to justify why should we change the
> behaviour to suddenly make RPCSEC_GSS_KRB5 optional for NFSv4. That has
> never been the case before.
My intention is not to make "RPCSEC_GSS_KRB5 optional for NFSv4". First
I saw a build failure and then I wondered if the fix was optimal. After
reading the log of 827e345 I thought NFSv4 doesn't depend on
RPCSEC_GSS_KRB5, still more considering that 827e345 was your fix after
I suggested to select CRYPTO to enforce RPCSEC_GSS_KRB5 again.
Currently you can have NFSv4 without RPCSEC_GSS_KRB5 because if you
don't have CRYPTO RPCSEC_GSS_KRB5 is off, too, even if it defaults to
yes and there's no prompt. (Selecting would not work, too.)
And note that RPCSEC_GSS_KRB5 already selects SUNRPC_GSS, so 827e345
doesn't do anything useful if NFS_V4 really needs RPCSEC_GSS_KRB5.
So either we should really enforce RPCSEC_GSS_KRB5 if NFS_V4 is selected
(by letting one of these select CRYPTO, see e.g. my first patch, or by
letting NFS_V4 depend on CRYPTO) or make it optional in all cases (as it
is already now in some cases).
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH] fix TSO FACK loss marking in tcp_mark_head_lost
From: Ilpo Järvinen @ 2010-09-27 12:22 UTC (permalink / raw)
To: Yuchung Cheng; +Cc: David Miller, Netdev
In-Reply-To: <1285370526-18279-1-git-send-email-ycheng@google.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1159 bytes --]
On Fri, 24 Sep 2010, Yuchung Cheng wrote:
> When TCP uses FACK algorithm to mark lost packets in
> tcp_mark_head_lost(), if the number of packets in the (TSO) skb is
> greater than the number of packets that should be marked lost, TCP
> incorrectly exits the loop and marks no packets lost in the skb. This
> underestimates tp->lost_out and affects the recovery/retransmission.
> This patch fargments the skb and marks the correct amount of packets
> lost.
>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> ---
> net/ipv4/tcp_input.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index 1bc87a0..e4f472e 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -2532,7 +2532,8 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
> cnt += tcp_skb_pcount(skb);
>
> if (cnt > packets) {
> - if (tcp_is_sack(tp) || (oldcnt >= packets))
> + if ((tcp_is_sack(tp) && !tcp_is_fack(tp)) ||
> + (oldcnt >= packets))
> break;
>
> mss = skb_shinfo(skb)->gso_size;
>
Acked-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
--
i.
^ permalink raw reply
* Re: [PATCH] sunrpc: prompt for RPCSEC_GSS_KRB5 even if NFS_V4 is enabled
From: Trond Myklebust @ 2010-09-27 11:39 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, J. Bruce Fields, Neil Brown,
David S. Miller, Randy Dunlap, linux-nfs-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1285584120-16860-1-git-send-email-u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
On Mon, 2010-09-27 at 12:41 +0200, Uwe Kleine-König wrote:
> NFS_V4 works fine without RPCSEC_GSS_KRB5 (even without CRYPTO).
> This dependency was introduced in
>
> df486a2 (NFS: Fix the selection of security flavours in Kconfig)
>
> to fix a build failure as RPCSEC_GSS_KRB5 was thought to be needed for
> NFS_V4. The fix didn't work completely as NFS_V4 didn't enforce CRYPTO
> and so the select on RPCSEC_GSS_KRB5 didn't work in all situations (e.g.
> arm/mx1_defconfig).
>
> This was rectified by
>
> 827e345 (SUNRPC: Fix the NFSv4 and RPCSEC_GSS Kconfig dependencies)
>
> but the magic for RPCSEC_GSS_KRB5 introduced by df486a2 wasn't reverted.
>
> Cc: Trond Myklebust <Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> ---
> Hello,
>
> after Trond sent me the patch that later ended in 827e345702 I suggested
> to fold the patch below into it[1], but without reaction and success as I
> noticed just now. :-(
>
> Best regards
> Uwe
That's because you completely fail to justify why should we change the
behaviour to suddenly make RPCSEC_GSS_KRB5 optional for NFSv4. That has
never been the case before.
Trond
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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] 3c59x: fix regression from patch "Add ethtool WOL support"
From: Jan Beulich @ 2010-09-27 11:37 UTC (permalink / raw)
To: davem; +Cc: andrew, netdev
This patch (commit 690a1f2002a3091bd18a501f46c9530f10481463) added a
new call site for acpi_set_WOL() without checking that the function is
actually suitable to be called via
vortex_set_wol+0xcd/0xe0 [3c59x]
dev_ethtool+0xa5a/0xb70
dev_ioctl+0x2e0/0x4b0
T.961+0x49/0x50
sock_ioctl+0x47/0x290
do_vfs_ioctl+0x7f/0x340
sys_ioctl+0x80/0xa0
system_call_fastpath+0x16/0x1b
i.e. outside of code paths run when the device is not yet enabled or
already disabled. In particular, putting the device into D3hot is a
pretty bad idea when it was already brought up.
Furthermore, all prior callers of the function made sure they're
actually dealing with a PCI device, while the newly added one didn't.
In the same spirit, the .get_wol handler shouldn't indicate support
for WOL for non-PCI devices.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Cc: Andrew O. Shadoura <andrew@beldisplaytech.com>
---
drivers/net/3c59x.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- linux-2.6.36-rc5/drivers/net/3c59x.c
+++ 2.6.36-rc5-3c59x-WOL/drivers/net/3c59x.c
@@ -2942,6 +2942,9 @@ static void vortex_get_wol(struct net_de
{
struct vortex_private *vp = netdev_priv(dev);
+ if (!VORTEX_PCI(vp))
+ return;
+
wol->supported = WAKE_MAGIC;
wol->wolopts = 0;
@@ -2952,6 +2955,10 @@ static void vortex_get_wol(struct net_de
static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return -EOPNOTSUPP;
+
if (wol->wolopts & ~WAKE_MAGIC)
return -EINVAL;
@@ -3201,6 +3208,9 @@ static void acpi_set_WOL(struct net_devi
return;
}
+ if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
+ return;
+
/* Change the power state to D3; RxEnable doesn't take effect. */
pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
^ permalink raw reply
* Re: [patch] ipvs: Keep track of backlog connections
From: Simon Horman @ 2010-09-27 11:06 UTC (permalink / raw)
To: Sven Wegener
Cc: lvs-devel, netdev, Wensong Zhang, Julian Anastasov,
Venkata Mohan Reddy Koppula
In-Reply-To: <alpine.LNX.2.00.1009261629240.609@titan.stealer.net>
On Sun, Sep 26, 2010 at 04:31:49PM +0200, Sven Wegener wrote:
> On Sun, 26 Sep 2010, Simon Horman wrote:
>
> > here is an updated though as yet untested version of your patch from Julian
> > to take into account recent changes. In particualr, the ip_vs_sync.c
> > portion is no longer needed as only the flags in the first 16 bits are
> > synced now. It applies against Patrick McHardy's nf-next-2.6 tree.
> >
> > You mentioned in your original post that you would work on an ipvsadm
> > patch for this feature. Have you had time to do so?
> >
> > Also, are you in a position to test this? If not I can do so.
>
> Hi,
>
> I've tested your patch with the below addition to ipvsadm and it works
> correctly.
Thanks Sven,
I'll push the kernel side to Patrick McHardy and assuming
Wensong doesn't object, I'll push the ipvsadm side myself.
>
> Sven
>
> From: Sven Wegener <sven.wegener@stealer.net>
> Subject: [PATCH] Show backlog connections
>
> Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
> ---
> ipvsadm.c | 51 ++++++++++++++++++++++++++++++--------------
> libipvs/ip_vs.h | 4 +++
> libipvs/ip_vs_nl_policy.c | 1 +
> libipvs/libipvs.c | 3 ++
> 4 files changed, 43 insertions(+), 16 deletions(-)
>
> diff --git a/ipvsadm.c b/ipvsadm.c
> index 8557d21..54ae110 100644
> --- a/ipvsadm.c
> +++ b/ipvsadm.c
> @@ -181,7 +181,8 @@ static const char* cmdnames[] = {
> #define OPT_SYNCID 0x080000
> #define OPT_EXACT 0x100000
> #define OPT_ONEPACKET 0x200000
> -#define NUMBER_OF_OPT 22
> +#define OPT_BACKLOGCONN 0x400000
> +#define NUMBER_OF_OPT 23
>
> static const char* optnames[] = {
> "numeric",
> @@ -206,6 +207,7 @@ static const char* optnames[] = {
> "syncid",
> "exact",
> "ops",
> + "backlog-conn",
> };
>
> /*
> @@ -218,21 +220,21 @@ static const char* optnames[] = {
> */
> static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
> {
> - /* -n -c svc -s -p -M -r fwd -w -x -y -mc tot dmn -st -rt thr -pc srt sid -ex ops */
> -/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' '},
> -/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' '},
> -/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x'},
> -/*ADDSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*DELSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*STARTD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x'},
> -/*STOPD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x'},
> -/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> -/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> + /* -n -c svc -s -p -M -r fwd -w -x -y -mc tot dmn -st -rt thr -pc srt sid -ex ops, blc */
> +/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x'},
> +/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x'},
> +/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' '},
> +/*ADDSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*DELSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*STARTD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x'},
> +/*STOPD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x'},
> +/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> +/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
> };
>
> /* printing format flags */
> @@ -245,6 +247,7 @@ static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
> #define FMT_PERSISTENTCONN 0x0020
> #define FMT_NOSORT 0x0040
> #define FMT_EXACT 0x0080
> +#define FMT_BACKLOGCONN 0x0100
>
> #define SERVICE_NONE 0x0000
> #define SERVICE_ADDR 0x0001
> @@ -282,6 +285,7 @@ enum {
> TAG_PERSISTENTCONN,
> TAG_SORT,
> TAG_NO_SORT,
> + TAG_BACKLOGCONN,
> };
>
> /* various parsing helpers & parsing functions */
> @@ -421,6 +425,8 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
> { "exact", 'X', POPT_ARG_NONE, NULL, 'X', NULL, NULL },
> { "ipv6", '6', POPT_ARG_NONE, NULL, '6', NULL, NULL },
> { "ops", 'o', POPT_ARG_NONE, NULL, 'o', NULL, NULL },
> + { "backlog-conn", '\0', POPT_ARG_NONE, NULL,
> + TAG_BACKLOGCONN, NULL, NULL },
> { NULL, 0, 0, NULL, 0, NULL, NULL }
> };
>
> @@ -647,6 +653,10 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
> set_option(options, OPT_ONEPACKET);
> ce->svc.flags |= IP_VS_SVC_F_ONEPACKET;
> break;
> + case TAG_BACKLOGCONN:
> + set_option(options, OPT_BACKLOGCONN);
> + *format |= FMT_BACKLOGCONN;
> + break;
> default:
> fail(2, "invalid option `%s'",
> poptBadOption(context, POPT_BADOPTION_NOALIAS));
> @@ -1396,6 +1406,11 @@ static void print_title(unsigned int format)
> " -> RemoteAddress:Port\n",
> "Prot LocalAddress:Port",
> "Weight", "PersistConn", "ActiveConn", "InActConn");
> + else if (format & FMT_BACKLOGCONN)
> + printf("%-33s %-9s %-11s %-10s %-10s\n"
> + " -> RemoteAddress:Port\n",
> + "Prot LocalAddress:Port",
> + "Weight", "BacklogConn", "ActiveConn", "InActConn");
> else if (!(format & FMT_RULE))
> printf("Prot LocalAddress:Port Scheduler Flags\n"
> " -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");
> @@ -1539,6 +1554,10 @@ print_service_entry(ipvs_service_entry_t *se, unsigned int format)
> printf(" -> %-28s %-9u %-11u %-10u %-10u\n", dname,
> e->weight, e->persistconns,
> e->activeconns, e->inactconns);
> + } else if (format & FMT_BACKLOGCONN) {
> + printf(" -> %-28s %-9u %-11u %-10u %-10u\n", dname,
> + e->weight, e->backlogconns,
> + e->activeconns, e->inactconns);
> } else
> printf(" -> %-28s %-7s %-6d %-10u %-10u\n",
> dname, fwd_name(e->conn_flags),
> diff --git a/libipvs/ip_vs.h b/libipvs/ip_vs.h
> index 843c51a..4c2c265 100644
> --- a/libipvs/ip_vs.h
> +++ b/libipvs/ip_vs.h
> @@ -277,6 +277,8 @@ struct ip_vs_dest_entry {
> struct ip_vs_stats_user stats;
> u_int16_t af;
> union nf_inet_addr addr;
> +
> + u_int32_t backlogconns; /* backlog connections */
> };
>
> /* The argument to IP_VS_SO_GET_DESTS */
> @@ -455,6 +457,8 @@ enum {
> IPVS_DEST_ATTR_PERSIST_CONNS, /* persistent connections */
>
> IPVS_DEST_ATTR_STATS, /* nested attribute for dest stats */
> +
> + IPVS_DEST_ATTR_BACKLOG_CONNS, /* backlog connections */
> __IPVS_DEST_ATTR_MAX,
> };
>
> diff --git a/libipvs/ip_vs_nl_policy.c b/libipvs/ip_vs_nl_policy.c
> index c80083e..d06a490 100644
> --- a/libipvs/ip_vs_nl_policy.c
> +++ b/libipvs/ip_vs_nl_policy.c
> @@ -40,6 +40,7 @@ struct nla_policy ipvs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = {
> [IPVS_DEST_ATTR_INACT_CONNS] = { .type = NLA_U32 },
> [IPVS_DEST_ATTR_PERSIST_CONNS] = { .type = NLA_U32 },
> [IPVS_DEST_ATTR_STATS] = { .type = NLA_NESTED },
> + [IPVS_DEST_ATTR_BACKLOG_CONNS] = { .type = NLA_U32 },
> };
>
> struct nla_policy ipvs_stats_policy[IPVS_STATS_ATTR_MAX + 1] = {
> diff --git a/libipvs/libipvs.c b/libipvs/libipvs.c
> index 979d5bd..e06f9fa 100644
> --- a/libipvs/libipvs.c
> +++ b/libipvs/libipvs.c
> @@ -748,6 +748,8 @@ static int ipvs_dests_parse_cb(struct nl_msg *msg, void *arg)
> d->entrytable[i].l_threshold = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_L_THRESH]);
> d->entrytable[i].activeconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_ACTIVE_CONNS]);
> d->entrytable[i].inactconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_INACT_CONNS]);
> + if (dest_attrs[IPVS_DEST_ATTR_BACKLOG_CONNS])
> + d->entrytable[i].backlogconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_BACKLOG_CONNS]);
> d->entrytable[i].persistconns = nla_get_u32(dest_attrs[IPVS_DEST_ATTR_PERSIST_CONNS]);
> d->entrytable[i].af = d->af;
>
> @@ -853,6 +855,7 @@ ipvs_nl_dest_failure:
> sizeof(struct ip_vs_dest_entry_kern));
> d->entrytable[i].af = AF_INET;
> d->entrytable[i].addr.ip = d->entrytable[i].__addr_v4;
> + d->entrytable[i].backlogconns = 0;
> }
> free(dk);
> return d;
>
^ permalink raw reply
* [PATCH] sunrpc: prompt for RPCSEC_GSS_KRB5 even if NFS_V4 is enabled
From: Uwe Kleine-König @ 2010-09-27 10:41 UTC (permalink / raw)
To: linux-kernel
Cc: Trond Myklebust, J. Bruce Fields, Neil Brown, David S. Miller,
Uwe Kleine-König, Randy Dunlap, linux-nfs, netdev
In-Reply-To: <20100909181454.GB14915@pengutronix.de>
NFS_V4 works fine without RPCSEC_GSS_KRB5 (even without CRYPTO).
This dependency was introduced in
df486a2 (NFS: Fix the selection of security flavours in Kconfig)
to fix a build failure as RPCSEC_GSS_KRB5 was thought to be needed for
NFS_V4. The fix didn't work completely as NFS_V4 didn't enforce CRYPTO
and so the select on RPCSEC_GSS_KRB5 didn't work in all situations (e.g.
arm/mx1_defconfig).
This was rectified by
827e345 (SUNRPC: Fix the NFSv4 and RPCSEC_GSS Kconfig dependencies)
but the magic for RPCSEC_GSS_KRB5 introduced by df486a2 wasn't reverted.
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
Hello,
after Trond sent me the patch that later ended in 827e345702 I suggested
to fold the patch below into it[1], but without reaction and success as I
noticed just now. :-(
Best regards
Uwe
[1] http://thread.gmane.org/gmane.linux.kernel/1027380/focus=1033847
net/sunrpc/Kconfig | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index 3376d76..442efe1 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -20,8 +20,7 @@ config SUNRPC_XPRT_RDMA
config RPCSEC_GSS_KRB5
tristate
depends on SUNRPC && CRYPTO
- prompt "Secure RPC: Kerberos V mechanism" if !(NFS_V4 || NFSD_V4)
- default y
+ prompt "Secure RPC: Kerberos V mechanism"
select SUNRPC_GSS
select CRYPTO_MD5
select CRYPTO_DES
--
1.7.2.3
^ permalink raw reply related
* [PATCH -next 4/4] sit: percpu stats accounting
From: Eric Dumazet @ 2010-09-27 10:38 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets.
Other seldom used fields are kept in netdev->stats structure, possibly
unsafe.
This is a preliminary work to support lockless transmit path, and
correct RX stats, that are already unsafe.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv6/sit.c | 82 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 64 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 8a03998..011ecf5 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -63,8 +63,9 @@
#define HASH_SIZE 16
#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
-static void ipip6_tunnel_init(struct net_device *dev);
+static int ipip6_tunnel_init(struct net_device *dev);
static void ipip6_tunnel_setup(struct net_device *dev);
+static void ipip6_dev_free(struct net_device *dev);
static int sit_net_id __read_mostly;
struct sit_net {
@@ -84,6 +85,33 @@ struct sit_net {
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipip6_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
/*
* Must be invoked with rcu_read_lock
*/
@@ -214,7 +242,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "sit%%d");
+ strcpy(name, "sit%d");
dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup);
if (dev == NULL)
@@ -230,7 +258,8 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->parms = *parms;
- ipip6_tunnel_init(dev);
+ if (ipip6_tunnel_init(dev) < 0)
+ goto failed_free;
ipip6_tunnel_clone_6rd(dev, sitn);
if (parms->i_flags & SIT_ISATAP)
@@ -245,7 +274,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
return nt;
failed_free:
- free_netdev(dev);
+ ipip6_dev_free(dev);
failed:
return NULL;
}
@@ -546,6 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb)
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
iph->saddr, iph->daddr);
if (tunnel != NULL) {
+ struct pcpu_tstats *tstats;
+
secpath_reset(skb);
skb->mac_header = skb->network_header;
skb_reset_network_header(skb);
@@ -561,7 +592,11 @@ static int ipip6_rcv(struct sk_buff *skb)
return 0;
}
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
ipip6_ecn_decapsulate(iph, skb);
@@ -626,14 +661,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
struct iphdr *tiph = &tunnel->parms.iph;
struct ipv6hdr *iph6 = ipv6_hdr(skb);
u8 tos = tunnel->parms.iph.tos;
__be16 df = tiph->frag_off;
struct rtable *rt; /* Route to the other host */
- struct net_device *tdev; /* Device to other host */
+ struct net_device *tdev; /* Device to other host */
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr;
@@ -704,20 +738,20 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
.oif = tunnel->parms.link,
.proto = IPPROTO_IPV6 };
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
}
if (rt->rt_type != RTN_UNICAST) {
ip_rt_put(rt);
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
tdev = rt->dst.dev;
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -725,7 +759,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
if (mtu < 68) {
- stats->collisions++;
+ dev->stats.collisions++;
ip_rt_put(rt);
goto tx_error;
}
@@ -764,7 +798,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -800,14 +834,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
iph->ttl = iph6->hop_limit;
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -1084,12 +1118,19 @@ static const struct net_device_ops ipip6_netdev_ops = {
.ndo_start_xmit = ipip6_tunnel_xmit,
.ndo_do_ioctl = ipip6_tunnel_ioctl,
.ndo_change_mtu = ipip6_tunnel_change_mtu,
+ .ndo_get_stats = ipip6_get_stats,
};
+static void ipip6_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipip6_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipip6_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipip6_dev_free;
dev->type = ARPHRD_SIT;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
@@ -1101,7 +1142,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)
dev->features |= NETIF_F_NETNS_LOCAL;
}
-static void ipip6_tunnel_init(struct net_device *dev)
+static int ipip6_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
@@ -1112,6 +1153,11 @@ static void ipip6_tunnel_init(struct net_device *dev)
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
ipip6_tunnel_bind_dev(dev);
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
+ return 0;
}
static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
^ permalink raw reply related
* [PATCH -next 3/4] ipip: percpu stats accounting
From: Eric Dumazet @ 2010-09-27 10:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets.
Other seldom used fields are kept in netdev->stats structure, possibly
unsafe.
This is a preliminary work to support lockless transmit path, and
correct RX stats, that are already unsafe.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/ipip.c | 127 +++++++++++++++++++++++++++++++++-------------
1 file changed, 93 insertions(+), 34 deletions(-)
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index babd252..12b6fde 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -131,8 +131,9 @@ struct ipip_net {
struct net_device *fb_tunnel_dev;
};
-static void ipip_tunnel_init(struct net_device *dev);
+static int ipip_tunnel_init(struct net_device *dev);
static void ipip_tunnel_setup(struct net_device *dev);
+static void ipip_dev_free(struct net_device *dev);
/*
* Locking : hash tables are protected by RCU and RTNL
@@ -141,6 +142,34 @@ static void ipip_tunnel_setup(struct net_device *dev);
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipip_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
+
static struct ip_tunnel * ipip_tunnel_lookup(struct net *net,
__be32 remote, __be32 local)
{
@@ -239,7 +268,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "tunl%%d");
+ strcpy(name, "tunl%d");
dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup);
if (dev == NULL)
@@ -255,7 +284,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->parms = *parms;
- ipip_tunnel_init(dev);
+ if (ipip_tunnel_init(dev) < 0)
+ goto failed_free;
if (register_netdevice(dev) < 0)
goto failed_free;
@@ -265,7 +295,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
return nt;
failed_free:
- free_netdev(dev);
+ ipip_dev_free(dev);
return NULL;
}
@@ -359,8 +389,10 @@ static int ipip_rcv(struct sk_buff *skb)
const struct iphdr *iph = ip_hdr(skb);
rcu_read_lock();
- if ((tunnel = ipip_tunnel_lookup(dev_net(skb->dev),
- iph->saddr, iph->daddr)) != NULL) {
+ tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr);
+ if (tunnel != NULL) {
+ struct pcpu_tstats *tstats;
+
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
rcu_read_unlock();
kfree_skb(skb);
@@ -374,7 +406,11 @@ static int ipip_rcv(struct sk_buff *skb)
skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
ipip_ecn_decapsulate(iph, skb);
@@ -397,13 +433,12 @@ static int ipip_rcv(struct sk_buff *skb)
static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
struct iphdr *tiph = &tunnel->parms.iph;
u8 tos = tunnel->parms.iph.tos;
__be16 df = tiph->frag_off;
struct rtable *rt; /* Route to the other host */
- struct net_device *tdev; /* Device to other host */
+ struct net_device *tdev; /* Device to other host */
struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
@@ -413,13 +448,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
- if (tos&1)
+ if (tos & 1)
tos = old_iph->tos;
if (!dst) {
/* NBMA tunnel */
if ((rt = skb_rtable(skb)) == NULL) {
- stats->tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
goto tx_error;
}
if ((dst = rt->rt_gateway) == 0)
@@ -427,14 +462,20 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
}
{
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos) } },
- .proto = IPPROTO_IPIP };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = dst,
+ .saddr = tiph->saddr,
+ .tos = RT_TOS(tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
+
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error_icmp;
}
}
@@ -442,7 +483,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -452,7 +493,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr);
if (mtu < 68) {
- stats->collisions++;
+ dev->stats.collisions++;
ip_rt_put(rt);
goto tx_error;
}
@@ -488,7 +529,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -525,14 +566,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->ttl = old_iph->ttl;
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -547,13 +588,19 @@ static void ipip_tunnel_bind_dev(struct net_device *dev)
iph = &tunnel->parms.iph;
if (iph->daddr) {
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_IPIP };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_IPIP
+ };
struct rtable *rt;
+
if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -699,13 +746,19 @@ static const struct net_device_ops ipip_netdev_ops = {
.ndo_start_xmit = ipip_tunnel_xmit,
.ndo_do_ioctl = ipip_tunnel_ioctl,
.ndo_change_mtu = ipip_tunnel_change_mtu,
-
+ .ndo_get_stats = ipip_get_stats,
};
+static void ipip_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipip_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipip_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipip_dev_free;
dev->type = ARPHRD_TUNNEL;
dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr);
@@ -717,7 +770,7 @@ static void ipip_tunnel_setup(struct net_device *dev)
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
-static void ipip_tunnel_init(struct net_device *dev)
+static int ipip_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
@@ -728,6 +781,12 @@ static void ipip_tunnel_init(struct net_device *dev)
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
ipip_tunnel_bind_dev(dev);
+
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
+ return 0;
}
static void __net_init ipip_fb_tunnel_init(struct net_device *dev)
^ permalink raw reply related
* [PATCH -next 2/4] ip_gre: percpu stats accounting
From: Eric Dumazet @ 2010-09-27 10:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Maintain per_cpu tx_bytes, tx_packets, rx_bytes, rx_packets.
Other seldom used fields are kept in netdev->stats structure, possibly
unsafe.
This is a preliminary work to support lockless transmit path, and
correct RX stats, that are already unsafe.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/ip_gre.c | 138 +++++++++++++++++++++++++++++++-------------
1 file changed, 99 insertions(+), 39 deletions(-)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 5d6ddcb..de39b22 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -165,6 +165,34 @@ struct ipgre_net {
#define for_each_ip_tunnel_rcu(start) \
for (t = rcu_dereference(start); t; t = rcu_dereference(t->next))
+/* often modified stats are per cpu, other are shared (netdev->stats) */
+struct pcpu_tstats {
+ unsigned long rx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_packets;
+ unsigned long tx_bytes;
+};
+
+static struct net_device_stats *ipgre_get_stats(struct net_device *dev)
+{
+ struct pcpu_tstats sum = { 0 };
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i);
+
+ sum.rx_packets += tstats->rx_packets;
+ sum.rx_bytes += tstats->rx_bytes;
+ sum.tx_packets += tstats->tx_packets;
+ sum.tx_bytes += tstats->tx_bytes;
+ }
+ dev->stats.rx_packets = sum.rx_packets;
+ dev->stats.rx_bytes = sum.rx_bytes;
+ dev->stats.tx_packets = sum.tx_packets;
+ dev->stats.tx_bytes = sum.tx_bytes;
+ return &dev->stats;
+}
+
/* Given src, dst and key, find appropriate for input tunnel. */
static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
@@ -377,7 +405,7 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net,
if (parms->name[0])
strlcpy(name, parms->name, IFNAMSIZ);
else
- sprintf(name, "gre%%d");
+ strcpy(name, "gre%d");
dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
if (!dev)
@@ -584,7 +612,7 @@ static int ipgre_rcv(struct sk_buff *skb)
if ((tunnel = ipgre_tunnel_lookup(skb->dev,
iph->saddr, iph->daddr, key,
gre_proto))) {
- struct net_device_stats *stats = &tunnel->dev->stats;
+ struct pcpu_tstats *tstats;
secpath_reset(skb);
@@ -608,22 +636,22 @@ static int ipgre_rcv(struct sk_buff *skb)
/* Looped back packet, drop it! */
if (skb_rtable(skb)->fl.iif == 0)
goto drop;
- stats->multicast++;
+ tunnel->dev->stats.multicast++;
skb->pkt_type = PACKET_BROADCAST;
}
#endif
if (((flags&GRE_CSUM) && csum) ||
(!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
- stats->rx_crc_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_crc_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
if (tunnel->parms.i_flags&GRE_SEQ) {
if (!(flags&GRE_SEQ) ||
(tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) {
- stats->rx_fifo_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_fifo_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
tunnel->i_seqno = seqno + 1;
@@ -632,8 +660,8 @@ static int ipgre_rcv(struct sk_buff *skb)
/* Warning: All skb pointers will be invalidated! */
if (tunnel->dev->type == ARPHRD_ETHER) {
if (!pskb_may_pull(skb, ETH_HLEN)) {
- stats->rx_length_errors++;
- stats->rx_errors++;
+ tunnel->dev->stats.rx_length_errors++;
+ tunnel->dev->stats.rx_errors++;
goto drop;
}
@@ -642,13 +670,17 @@ static int ipgre_rcv(struct sk_buff *skb)
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
}
- skb_tunnel_rx(skb, tunnel->dev);
+ tstats = this_cpu_ptr(tunnel->dev->tstats);
+ tstats->rx_packets++;
+ tstats->rx_bytes += skb->len;
+
+ __skb_tunnel_rx(skb, tunnel->dev);
skb_reset_network_header(skb);
ipgre_ecn_decapsulate(iph, skb);
if (netif_rx(skb) == NET_RX_DROP)
- stats->rx_dropped++;
+ tunnel->dev->stats.rx_dropped++;
rcu_read_unlock();
return 0;
@@ -665,8 +697,7 @@ drop_nolock:
static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+ struct pcpu_tstats *tstats;
struct iphdr *old_iph = ip_hdr(skb);
struct iphdr *tiph;
u8 tos;
@@ -694,7 +725,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
/* NBMA tunnel */
if (skb_dst(skb) == NULL) {
- stats->tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
goto tx_error;
}
@@ -740,14 +771,20 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
{
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = dst,
- .saddr = tiph->saddr,
- .tos = RT_TOS(tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = dst,
+ .saddr = tiph->saddr,
+ .tos = RT_TOS(tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ }
+;
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
- stats->tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
goto tx_error;
}
}
@@ -755,7 +792,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (tdev == dev) {
ip_rt_put(rt);
- stats->collisions++;
+ dev->stats.collisions++;
goto tx_error;
}
@@ -818,7 +855,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
dev->needed_headroom = max_headroom;
if (!new_skb) {
ip_rt_put(rt);
- txq->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -885,15 +922,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
nf_reset(skb);
-
- IPTUNNEL_XMIT();
+ tstats = this_cpu_ptr(dev->tstats);
+ __IPTUNNEL_XMIT(tstats, &dev->stats);
return NETDEV_TX_OK;
tx_error_icmp:
dst_link_failure(skb);
tx_error:
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
@@ -913,13 +950,19 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
/* Guess output device to choose reasonable mtu and needed_headroom */
if (iph->daddr) {
- struct flowi fl = { .oif = tunnel->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = iph->daddr,
- .saddr = iph->saddr,
- .tos = RT_TOS(iph->tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = tunnel->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ };
struct rtable *rt;
+
if (!ip_route_output_key(dev_net(dev), &rt, &fl)) {
tdev = rt->dst.dev;
ip_rt_put(rt);
@@ -1171,13 +1214,19 @@ static int ipgre_open(struct net_device *dev)
struct ip_tunnel *t = netdev_priv(dev);
if (ipv4_is_multicast(t->parms.iph.daddr)) {
- struct flowi fl = { .oif = t->parms.link,
- .nl_u = { .ip4_u =
- { .daddr = t->parms.iph.daddr,
- .saddr = t->parms.iph.saddr,
- .tos = RT_TOS(t->parms.iph.tos) } },
- .proto = IPPROTO_GRE };
+ struct flowi fl = {
+ .oif = t->parms.link,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = t->parms.iph.daddr,
+ .saddr = t->parms.iph.saddr,
+ .tos = RT_TOS(t->parms.iph.tos)
+ }
+ },
+ .proto = IPPROTO_GRE
+ };
struct rtable *rt;
+
if (ip_route_output_key(dev_net(dev), &rt, &fl))
return -EADDRNOTAVAIL;
dev = rt->dst.dev;
@@ -1217,12 +1266,19 @@ static const struct net_device_ops ipgre_netdev_ops = {
.ndo_start_xmit = ipgre_tunnel_xmit,
.ndo_do_ioctl = ipgre_tunnel_ioctl,
.ndo_change_mtu = ipgre_tunnel_change_mtu,
+ .ndo_get_stats = ipgre_get_stats,
};
+static void ipgre_dev_free(struct net_device *dev)
+{
+ free_percpu(dev->tstats);
+ free_netdev(dev);
+}
+
static void ipgre_tunnel_setup(struct net_device *dev)
{
dev->netdev_ops = &ipgre_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = ipgre_dev_free;
dev->type = ARPHRD_IPGRE;
dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
@@ -1260,6 +1316,10 @@ static int ipgre_tunnel_init(struct net_device *dev)
} else
dev->header_ops = &ipgre_header_ops;
+ dev->tstats = alloc_percpu(struct pcpu_tstats);
+ if (!dev->tstats)
+ return -ENOMEM;
+
return 0;
}
^ permalink raw reply related
* [PATCH -next 1/4] tunnels: prepare percpu accounting
From: Eric Dumazet @ 2010-09-27 10:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Tunnels are going to use percpu for their accounting.
They are going to use a new tstats field in net_device.
skb_tunnel_rx() is changed to be a wrapper around __skb_tunnel_rx()
IPTUNNEL_XMIT() is changed to be a wrapper around __IPTUNNEL_XMIT()
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/linux/netdevice.h | 1 +
include/net/dst.h | 24 +++++++++++++++++++-----
include/net/ipip.h | 12 +++++++-----
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 01bd4c8..83de0eb 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1053,6 +1053,7 @@ struct net_device {
union {
void *ml_priv;
struct pcpu_lstats __percpu *lstats; /* loopback stats */
+ struct pcpu_tstats __percpu *tstats; /* tunnel stats */
};
/* GARP */
struct garp_port *garp_port;
diff --git a/include/net/dst.h b/include/net/dst.h
index 0238650..2916852 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -228,23 +228,37 @@ static inline void skb_dst_force(struct sk_buff *skb)
/**
+ * __skb_tunnel_rx - prepare skb for rx reinsert
+ * @skb: buffer
+ * @dev: tunnel device
+ *
+ * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
+ * so make some cleanups. (no accounting done)
+ */
+static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
+{
+ skb->dev = dev;
+ skb->rxhash = 0;
+ skb_set_queue_mapping(skb, 0);
+ skb_dst_drop(skb);
+ nf_reset(skb);
+}
+
+/**
* skb_tunnel_rx - prepare skb for rx reinsert
* @skb: buffer
* @dev: tunnel device
*
* After decapsulation, packet is going to re-enter (netif_rx()) our stack,
* so make some cleanups, and perform accounting.
+ * Note: this accounting is not SMP safe.
*/
static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
{
- skb->dev = dev;
/* TODO : stats should be SMP safe */
dev->stats.rx_packets++;
dev->stats.rx_bytes += skb->len;
- skb->rxhash = 0;
- skb_set_queue_mapping(skb, 0);
- skb_dst_drop(skb);
- nf_reset(skb);
+ __skb_tunnel_rx(skb, dev);
}
/* Children define the path of the packet through the
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 65caea8..58abbf9 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -45,7 +45,7 @@ struct ip_tunnel_prl_entry {
struct rcu_head rcu_head;
};
-#define IPTUNNEL_XMIT() do { \
+#define __IPTUNNEL_XMIT(stats1, stats2) do { \
int err; \
int pkt_len = skb->len - skb_transport_offset(skb); \
\
@@ -54,12 +54,14 @@ struct ip_tunnel_prl_entry {
\
err = ip_local_out(skb); \
if (likely(net_xmit_eval(err) == 0)) { \
- txq->tx_bytes += pkt_len; \
- txq->tx_packets++; \
+ (stats1)->tx_bytes += pkt_len; \
+ (stats1)->tx_packets++; \
} else { \
- stats->tx_errors++; \
- stats->tx_aborted_errors++; \
+ (stats2)->tx_errors++; \
+ (stats2)->tx_aborted_errors++; \
} \
} while (0)
+#define IPTUNNEL_XMIT() __IPTUNNEL_XMIT(txq, stats)
+
#endif
^ permalink raw reply related
* [PATCH net-next-2.6 0/4] tunnels: SMP safe accounting
From: Eric Dumazet @ 2010-09-27 10:32 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Before making ip_gre, ipip, and sit transmit path lockless, it is
necessary to make accounting SMP safe, not only for correctness but to
avoid cache line ping pongs.
This also takes care of receive path, already lockless and using unsafe
stats accounting.
I chose to use small percpu structures, holding {rx|tx}_{packets|bytes}
only, and keep all other counters in netdev->stats, since they should be
seldom used.
Patch 1/4 makes the needed changes in include files
Patch 2/4 takes care of ip_gre
Patch 3/4 takes care of ipip
Patch 4/4 takes care of sit
Thanks
include/linux/netdevice.h | 1
include/net/dst.h | 24 ++++--
include/net/ipip.h | 12 +--
net/ipv4/ip_gre.c | 138 +++++++++++++++++++++++++-----------
net/ipv4/ipip.c | 127 ++++++++++++++++++++++++---------
net/ipv6/sit.c | 80 ++++++++++++++++----
6 files changed, 282 insertions(+), 100 deletions(-)
^ permalink raw reply
* [PATCH] net: Implement Any-IP support for IPv6.
From: Maciej Żenczykowski @ 2010-09-27 10:07 UTC (permalink / raw)
To: David Miller, netdev; +Cc: Maciej Żenczykowski
From: Maciej Żenczykowski <maze@google.com>
AnyIP is the capability to receive packets and establish incoming
connections on IPs we have not explicitly configured on the machine.
An example use case is to configure a machine to accept all incoming
traffic on eth0, and leave the policy of whether traffic for a given IP
should be delivered to the machine up to the load balancer.
Can be setup as follows:
ip -6 rule from all iif eth0 lookup 200
ip -6 route add local default dev lo table 200
(in this case for all IPv6 addresses)
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/route.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d126365..3a74f90 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1169,6 +1169,8 @@ int ip6_route_add(struct fib6_config *cfg)
if (addr_type & IPV6_ADDR_MULTICAST)
rt->dst.input = ip6_mc_input;
+ else if (cfg->fc_flags & RTF_LOCAL)
+ rt->dst.input = ip6_input;
else
rt->dst.input = ip6_forward;
@@ -1190,7 +1192,8 @@ int ip6_route_add(struct fib6_config *cfg)
they would result in kernel looping; promote them to reject routes
*/
if ((cfg->fc_flags & RTF_REJECT) ||
- (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
+ (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK)
+ && !(cfg->fc_flags&RTF_LOCAL))) {
/* hold loopback dev/idev if we haven't done so. */
if (dev != net->loopback_dev) {
if (dev) {
@@ -2082,6 +2085,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
if (rtm->rtm_type == RTN_UNREACHABLE)
cfg->fc_flags |= RTF_REJECT;
+ if (rtm->rtm_type == RTN_LOCAL)
+ cfg->fc_flags |= RTF_LOCAL;
+
cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
cfg->fc_nlinfo.nlh = nlh;
cfg->fc_nlinfo.nl_net = sock_net(skb->sk);
@@ -2202,6 +2208,8 @@ static int rt6_fill_node(struct net *net,
NLA_PUT_U32(skb, RTA_TABLE, table);
if (rt->rt6i_flags&RTF_REJECT)
rtm->rtm_type = RTN_UNREACHABLE;
+ else if (rt->rt6i_flags&RTF_LOCAL)
+ rtm->rtm_type = RTN_LOCAL;
else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
rtm->rtm_type = RTN_LOCAL;
else
--
1.7.2.3
^ permalink raw reply related
* [PATCH] net: Fix IPv6 PMTU disc. w/ asymmetric routes
From: Maciej Żenczykowski @ 2010-09-27 10:05 UTC (permalink / raw)
To: David Miller, netdev; +Cc: Maciej Żenczykowski
In-Reply-To: <55a4f86e1001131651j102b600fm1552a42866c3c671@mail.gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/route.c | 31 +++++++++++++++++++++++++++----
1 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3a74f90..d700d1c 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1559,14 +1559,13 @@ out:
* i.e. Path MTU discovery
*/
-void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
- struct net_device *dev, u32 pmtu)
+static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr,
+ struct net *net, u32 pmtu, int ifindex)
{
struct rt6_info *rt, *nrt;
- struct net *net = dev_net(dev);
int allfrag = 0;
- rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0);
+ rt = rt6_lookup(net, daddr, saddr, ifindex, 0);
if (rt == NULL)
return;
@@ -1634,6 +1633,30 @@ out:
dst_release(&rt->dst);
}
+void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
+ struct net_device *dev, u32 pmtu)
+{
+ struct net *net = dev_net(dev);
+
+ /*
+ * RFC 1981 states that a node "MUST reduce the size of the packets it
+ * is sending along the path" that caused the Packet Too Big message.
+ * Since it's not possible in the general case to determine which
+ * interface was used to send the original packet, we update the MTU
+ * on the interface that will be used to send future packets. We also
+ * update the MTU on the interface that received the Packet Too Big in
+ * case the original packet was forced out that interface with
+ * SO_BINDTODEVICE or similar. This is the next best thing to the
+ * correct behaviour, which would be to update the MTU on all
+ * interfaces.
+ */
+ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0);
+ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex);
+ /* also support source address based routing */
+ rt6_do_pmtu_disc(daddr, NULL, net, pmtu, 0);
+ rt6_do_pmtu_disc(daddr, NULL, net, pmtu, dev->ifindex);
+}
+
/*
* Misc support functions
*/
--
1.7.2.3
^ permalink raw reply related
* Re: TCP: orphans broken by RFC 2525 #2.17
From: Julian Anastasov @ 2010-09-27 9:12 UTC (permalink / raw)
To: Willy Tarreau; +Cc: David Miller, netdev
In-Reply-To: <20100927073443.GR12373@1wt.eu>
Hello,
On Mon, 27 Sep 2010, Willy Tarreau wrote:
> case A (current one) :
> we send the response to the client from an orphaned connection.
> Most of the times, the client won't have any issue and will get the
> response. In some rare circumstances, some data sent by the client
> after the response causes an RST to be emitted, which may destroy
> in flight data. But those issues are extremely rare, still they
> happen.
>
> case B (my proposal, and was the case before the RFC2525 fix) :
> we send the response to the client.
> it acks it
> we send an RST. End of the transfer. Total time: 50ms (avg RTT over ADSL).
>
> case C (alternative) :
> we send the response to the client.
> the application can't know it has acked it, and must maintain the
> connection open for however long is necessary to get the only form
> of ACK the application can detect: the FIN from the client, which
> is 6 minutes on my ADSL line for 10 meg.
If it is not already mentioned, the application can
know if sent data is acked. I think, ioctl SIOCOUTQ is for
this purpose. May be the application that wants to send
reliably HTTP error response before closing should do something
like:
- add this FD in some list for monitoring instead of keeping
large connection state
- use shutdown SHUT_WR to add FIN after response
- use setsockopt SO_RCVBUF with some low value to close the
RX window, we do not want the body
- wait for POLLHUP (FIN), not for POLLIN because we want to
ignore data, not to read it. Still, data can be read and
dropped if needed to release the socket memory
- use timer to limit the time we wait our data to be acked
- use SIOCOUTQ to know if everything is received in peer and
then close the fd
> In case C, not only the state remains *a lot* longer, but the bandwidth
> usage is much worse, and in the end the client does not even get the reset
> that we're trying to ensure it gets to indicate that the data were dropped.
>
> So while case C is a reliable workaround, it's the least efficient method
> and the most expensive one in terms of memory, CPU, network bandwidth,
> socket usage, file descriptor usage and perceived time.
>
> You see, I'm not trying to make dirty dangerous things to save a few
> lines of code. I'm even OK to have a lot of linux-specific code to make
> use of the features the linux stack provides that makes it more efficient
> than other implementations. I'm just seeking reliability.
>
> Willy
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* [PATCH net-next-2.6] vlan: use this_cpu_ptr() in vlan_skb_recv()
From: Eric Dumazet @ 2010-09-27 8:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/8021q/vlan_dev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 94a1fed..f6fbcc0 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -177,8 +177,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
} else {
skb->dev = vlan_dev;
- rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
- smp_processor_id());
+ rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);
+
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
rx_stats->rx_bytes += skb->len;
^ permalink raw reply related
* Re: [MeeGo-Dev][PATCH v3] Topcliff: Update PCH_CAN driver to 2.6.35
From: Wolfgang Grandegger @ 2010-09-27 8:38 UTC (permalink / raw)
To: Masayuki Ohtak
Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w, Samuel Ortiz,
margie.foster-ral2JQCrhuEAvxtiuMwx3w,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
yong.y.wang-ral2JQCrhuEAvxtiuMwx3w,
kok.howg.ewe-ral2JQCrhuEAvxtiuMwx3w,
joel.clark-ral2JQCrhuEAvxtiuMwx3w, Tomoya MORINAGA,
meego-dev-WXzIur8shnEAvxtiuMwx3w, David S. Miller,
Christian Pellegrin, qi.wang-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <4C9C7C6F.1000003-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
Hi Ohtake,
On 09/24/2010 12:24 PM, Masayuki Ohtak wrote:
> Hi Wolfgang and Marc,
>
> We have modified a pretty amount of our driver based on other accepted Socket CAN driver.
> Additionally, We have reduced the number of lines 3601 to 1444.
Much better now! I need some more time for a full review, though.
Thanks,
Wolfgang.
^ permalink raw reply
* Re: [Bugme-new] [Bug 18952] New: The mount of SYN retries is not equal to /proc/sys/net/ipv4/tcp_syn_retries
From: Damian Lukowski @ 2010-09-27 8:35 UTC (permalink / raw)
To: David Miller; +Cc: yuri, akpm, netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <20100927.011046.45906887.davem@davemloft.net>
Hi David,
give me some time, please. I'll take a closer look in the evening.
Regards
Damian
Am Montag, den 27.09.2010, 01:10 -0700 schrieb David Miller:
> From: Yuri Chislov <yuri@itinteg.net>
> Date: Mon, 27 Sep 2010 10:07:06 +0200
>
> > It looks like the behavior changed in 2.6.32. 2.6.32 and up, uses some
> > calculation instead of a direct definition of the retries number, that makes it
> > harder to achieve the necessary system behavior.
> >
> > The default behavior of the system changed completely
> > (the old default connect timeout was ~ 180 seconds, while the new one is ~21
> > sec).
> >
> > The new behavior invalidates the kernel documentation and tcp man page.
> >
> > It's not possible to set a connect timeout > 25 sec in the applications while
> > using the default values in /proc.
> >
> > From my view point is regression.
>
> Agreed, Damian you have to fix this.
>
> Otherwise I'm reverting all of your Revert Backoff commits.
^ permalink raw reply
* Re: linux-next: build failure after merge of the final tree (net tree related)
From: David Miller @ 2010-09-27 8:17 UTC (permalink / raw)
To: sfr; +Cc: netdev, linux-next, linux-kernel, ohad, linville
In-Reply-To: <20100927154408.55a28127.sfr@canb.auug.org.au>
From: Stephen Rothwell <sfr@canb.auug.org.au>
Date: Mon, 27 Sep 2010 15:44:08 +1000
> After merging the final tree, today's linux-next build (x86_64
> allmodconfig) failed like this:
>
> Assembler messages:
> Fatal error: can't create drivers/net/wireless/wl12xx/.tmp_wl12xx_platform_data.o: No such file or directory
> drivers/net/wireless/wl12xx/wl12xx_platform_data.c: In function 'wl12xx_get_platform_data':
> drivers/net/wireless/wl12xx/wl12xx_platform_data.c:28: error: cannot open drivers/net/wireless/wl12xx/.tmp_wl12xx_platform_data.gcno
> drivers/net/wireless/wl12xx/wl12xx_platform_data.c:28: confused by earlier errors, bailing out
>
> Presumably caused by commit 61ee7007a5d61aa066076da578e8e8084e122d7d
> ("wl12xx: add platform data passing support").
>
> I do my builds with a separate object directory (which may be a reason
> you don't see this).
John, please get this fixed, thanks.
^ permalink raw reply
* net-2.6 merged into net-next-2.6
From: David Miller @ 2010-09-27 8:14 UTC (permalink / raw)
To: netdev; +Cc: sfr, jeffrey.t.kirsher, linville
Just FYI...
^ 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