Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/9][BNX2]: Add function to fetch hardware tx index.
From: David Miller @ 2007-12-21  3:55 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182667.9163.27.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:31:07 -0800

> [BNX2]: Add function to fetch hardware tx index.
> 
> This makes the code cleaner and easier to support different tx rings.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/9][BNX2]: Restructure IRQ datastructures.
From: David Miller @ 2007-12-21  3:56 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182688.9163.28.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:31:28 -0800

> [BNX2]: Restructure IRQ datastructures.
> 
> Add a table to keep track of multiple IRQs and restructure the IRQ
> request and free functions so that they can be easily expanded to
> handle multiple IRQs.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 3/9][BNX2]: Introduce new bnx2_napi structure.
From: David Miller @ 2007-12-21  3:56 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182704.9163.29.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:31:44 -0800

> [BNX2]: Introduce new bnx2_napi structure.
> 
> Introduce a bnx2_napi structure that will hold a napi_struct and
> other fields to handle NAPI polling for the napi_struct.  Various tx
> and rx indexes and status block pointers will be moved from the main
> bnx2 structure to this bnx2_napi structure.
> 
> Most NAPI path functions are modified to be passed this bnx2_napi
> struct pointer.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 4/9][BNX2]: Move tx indexes into bnx2_napi struct.
From: David Miller @ 2007-12-21  3:57 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182730.9163.30.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:32:10 -0800

> [BNX2]: Move tx indexes into bnx2_napi struct.
> 
> Tx related fields used in NAPI polling are moved from the main
> bnx2 struct to the bnx2_napi struct.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 5/9][BNX2]: Move rx indexes into bnx2_napi struct.
From: David Miller @ 2007-12-21  3:57 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182745.9163.31.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:32:25 -0800

> [BNX2]: Move rx indexes into bnx2_napi struct.
> 
> Rx related fields used in NAPI polling are moved from the main
> bnx2 struct to the bnx2_napi struct.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 6/9][BNX2]: Support multiple MSIX IRQs.
From: David Miller @ 2007-12-21  3:59 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182767.9163.32.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:32:47 -0800

> [BNX2]: Support multiple MSIX IRQs.
> 
> Change bnx2_napi struct into an array and add code to manage multiple
> IRQs.  MSIX hardware structures and new registers are also added.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH 4/4] [UDP]: memory accounting in IPv4
From: Hideo AOKI @ 2007-12-21  3:58 UTC (permalink / raw)
  To: David Miller
  Cc: herbert, netdev, tyasui, mhiramat, satoshi.oshima.fk, billfink,
	andi, johnpol, shemminger, yoshfuji, yumiko.sugita.yf, haoki
In-Reply-To: <20071220.034437.126882771.davem@davemloft.net>

David Miller wrote:
> From: Hideo AOKI <haoki@redhat.com>
> Date: Mon, 17 Dec 2007 21:38:47 -0500
> 
>> This patch adds UDP memory usage accounting in IPv4.
>>
> We can't accept these changes, even once the other issues
> are fixed, until IPV6 is supported as well.
> 
> It's pointless to support proper UDP memory accounting only
> in IPV4 and not in IPV6 as well.

I understood. I'll develop IPv6 UDP memory accounting as well and
include it in next UDP memory accounting patch set submission.

Many thanks,
Hideo

-- 
Hitachi Computer Products (America) Inc.

^ permalink raw reply

* Re: [PATCH 7/9][BNX2]: Add support for a new tx ring.
From: David Miller @ 2007-12-21  4:01 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182780.9163.33.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:33:00 -0800

> [BNX2]: Add support for a new tx ring.
> 
> To separate TX IRQs into a different MSIX vector, we need to
> support a new tx ring.  The original tx ring will still be used
> when not using MSIX.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.


^ permalink raw reply

* Re: [PATCH 8/9][BNX2]: Enable new tx ring.
From: David Miller @ 2007-12-21  4:01 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182815.9163.34.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:33:35 -0800

> [BNX2]: Enable new tx ring.
> 
> Enable new tx ring and add new MSIX handler and NAPI poll function
> for the new tx ring.  Enable MSIX when the hardware supports it.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 9/9][BNX2]: Update version to 1.7.1.
From: David Miller @ 2007-12-21  4:02 UTC (permalink / raw)
  To: mchan; +Cc: netdev
In-Reply-To: <1198182829.9163.35.camel@dell>

From: "Michael Chan" <mchan@broadcom.com>
Date: Thu, 20 Dec 2007 12:33:49 -0800

> [BNX2]: Update version to 1.7.1.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: Please pull 'upstream-davem' branch of wireless-2.6
From: David Miller @ 2007-12-21  4:04 UTC (permalink / raw)
  To: linville-2XuSBdqkA4R54TAoqtyWWQ
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20071220223850.GL3139-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

From: "John W. Linville" <linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Date: Thu, 20 Dec 2007 17:38:50 -0500

> On Thu, Dec 20, 2007 at 10:53:21AM -0500, John W. Linville wrote:
> 
> > These are destined for 2.6.25.  The patches fall mostly into two
> > categories: a new rate control algorithm for mac80211, and some
> > cfg80211 enhancements (including mac80211 patches to use them).
> 
> >       mac80211: make PID rate control algorithm the default
> 
> This patch is busted.  I was mistaken about its readiness --
> I apologize.  Don't pull if you haven't already.
> 
> We are actively working on fixing/replacing it.
> 
> Thanks for your patience!

No worries, let me know when there is a new tree to pull from.

^ permalink raw reply

* Re: [PATCH 1/8] tg3: Separate requested and actual flow control parameters
From: David Miller @ 2007-12-21  4:05 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191589.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 14:59:49 -0800

> This patch removes the TX and RX flow control flags from tg3_flags and
> adds two new flow control variables, flowctrl and active_flowctrl.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/8] tg3: Add 1000T & 1000X flowctrl resolvers
From: David Miller @ 2007-12-21  4:06 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191593.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 14:59:53 -0800

> This patch adds two new utility functions to resolve flow control.  One
> function resolves flow control based on 1000-BaseT register definitions.
> The other resolves flow control based on 1000-Base X register
> definitions.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 3/8] tg3: Add 1000T & 1000X flowctl adv helpers
From: David Miller @ 2007-12-21  4:08 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191596.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 14:59:56 -0800

> This patch adds two functions designed to convert abstract TX & RX
> flow control parameters to 1000-BaseT and 1000-BaseX autonegotiation
> advertisements.  Code that uses standard definitions which statically
> advertises TX & RX flow control has been replaced with code that
> configures the advertisements based on administrator dictated
> preferences.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

APplied.

^ permalink raw reply

* Re: [PATCH 4/8] tg3: Replace some magic 5704S constants
From: David Miller @ 2007-12-21  4:08 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191599.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 14:59:59 -0800

> This patch replaces magic values with preprocessor definitions for
> the sg_dig_ctrl and sg_dig_status registers.  This is preparatory work
> for the next patch.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 5/8] tg3: Correct 5704S flowctrl advertisements
From: David Miller @ 2007-12-21  4:09 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191602.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 15:00:02 -0800

> This patch modifies the 5704S hardware autoneg code to use the
> administrator specified flow control parameters.  Since the 5704S uses
> device specific flow control enumerations, the 1000-BaseX utility
> functions are used and code was added to convert the definitions to and
> from the proprietary enumerations.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* [PATCH] [XFRM] IPv6: Fix dst/routing check at transformation.
From: Masahide NAKAMURA @ 2007-12-21  3:40 UTC (permalink / raw)
  To: herbert; +Cc: netdev, usagi-core, Masahide NAKAMURA

IPv6 specific thing is wrongly removed from transformation at net-2.6.25.
This patch recovers it with current design.

o Update "path" of xfrm_dst since IPv6 transformation should
  care about routing changes. It is required by MIPv6 and
  off-link destined IPsec.
o Rename nfheader_len which is for non-fragment transformation used by
  MIPv6 to rt6i_nfheader_len as IPv6 name space.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 include/net/ip6_fib.h   |    2 +-
 include/net/xfrm.h      |    3 +++
 net/ipv4/xfrm4_policy.c |    7 +++++++
 net/ipv6/ip6_output.c   |    4 ++--
 net/ipv6/xfrm6_policy.c |   17 +++++++++++++++++
 net/xfrm/xfrm_policy.c  |   21 +++++++++++++++++++++
 6 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 14830ed..d8d85b1 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -101,7 +101,7 @@ struct rt6_info
 	atomic_t			rt6i_ref;
 
 	/* more non-fragment space at head required */
-	unsigned short			nfheader_len;
+	unsigned short			rt6i_nfheader_len;
 
 	u8				rt6i_protocol;
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 32b99e2..6df8253 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -242,6 +242,9 @@ struct xfrm_policy_afinfo {
 						  struct flowi *fl,
 						  int reverse);
 	int			(*get_tos)(struct flowi *fl);
+	int			(*init_path)(struct xfrm_dst *path,
+					     struct dst_entry *dst,
+					     int nfheader_len);
 	int			(*fill_dst)(struct xfrm_dst *xdst,
 					    struct net_device *dev);
 };
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 5ccae3a..656345f 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -84,6 +84,12 @@ static int xfrm4_get_tos(struct flowi *fl)
 	return fl->fl4_tos;
 }
 
+static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+			   int nfheader_len)
+{
+	return 0;
+}
+
 static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 {
 	struct rtable *rt = (struct rtable *)xdst->route;
@@ -251,6 +257,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
 	.find_bundle = 		__xfrm4_find_bundle,
 	.decode_session =	_decode_session4,
 	.get_tos =		xfrm4_get_tos,
+	.init_path =		xfrm4_init_path,
 	.fill_dst =		xfrm4_fill_dst,
 };
 
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 388a098..cb6bb89 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1126,7 +1126,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 		sk->sk_sndmsg_page = NULL;
 		sk->sk_sndmsg_off = 0;
 		exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0) -
-			    rt->nfheader_len;
+			    rt->rt6i_nfheader_len;
 		length += exthdrlen;
 		transhdrlen += exthdrlen;
 	} else {
@@ -1141,7 +1141,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 
 	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 
-	fragheaderlen = sizeof(struct ipv6hdr) + rt->nfheader_len +
+	fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
 			(opt ? opt->opt_nflen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d26b7dc..cf373b4 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -98,6 +98,20 @@ static int xfrm6_get_tos(struct flowi *fl)
 	return 0;
 }
 
+static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+			   int nfheader_len)
+{
+	if (dst->ops->family == AF_INET6) {
+		struct rt6_info *rt = (struct rt6_info*)dst;
+		if (rt->rt6i_node)
+			path->path_cookie = rt->rt6i_node->fn_sernum;
+	}
+
+	path->u.rt6.rt6i_nfheader_len = nfheader_len;
+
+	return 0;
+}
+
 static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 {
 	struct rt6_info *rt = (struct rt6_info*)xdst->route;
@@ -115,6 +129,8 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 						   RTF_LOCAL);
 	xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
 	xdst->u.rt6.rt6i_node = rt->rt6i_node;
+	if (rt->rt6i_node)
+		xdst->route_cookie = rt->rt6i_node->fn_sernum;
 	xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
 	xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
 	xdst->u.rt6.rt6i_src = rt->rt6i_src;
@@ -266,6 +282,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
 	.find_bundle =		__xfrm6_find_bundle,
 	.decode_session =	_decode_session6,
 	.get_tos =		xfrm6_get_tos,
+	.init_path =		xfrm6_init_path,
 	.fill_dst =		xfrm6_fill_dst,
 };
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d2084b1..4f823f4 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1266,6 +1266,23 @@ static inline struct xfrm_dst *xfrm_alloc_dst(int family)
 	return xdst;
 }
 
+static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+				 int nfheader_len)
+{
+	struct xfrm_policy_afinfo *afinfo =
+		xfrm_policy_get_afinfo(dst->ops->family);
+	int err;
+
+	if (!afinfo)
+		return -EINVAL;
+
+	err = afinfo->init_path(path, dst, nfheader_len);
+
+	xfrm_policy_put_afinfo(afinfo);
+
+	return err;
+}
+
 static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 {
 	struct xfrm_policy_afinfo *afinfo =
@@ -1298,6 +1315,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
 	int i = 0;
 	int err;
 	int header_len = 0;
+	int nfheader_len = 0;
 	int trailer_len = 0;
 	int tos;
 	int family = policy->selector.family;
@@ -1352,6 +1370,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
 		dst_prev = dst1;
 
 		header_len += xfrm[i]->props.header_len;
+		if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
+			nfheader_len += xfrm[i]->props.header_len;
 		trailer_len += xfrm[i]->props.trailer_len;
 	}
 
@@ -1366,6 +1386,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
 	/* Copy neighbout for reachability confirmation */
 	dst0->neighbour = neigh_clone(dst->neighbour);
 
+	xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len);
 	xfrm_init_pmtu(dst_prev);
 
 	for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
-- 
1.4.4.2


^ permalink raw reply related

* [PATCH 3/3] [XFRM]: Add packet processing statistics option.
From: Masahide NAKAMURA @ 2007-12-21  3:42 UTC (permalink / raw)
  To: herbert; +Cc: netdev, usagi-core, Masahide NAKAMURA

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 net/xfrm/Kconfig |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 577a4f8..6b5b50f 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -35,6 +35,16 @@ config XFRM_MIGRATE
 
 	  If unsure, say N.
 
+config XFRM_STATISTICS
+	bool "Transformation statistics (EXPERIMENTAL)"
+	depends on XFRM && PROC_FS && EXPERIMENTAL
+	---help---
+	  This statistics is not a SNMP/MIB specification but shows
+	  statistics about transformation error (or almost error) factor
+	  at packet processing for developer.
+
+	  If unsure, say N.
+
 config NET_KEY
 	tristate "PF_KEY sockets"
 	select XFRM
-- 
1.4.4.2


^ permalink raw reply related

* [PATCH] [XFRM] MIPv6: Fix to input RO state correctly.
From: Masahide NAKAMURA @ 2007-12-21  3:40 UTC (permalink / raw)
  To: herbert; +Cc: netdev, usagi-core, Masahide NAKAMURA

Disable spin_lock during xfrm_type.input() function.
Follow design as IPsec inbound does.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 net/ipv6/xfrm6_input.c |   54 +++++++++++++++++++++++++----------------------
 1 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 74f3aac..f835ab4 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -63,10 +63,26 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 	struct xfrm_state *x = NULL;
 	int wildcard = 0;
 	xfrm_address_t *xany;
-	struct xfrm_state *xfrm_vec_one = NULL;
 	int nh = 0;
 	int i = 0;
 
+	/* Allocate new secpath or COW existing one. */
+	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+		struct sec_path *sp;
+
+		sp = secpath_dup(skb->sp);
+		if (!sp) {
+			goto drop;
+		}
+		if (skb->sp)
+			secpath_put(skb->sp);
+		skb->sp = sp;
+	}
+
+	if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
+		goto drop;
+	}
+
 	xany = (xfrm_address_t *)&in6addr_any;
 
 	for (i = 0; i < 3; i++) {
@@ -119,47 +135,35 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			continue;
 		}
 
+		spin_unlock(&x->lock);
+
 		nh = x->type->input(x, skb);
 		if (nh <= 0) {
-			spin_unlock(&x->lock);
 			xfrm_state_put(x);
 			x = NULL;
 			continue;
 		}
 
-		x->curlft.bytes += skb->len;
-		x->curlft.packets++;
-
-		spin_unlock(&x->lock);
-
-		xfrm_vec_one = x;
+		/* Found a state */
 		break;
 	}
 
-	if (!xfrm_vec_one)
+	if (!x) {
 		goto drop;
-
-	/* Allocate new secpath or COW existing one. */
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = secpath_dup(skb->sp);
-		if (!sp)
-			goto drop;
-		if (skb->sp)
-			secpath_put(skb->sp);
-		skb->sp = sp;
 	}
 
-	if (1 + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
+	skb->sp->xvec[skb->sp->len++] = x;
+
+	spin_lock(&x->lock);
 
-	skb->sp->xvec[skb->sp->len] = xfrm_vec_one;
-	skb->sp->len ++;
+	x->curlft.bytes += skb->len;
+	x->curlft.packets++;
+
+	spin_unlock(&x->lock);
 
 	return 1;
+
 drop:
-	if (xfrm_vec_one)
-		xfrm_state_put(xfrm_vec_one);
 	return -1;
 }
 
-- 
1.4.4.2


^ permalink raw reply related

* [PATCH 1/3] [XFRM]: Define packet dropping statistics.
From: Masahide NAKAMURA @ 2007-12-21  3:41 UTC (permalink / raw)
  To: herbert; +Cc: netdev, usagi-core, Masahide NAKAMURA

This statistics is shown factor dropped by transformation
at /proc/net/xfrm_stat for developer.
It is a counter designed from current transformation source code
and defined as linux private MIB.

See Documentation/networking/xfrm_proc.txt for the detail.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 Documentation/networking/xfrm_proc.txt |   71 +++++++++++++++++++++++
 include/linux/snmp.h                   |   31 ++++++++++
 include/net/snmp.h                     |    5 ++
 include/net/xfrm.h                     |   18 ++++++
 net/xfrm/Makefile                      |    1 +
 net/xfrm/xfrm_policy.c                 |   24 ++++++++
 net/xfrm/xfrm_proc.c                   |   96 ++++++++++++++++++++++++++++++++
 7 files changed, 246 insertions(+), 0 deletions(-)

diff --git a/Documentation/networking/xfrm_proc.txt b/Documentation/networking/xfrm_proc.txt
new file mode 100644
index 0000000..ec9045b
--- /dev/null
+++ b/Documentation/networking/xfrm_proc.txt
@@ -0,0 +1,71 @@
+XFRM proc - /proc/net/xfrm_* files
+==================================
+Masahide NAKAMURA <nakam@linux-ipv6.org>
+
+
+Transformation Statistics
+-------------------------
+xfrm_proc is a statistics shown factor dropped by transformation
+for developer.
+It is a counter designed from current transformation source code
+and defined like linux private MIB.
+
+Inbound statistics
+~~~~~~~~~~~~~~~~~~
+XfrmInError:
+	All errors which is not matched others
+XfrmInBufferError:
+	No buffer is left
+XfrmInHdrError:
+	Header error
+XfrmInNoStates:
+	No state is found
+	i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong
+XfrmInStateProtoError:
+	Transformation protocol specific error
+	e.g. SA key is wrong
+XfrmInStateModeError:
+	Transformation mode specific error
+XfrmInSeqOutOfWindow:
+	Sequence out of window
+XfrmInStateExpired:
+	State is expired
+XfrmInStateMismatch:
+	State has mismatch option
+	e.g. UDP encapsulation type is mismatch
+XfrmInStateInvalid:
+	State is invalid
+XfrmInTmplMismatch:
+	No matching template for states
+	e.g. Inbound SAs are correct but SP rule is wrong
+XfrmInNoPols:
+	No policy is found for states
+	e.g. Inbound SAs are correct but no SP is found
+XfrmInPolBlock:
+	Policy discards
+XfrmInPolError:
+	Policy error
+
+Outbound errors
+~~~~~~~~~~~~~~~
+XfrmOutError:
+	All errors which is not matched others
+XfrmOutBundleGenError:
+	Bundle generation error
+XfrmOutBundleCheckError:
+	Bundle check error
+XfrmOutNoStates:
+	No state is found
+XfrmOutStateProtoError:
+	Transformation protocol specific error
+XfrmOutStateModeError:
+	Transformation mode specific error
+	e.g. Outer header space is not enough
+XfrmOutStateExpired:
+	State is expired
+XfrmOutPolBlock:
+	Policy discards
+XfrmOutPolDead:
+	Policy is dead
+XfrmOutPolError:
+	Policy error
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 89f0c2b..86d3eff 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -217,4 +217,35 @@ enum
 	__LINUX_MIB_MAX
 };
 
+/* linux Xfrm mib definitions */
+enum
+{
+	LINUX_MIB_XFRMNUM = 0,
+	LINUX_MIB_XFRMINERROR,			/* XfrmInError */
+	LINUX_MIB_XFRMINBUFFERERROR,		/* XfrmInBufferError */
+	LINUX_MIB_XFRMINHDRERROR,		/* XfrmInHdrError */
+	LINUX_MIB_XFRMINNOSTATES,		/* XfrmInNoStates */
+	LINUX_MIB_XFRMINSTATEPROTOERROR,	/* XfrmInStateProtoError */
+	LINUX_MIB_XFRMINSTATEMODEERROR,		/* XfrmInStateModeError */
+	LINUX_MIB_XFRMINSEQOUTOFWINDOW,		/* XfrmInSeqOutOfWindow */
+	LINUX_MIB_XFRMINSTATEEXPIRED,		/* XfrmInStateExpired */
+	LINUX_MIB_XFRMINSTATEMISMATCH,		/* XfrmInStateMismatch */
+	LINUX_MIB_XFRMINSTATEINVALID,		/* XfrmInStateInvalid */
+	LINUX_MIB_XFRMINTMPLMISMATCH,		/* XfrmInTmplMismatch */
+	LINUX_MIB_XFRMINNOPOLS,			/* XfrmInNoPols */
+	LINUX_MIB_XFRMINPOLBLOCK,		/* XfrmInPolBlock */
+	LINUX_MIB_XFRMINPOLERROR,		/* XfrmInPolError */
+	LINUX_MIB_XFRMOUTERROR,			/* XfrmOutError */
+	LINUX_MIB_XFRMOUTBUNDLEGENERROR,	/* XfrmOutBundleGenError */
+	LINUX_MIB_XFRMOUTBUNDLECHECKERROR,	/* XfrmOutBundleCheckError */
+	LINUX_MIB_XFRMOUTNOSTATES,		/* XfrmOutNoStates */
+	LINUX_MIB_XFRMOUTSTATEPROTOERROR,	/* XfrmOutStateProtoError */
+	LINUX_MIB_XFRMOUTSTATEMODEERROR,	/* XfrmOutStateModeError */
+	LINUX_MIB_XFRMOUTSTATEEXPIRED,		/* XfrmOutStateExpired */
+	LINUX_MIB_XFRMOUTPOLBLOCK,		/* XfrmOutPolBlock */
+	LINUX_MIB_XFRMOUTPOLDEAD,		/* XfrmOutPolDead */
+	LINUX_MIB_XFRMOUTPOLERROR,		/* XfrmOutPolError */
+	__LINUX_MIB_XFRMMAX
+};
+
 #endif	/* _LINUX_SNMP_H */
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 9c5793d..f2603c6 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -117,6 +117,11 @@ struct linux_mib {
 	unsigned long	mibs[LINUX_MIB_MAX];
 };
 
+/* Linux Xfrm */
+#define LINUX_MIB_XFRMMAX	__LINUX_MIB_XFRMMAX
+struct linux_xfrm_mib {
+	unsigned long	mibs[LINUX_MIB_XFRMMAX];
+};
 
 /* 
  * FIXME: On x86 and some other CPUs the split into user and softirq parts
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 6df8253..551bb78 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -19,6 +19,9 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
+#ifdef CONFIG_XFRM_STATISTICS
+#include <net/snmp.h>
+#endif
 
 #define XFRM_PROTO_ESP		50
 #define XFRM_PROTO_AH		51
@@ -34,6 +37,17 @@
 #define MODULE_ALIAS_XFRM_TYPE(family, proto) \
 	MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
 
+#ifdef CONFIG_XFRM_STATISTICS
+DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
+#define XFRM_INC_STATS(field)		SNMP_INC_STATS(xfrm_statistics, field)
+#define XFRM_INC_STATS_BH(field)	SNMP_INC_STATS_BH(xfrm_statistics, field)
+#define XFRM_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(xfrm_statistics, field)
+#else
+#define XFRM_INC_STATS(field)
+#define XFRM_INC_STATS_BH(field)
+#define XFRM_INC_STATS_USER(field)
+#endif
+
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
@@ -1139,6 +1153,10 @@ static inline void xfrm6_fini(void)
 }
 #endif
 
+#ifdef CONFIG_XFRM_STATISTICS
+extern int xfrm_proc_init(void);
+#endif
+
 extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
 extern struct xfrm_state *xfrm_state_alloc(void);
 extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, 
diff --git a/net/xfrm/Makefile b/net/xfrm/Makefile
index 45744a3..332cfb0 100644
--- a/net/xfrm/Makefile
+++ b/net/xfrm/Makefile
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
 		      xfrm_input.o xfrm_output.o xfrm_algo.o
+obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4f823f4..7dcc6c1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -27,11 +27,19 @@
 #include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
+#ifdef CONFIG_XFRM_STATISTICS
+#include <net/snmp.h>
+#endif
 
 #include "xfrm_hash.h"
 
 int sysctl_xfrm_larval_drop __read_mostly;
 
+#ifdef CONFIG_XFRM_STATISTICS
+DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
+EXPORT_SYMBOL(xfrm_statistics);
+#endif
+
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -2258,6 +2266,16 @@ static struct notifier_block xfrm_dev_notifier = {
 	0
 };
 
+#ifdef CONFIG_XFRM_STATISTICS
+static int __init xfrm_statistics_init(void)
+{
+	if (snmp_mib_init((void **)xfrm_statistics,
+			  sizeof(struct linux_xfrm_mib)) < 0)
+		return -ENOMEM;
+	return 0;
+}
+#endif
+
 static void __init xfrm_policy_init(void)
 {
 	unsigned int hmask, sz;
@@ -2294,9 +2312,15 @@ static void __init xfrm_policy_init(void)
 
 void __init xfrm_init(void)
 {
+#ifdef CONFIG_XFRM_STATISTICS
+	xfrm_statistics_init();
+#endif
 	xfrm_state_init();
 	xfrm_policy_init();
 	xfrm_input_init();
+#ifdef CONFIG_XFRM_STATISTICS
+	xfrm_proc_init();
+#endif
 }
 
 #ifdef CONFIG_AUDITSYSCALL
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
new file mode 100644
index 0000000..31d0354
--- /dev/null
+++ b/net/xfrm/xfrm_proc.c
@@ -0,0 +1,96 @@
+/*
+ * xfrm_proc.c
+ *
+ * Copyright (C)2006-2007 USAGI/WIDE Project
+ *
+ * Authors:	Masahide NAKAMURA <nakam@linux-ipv6.org>
+ *
+ * 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/proc_fs.h>
+#include <linux/seq_file.h>
+#include <net/snmp.h>
+#include <net/xfrm.h>
+
+static struct snmp_mib xfrm_mib_list[] = {
+	SNMP_MIB_ITEM("XfrmInError", LINUX_MIB_XFRMINERROR),
+	SNMP_MIB_ITEM("XfrmInBufferError", LINUX_MIB_XFRMINBUFFERERROR),
+	SNMP_MIB_ITEM("XfrmInHdrError", LINUX_MIB_XFRMINHDRERROR),
+	SNMP_MIB_ITEM("XfrmInNoStates", LINUX_MIB_XFRMINNOSTATES),
+	SNMP_MIB_ITEM("XfrmInStateProtoError", LINUX_MIB_XFRMINSTATEPROTOERROR),
+	SNMP_MIB_ITEM("XfrmInStateModeError", LINUX_MIB_XFRMINSTATEMODEERROR),
+	SNMP_MIB_ITEM("XfrmInSeqOutOfWindow", LINUX_MIB_XFRMINSEQOUTOFWINDOW),
+	SNMP_MIB_ITEM("XfrmInStateExpired", LINUX_MIB_XFRMINSTATEEXPIRED),
+	SNMP_MIB_ITEM("XfrmInStateMismatch", LINUX_MIB_XFRMINSTATEMISMATCH),
+	SNMP_MIB_ITEM("XfrmInStateInvalid", LINUX_MIB_XFRMINSTATEINVALID),
+	SNMP_MIB_ITEM("XfrmInTmplMismatch", LINUX_MIB_XFRMINTMPLMISMATCH),
+	SNMP_MIB_ITEM("XfrmInNoPols", LINUX_MIB_XFRMINNOPOLS),
+	SNMP_MIB_ITEM("XfrmInPolBlock", LINUX_MIB_XFRMINPOLBLOCK),
+	SNMP_MIB_ITEM("XfrmInPolError", LINUX_MIB_XFRMINPOLERROR),
+	SNMP_MIB_ITEM("XfrmOutError", LINUX_MIB_XFRMOUTERROR),
+	SNMP_MIB_ITEM("XfrmOutBundleGenError", LINUX_MIB_XFRMOUTBUNDLEGENERROR),
+	SNMP_MIB_ITEM("XfrmOutBundleCheckError", LINUX_MIB_XFRMOUTBUNDLECHECKERROR),
+	SNMP_MIB_ITEM("XfrmOutNoStates", LINUX_MIB_XFRMOUTNOSTATES),
+	SNMP_MIB_ITEM("XfrmOutStateProtoError", LINUX_MIB_XFRMOUTSTATEPROTOERROR),
+	SNMP_MIB_ITEM("XfrmOutStateModeError", LINUX_MIB_XFRMOUTSTATEMODEERROR),
+	SNMP_MIB_ITEM("XfrmOutStateExpired", LINUX_MIB_XFRMOUTSTATEEXPIRED),
+	SNMP_MIB_ITEM("XfrmOutPolBlock", LINUX_MIB_XFRMOUTPOLBLOCK),
+	SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
+	SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR),
+	SNMP_MIB_SENTINEL
+};
+
+static unsigned long
+fold_field(void *mib[], int offt)
+{
+        unsigned long res = 0;
+        int i;
+
+        for_each_possible_cpu(i) {
+                res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
+                res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
+        }
+        return res;
+}
+
+static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
+{
+	int i;
+	for (i=0; xfrm_mib_list[i].name; i++)
+		seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
+			   fold_field((void **)xfrm_statistics,
+				      xfrm_mib_list[i].entry));
+	return 0;
+}
+
+static int xfrm_statistics_seq_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xfrm_statistics_seq_show, NULL);
+}
+
+static struct file_operations xfrm_statistics_seq_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = xfrm_statistics_seq_open,
+	.read	 = seq_read,
+	.llseek	 = seq_lseek,
+	.release = single_release,
+};
+
+int __init xfrm_proc_init(void)
+{
+	int rc = 0;
+
+	if (!proc_net_fops_create(&init_net, "xfrm_stat", S_IRUGO,
+				  &xfrm_statistics_seq_fops))
+		goto stat_fail;
+
+ out:
+	return rc;
+
+ stat_fail:
+	rc = -ENOMEM;
+	goto out;
+}
-- 
1.4.4.2


^ permalink raw reply related

* [PATCH 2/3] [XFRM]: Support to increment packet dropping statistics.
From: Masahide NAKAMURA @ 2007-12-21  3:41 UTC (permalink / raw)
  To: herbert; +Cc: netdev, usagi-core, Masahide NAKAMURA

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
---
 net/ipv6/xfrm6_input.c |    3 ++
 net/xfrm/xfrm_input.c  |   41 +++++++++++++++++++++++-------
 net/xfrm/xfrm_output.c |    6 ++++-
 net/xfrm/xfrm_policy.c |   63 ++++++++++++++++++++++++++++++++++++++---------
 4 files changed, 90 insertions(+), 23 deletions(-)

diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index f835ab4..6644fc6 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -72,6 +72,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 
 		sp = secpath_dup(skb->sp);
 		if (!sp) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
 			goto drop;
 		}
 		if (skb->sp)
@@ -80,6 +81,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 	}
 
 	if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
+		XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
 		goto drop;
 	}
 
@@ -149,6 +151,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 	}
 
 	if (!x) {
+		XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
 		goto drop;
 	}
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 8624cbd..493243f 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -119,8 +119,10 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		struct sec_path *sp;
 
 		sp = secpath_dup(skb->sp);
-		if (!sp)
+		if (!sp) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
 			goto drop;
+		}
 		if (skb->sp)
 			secpath_put(skb->sp);
 		skb->sp = sp;
@@ -131,31 +133,45 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	family = XFRM_SPI_SKB_CB(skb)->family;
 
 	seq = 0;
-	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
+	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
+		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
 		goto drop;
+	}
 
 	do {
-		if (skb->sp->len == XFRM_MAX_DEPTH)
+		if (skb->sp->len == XFRM_MAX_DEPTH) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
 			goto drop;
+		}
 
 		x = xfrm_state_lookup(daddr, spi, nexthdr, family);
-		if (x == NULL)
+		if (x == NULL) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
 			goto drop;
+		}
 
 		skb->sp->xvec[skb->sp->len++] = x;
 
 		spin_lock(&x->lock);
-		if (unlikely(x->km.state != XFRM_STATE_VALID))
+		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
 			goto drop_unlock;
+		}
 
-		if ((x->encap ? x->encap->encap_type : 0) != encap_type)
+		if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
 			goto drop_unlock;
+		}
 
-		if (x->props.replay_window && xfrm_replay_check(x, seq))
+		if (x->props.replay_window && xfrm_replay_check(x, seq)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW);
 			goto drop_unlock;
+		}
 
-		if (xfrm_state_check_expire(x))
+		if (xfrm_state_check_expire(x)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED);
 			goto drop_unlock;
+		}
 
 		spin_unlock(&x->lock);
 
@@ -171,6 +187,7 @@ resume:
 		if (nexthdr <= 0) {
 			if (nexthdr == -EBADMSG)
 				x->stats.integrity_failed++;
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR);
 			goto drop_unlock;
 		}
 
@@ -187,8 +204,10 @@ resume:
 
 		XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
 
-		if (x->inner_mode->input(x, skb))
+		if (x->inner_mode->input(x, skb)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR);
 			goto drop;
+		}
 
 		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
 			decaps = 1;
@@ -203,8 +222,10 @@ resume:
 		family = x->outer_mode->afinfo->family;
 
 		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
-		if (err < 0)
+		if (err < 0) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
 			goto drop;
+		}
 	} while (!err);
 
 	nf_reset(skb);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 26fa0cb..867484a 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -69,10 +69,13 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 		err = x->type->output(x, skb);
 
 resume:
-		if (err)
+		if (err) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR);
 			goto error_nolock;
+		}
 
 		if (!(skb->dst = dst_pop(dst))) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
 			err = -EHOSTUNREACH;
 			goto error_nolock;
 		}
@@ -167,6 +170,7 @@ int xfrm_output(struct sk_buff *skb)
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		err = skb_checksum_help(skb);
 		if (err) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
 			kfree_skb(skb);
 			return err;
 		}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7dcc6c1..6f8ca24 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1494,8 +1494,10 @@ restart:
 	if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
 		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
 		err = PTR_ERR(policy);
-		if (IS_ERR(policy))
+		if (IS_ERR(policy)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
 			goto dropdst;
+		}
 	}
 
 	if (!policy) {
@@ -1529,6 +1531,7 @@ restart:
 	default:
 	case XFRM_POLICY_BLOCK:
 		/* Prohibit the flow */
+		XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
 		err = -EPERM;
 		goto error;
 
@@ -1548,6 +1551,7 @@ restart:
 		 */
 		dst = xfrm_find_bundle(fl, policy, family);
 		if (IS_ERR(dst)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			err = PTR_ERR(dst);
 			goto error;
 		}
@@ -1562,10 +1566,12 @@ restart:
 							    XFRM_POLICY_OUT);
 			if (pols[1]) {
 				if (IS_ERR(pols[1])) {
+					XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
 					err = PTR_ERR(pols[1]);
 					goto error;
 				}
 				if (pols[1]->action == XFRM_POLICY_BLOCK) {
+					XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
 					err = -EPERM;
 					goto error;
 				}
@@ -1611,6 +1617,7 @@ restart:
 				nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
 
 				if (nx == -EAGAIN && signal_pending(current)) {
+					XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
 					err = -ERESTART;
 					goto error;
 				}
@@ -1621,8 +1628,10 @@ restart:
 				}
 				err = nx;
 			}
-			if (err < 0)
+			if (err < 0) {
+				XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
 				goto error;
+			}
 		}
 		if (nx == 0) {
 			/* Flow passes not transformed. */
@@ -1632,8 +1641,10 @@ restart:
 
 		dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
 		err = PTR_ERR(dst);
-		if (IS_ERR(dst))
+		if (IS_ERR(dst)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR);
 			goto error;
+		}
 
 		for (pi = 0; pi < npols; pi++) {
 			read_lock_bh(&pols[pi]->lock);
@@ -1652,6 +1663,10 @@ restart:
 			if (dst)
 				dst_free(dst);
 
+			if (pol_dead)
+				XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
+			else
+				XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			err = -EHOSTUNREACH;
 			goto error;
 		}
@@ -1664,6 +1679,7 @@ restart:
 			write_unlock_bh(&policy->lock);
 			if (dst)
 				dst_free(dst);
+			XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
 			goto error;
 		}
 
@@ -1817,8 +1833,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 	dir &= XFRM_POLICY_MASK;
 	fl_dir = policy_to_flow_dir(dir);
 
-	if (__xfrm_decode_session(skb, &fl, family, reverse) < 0)
+	if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
+		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
 		return 0;
+	}
+
 	nf_nat_decode_session(skb, &fl, family);
 
 	/* First, check used SA against their selectors. */
@@ -1827,28 +1846,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 
 		for (i=skb->sp->len-1; i>=0; i--) {
 			struct xfrm_state *x = skb->sp->xvec[i];
-			if (!xfrm_selector_match(&x->sel, &fl, family))
+			if (!xfrm_selector_match(&x->sel, &fl, family)) {
+				XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
 				return 0;
+			}
 		}
 	}
 
 	pol = NULL;
 	if (sk && sk->sk_policy[dir]) {
 		pol = xfrm_sk_policy_lookup(sk, dir, &fl);
-		if (IS_ERR(pol))
+		if (IS_ERR(pol)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
 			return 0;
+		}
 	}
 
 	if (!pol)
 		pol = flow_cache_lookup(&fl, family, fl_dir,
 					xfrm_policy_lookup);
 
-	if (IS_ERR(pol))
+	if (IS_ERR(pol)) {
+		XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
 		return 0;
+	}
 
 	if (!pol) {
 		if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
 			xfrm_secpath_reject(xerr_idx, skb, &fl);
+			XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS);
 			return 0;
 		}
 		return 1;
@@ -1864,8 +1890,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 						    &fl, family,
 						    XFRM_POLICY_IN);
 		if (pols[1]) {
-			if (IS_ERR(pols[1]))
+			if (IS_ERR(pols[1])) {
+				XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
 				return 0;
+			}
 			pols[1]->curlft.use_time = get_seconds();
 			npols ++;
 		}
@@ -1886,10 +1914,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 
 		for (pi = 0; pi < npols; pi++) {
 			if (pols[pi] != pol &&
-			    pols[pi]->action != XFRM_POLICY_ALLOW)
+			    pols[pi]->action != XFRM_POLICY_ALLOW) {
+				XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
 				goto reject;
-			if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH)
+			}
+			if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {
+				XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
 				goto reject_error;
+			}
 			for (i = 0; i < pols[pi]->xfrm_nr; i++)
 				tpp[ti++] = &pols[pi]->xfrm_vec[i];
 		}
@@ -1911,16 +1943,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 				if (k < -1)
 					/* "-2 - errored_index" returned */
 					xerr_idx = -(2+k);
+				XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
 				goto reject;
 			}
 		}
 
-		if (secpath_has_nontransport(sp, k, &xerr_idx))
+		if (secpath_has_nontransport(sp, k, &xerr_idx)) {
+			XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
 			goto reject;
+		}
 
 		xfrm_pols_put(pols, npols);
 		return 1;
 	}
+	XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
 
 reject:
 	xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -1934,8 +1970,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
 	struct flowi fl;
 
-	if (xfrm_decode_session(skb, &fl, family) < 0)
+	if (xfrm_decode_session(skb, &fl, family) < 0) {
+		/* XXX: we should have something like FWDHDRERROR here. */
+		XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
 		return 0;
+	}
 
 	return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
 }
-- 
1.4.4.2


^ permalink raw reply related

* Re: [PATCH 6/8] tg3: Correct sw autoneg flow control advertisements
From: David Miller @ 2007-12-21  4:09 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191605.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 15:00:05 -0800

> This patch modifies the software autoneg code to use the administrator
> specified flow control parameters.  Since the autonegotiation code uses
> alternative flow control enumerations, the 1000-BaseX utility functions
> are used and code was added to convert the definitions to and from the
> alternate enumerations.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 7/8] tg3: Fix supporting flowctrl code
From: David Miller @ 2007-12-21  4:10 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191608.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 15:00:08 -0800

> This patch does three things.  It modifies tg3_setup_flow_control() to
> use the administrator requested flow control settings if
> autonegotiation is turned off.  It slightly modifies the
> tg3_setup_fiber_mii_phy() function to account for this new use case.
> And finally, it does the same for tg3_setup_copper_phy().
> 
> The copper modifications are more than a small multi-line change.  The
> new code makes an attempt to avoid a link renegotiation if the link is
> active at half duplex and the only difference between the current
> advertised settings and requested advertised settings is the
> flow control advertisements.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 8/8] tg3: Update version to 3.87
From: David Miller @ 2007-12-21  4:10 UTC (permalink / raw)
  To: mcarlson; +Cc: netdev, mchan, andy
In-Reply-To: <1198191611.0@teletran1>

From: "Matt Carlson" <mcarlson@broadcom.com>
Date: Thu, 20 Dec 2007 15:00:11 -0800

> This patch updates the version number to 3.87.
> 
> Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
> Signed-off-by: Michael Chan <mchan@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH 2/4] [CORE]: datagram: basic memory accounting functions
From: Hideo AOKI @ 2007-12-21  4:18 UTC (permalink / raw)
  To: David Miller
  Cc: herbert, netdev, tyasui, mhiramat, satoshi.oshima.fk, billfink,
	andi, johnpol, shemminger, yoshfuji, yumiko.sugita.yf, haoki
In-Reply-To: <20071220.034304.212231150.davem@davemloft.net>

Hello,

Thank you so much for your comments.

David Miller wrote:

> All of these other functions are identical copies of the stream
> counterparts, they should all be consolidated.
> 
> I still see a lot of special casing, instead of large pieces of common
> code.
> 
> There should be one core set of functions that handle the memory
> accounting, regardless of socket type.  Maybe there is one spot where
> something like sk->prot->doing_memory_accounting is tested, but that's
> it.

I understood. I'll re-write my patch set to make memory accounting
core functions.

> Also, the memory accounting is done at different parts in
> the socket code paths for stream vs. datagram.  This is why
> everything is inconsistent, and, a mess.

Could you tell me more detailed information?

Does this comment mean interface and usage of memory accounting functions?
If so, I'll consolidate functions like sk_stream_set_owner_r() and
sk_stream_free_skb(). And, I may have to use memory accounting functions in
memory allocating functions like sk_stream_alloc_pskb() as possible
instead of inside of socket operating functions.

Or, does the comment mean that send buffer accounting in IP layer
(e.g. ip_append_data()) is wrong?

Anyway, in next patch set, I'm going to consolidate mem_schedule
functions and mem_reclaim functions. To do so, some of memory
accounting functions for stream protocols will be renamed or
be moved to core/sock.c from core/stream.c.

I would like to know what kind of enhancement must be needed for
memory accounting core functions.

Again, thank you for taking your time to review this feature.

Best regards,
Hideo

-- 
Hitachi Computer Products (America) Inc.

^ permalink raw reply


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