Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next-2.6 v3 00/12] net-caif: introducing CAIF protocol stack
From: David Miller @ 2010-02-27 10:31 UTC (permalink / raw)
  To: sjur.brandeland
  Cc: marcel, netdev, daniel.martensson, kaber, stefano.babic,
	randy.dunlap
In-Reply-To: <61D8D34BB13CFE408D154529C120E079138CB8@eseldmw101.eemea.ericsson.se>

From: Sjur Brændeland <sjur.brandeland@stericsson.com>
Date: Sat, 27 Feb 2010 11:05:14 +0100

> Unfortunately, I am traveling until Thursday this week, without
> Internet access, so if you would like me to resubmit again I will
> not be able to do that before Thursday or Friday this week.

Then you won't be able to make this merge window, that's way too
late.

Sorry.

^ permalink raw reply

* RE: [PATCH net-next-2.6 v3 00/12] net-caif: introducing CAIF protocol stack
From: Sjur Brændeland @ 2010-02-27 10:05 UTC (permalink / raw)
  To: David Miller
  Cc: marcel, netdev, Daniel Martensson, kaber, stefano.babic,
	randy.dunlap
In-Reply-To: <20100226.012204.67216627.davem@davemloft.net>

David Miller wrote:
>> Hi Marcel.
>>>> CHANGE LOG:
>>>> Based on review comments from David Miller and Marcel Holtmann on the
>>>> previous patch set submitted the 16 February the following changes
>>>> have been done: 
>>>> - Removed ifdef __cplusplus from caif_socket.h
>>>> - Use socket level SOL_IP for socket options SO_PRIORITY and
>>>> SO_BINDTODEVICE
>>> 
>>> are you sure it is not better to use SOL_SOCKET here. At least
>>> according to man 7 socket this would make a lot more sense. My point
>>> in actually using SO_PRIORITY and SO_BINDTODEVICE is to use standard
>>> socket options that are already used by everybody else. So they know
>>> what to expect.    
>>> 
>> Yes, this makes sense. I'll update this.
>
>Please fix this up and resubmit your patch series so I can add
>it to the net-next-2.6 tree.

I have sent a V4 patch-set, fixing the review comments on the 
V3 patch-set. But there are still review comments coming in.

Unfortunately, I am traveling until Thursday this week, without Internet access,
so if you would like me to resubmit again I will not be able to do that before
Thursday or Friday this week.

BR/Sjur

^ permalink raw reply

* Re: [net-next-2.6 PATCH] Preserve queue mapping with bonding and VLAN devices
From: David Miller @ 2010-02-27 10:02 UTC (permalink / raw)
  To: sysoleg; +Cc: netdev
In-Reply-To: <14541267264382@webmail122.yandex.ru>

From: "\"Oleg A. Arkhangelsky\"" <sysoleg@yandex.ru>
Date: Sat, 27 Feb 2010 12:53:02 +0300

> 26.02.10, 05:50, "David Miller" <davem@davemloft.net>:
> 
>>  Your patches are fine, but they are whitespace corrupted by your
>>  email client (tabs turned into spaces, etc.) so they won't apply
>>  properly.
>>  
>>  Please fix this up and resend your patches.
>>  
>>  Thanks!
> 
> I'm sorry, corrected it.

I said "patches", plural.

Both your patches had whitespace issues.

Please resend both patches, as a series, with the whitespace fixed.


^ permalink raw reply

* Re: [RFC PATCH] fix problems with NETIF_F_HIGHDMA in networking drivers
From: David Miller @ 2010-02-27  9:53 UTC (permalink / raw)
  To: hancockrwd; +Cc: bzolnier, linux-kernel, netdev, linux-usb
In-Reply-To: <51f3faa71002261908y7cfa62eeicb3e56d5c920887a@mail.gmail.com>

From: Robert Hancock <hancockrwd@gmail.com>
Date: Fri, 26 Feb 2010 21:08:04 -0600

> That seems like a reasonable approach to me. Only question is how to
> implement the check for DMA_64BIT. Can we just check page_to_phys on
> each of the pages in the skb to see if it's > 0xffffffff ? Are there
> any architectures where it's more complicated than that?

On almost every platform it's "more complicated than that".

This is the whole issue.  What matters is the final DMA address and
since we have IOMMUs and the like, it is absolutely not tenable to
solve this by checking physical address attributes.

^ permalink raw reply

* Re: [net-next-2.6 PATCH] Preserve queue mapping with bonding and VLAN devices
From: "Oleg A. Arkhangelsky" @ 2010-02-27  9:53 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20100226.055025.30718012.davem@davemloft.net>

26.02.10, 05:50, "David Miller" <davem@davemloft.net>:

>  Your patches are fine, but they are whitespace corrupted by your
>  email client (tabs turned into spaces, etc.) so they won't apply
>  properly.
>  
>  Please fix this up and resend your patches.
>  
>  Thanks!

I'm sorry, corrected it. By the way additional check was added to
return 0 in skb_get_queue_mapping() when skb->queue_mapping = 0.
Initial multiqueue support for bonding is also included here.

---

1. Forwarded packet goes through dev_queue_xmit() more that once
when using bonding or 802.1q VLAN devices, so we've lost rx-tx queue
mapping index for real devices. This is because initial queue index value
(as it recorded by skb_record_tx_queue()) is overwritten
by skb_set_queue_mapping().

2. Initial multiqueue support for bonding devices. Make bonding driver
multiqueue aware.

Signed-off-by: Oleg A. Arkhangelsky  

---
 drivers/net/bnx2.c              |    2 +-
 drivers/net/bnx2x_main.c        |    2 +-
 drivers/net/bonding/bond_main.c |    5 +++--
 drivers/net/bonding/bonding.h   |    1 +
 drivers/net/gianfar.c           |    6 +++---
 drivers/net/igb/igb_main.c      |    2 +-
 drivers/net/ixgbe/ixgbe_main.c  |    6 +++---
 drivers/net/mlx4/en_tx.c        |    2 +-
 drivers/net/niu.c               |    2 +-
 drivers/net/qlge/qlge_main.c    |    2 +-
 drivers/net/s2io.c              |    2 +-
 include/linux/skbuff.h          |   14 ++------------
 net/core/dev.c                  |    2 +-
 13 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d3f739a..abbbe40 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -3199,7 +3199,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
 
-		skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
+		skb_set_queue_mapping(skb, bnapi - &bp->bnx2_napi[0]);
 
 #ifdef BCM_VLAN
 		if (hw_vlan)
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 5adf2a0..6e8e327 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -1681,7 +1681,7 @@ reuse_rx:
 			}
 		}
 
-		skb_record_rx_queue(skb, fp->index);
+		skb_set_queue_mapping(skb, fp->index);
 
 #ifdef BCM_VLAN
 		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1787e3c..f54f590 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4928,8 +4928,9 @@ int bond_create(struct net *net, const char *name)
 
 	rtnl_lock();
 
-	bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
-				bond_setup);
+	bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "",
+				bond_setup,
+				min_t(u32, BOND_MAX_TX_QUEUES, num_online_cpus()));
 	if (!bond_dev) {
 		pr_err("%s: eek! can't alloc netdev!\n", name);
 		res = -ENOMEM;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 257a7a4..4a6cfb4 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -29,6 +29,7 @@
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
 #define BOND_MAX_ARP_TARGETS	16
+#define BOND_MAX_TX_QUEUES	8 
 
 #define IS_UP(dev)					   \
 	      ((((dev)->flags & IFF_UP) == IFF_UP)	&& \
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 6aa526e..d034f4e 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1934,7 +1934,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned int nr_frags, length;
 
 
-	rq = skb->queue_mapping;
+	rq = skb_get_queue_mapping(skb);
 	tx_queue = priv->tx_queue[rq];
 	txq = netdev_get_tx_queue(dev, rq);
 	base = tx_queue->tx_bd_base;
@@ -2466,7 +2466,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
 	/* Remove the FCB from the skb */
 	/* Remove the padded bytes, if there are any */
 	if (amount_pull) {
-		skb_record_rx_queue(skb, fcb->rq);
+		skb_set_queue_mapping(skb, fcb->rq);
 		skb_pull(skb, amount_pull);
 	}
 
@@ -2549,7 +2549,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
 				/* Remove the FCS from the packet length */
 				skb_put(skb, pkt_len);
 				rx_queue->stats.rx_bytes += pkt_len;
-				skb_record_rx_queue(skb, rx_queue->qindex);
+				skb_set_queue_mapping(skb, rx_queue->qindex);
 				gfar_process_frame(dev, skb, amount_pull);
 
 			} else {
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 583a21c..def942c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3838,7 +3838,7 @@ static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
 		return NETDEV_TX_OK;
 	}
 
-	r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
+	r_idx = skb_get_queue_mapping(skb) & (IGB_ABS_MAX_TX_QUEUES - 1);
 	tx_ring = adapter->multi_tx_table[r_idx];
 
 	/* This goes back to the question of how to logically map a tx queue
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index a961da2..c6a3231 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5662,13 +5662,13 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
 		tx_flags |= vlan_tx_tag_get(skb);
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 			tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;
-			tx_flags |= ((skb->queue_mapping & 0x7) << 13);
+			tx_flags |= ((skb_get_queue_mapping(skb) & 0x7) << 13);
 		}
 		tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 	} else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
 		if (skb->priority != TC_PRIO_CONTROL) {
-			tx_flags |= ((skb->queue_mapping & 0x7) << 13);
+			tx_flags |= ((skb_get_queue_mapping(skb) & 0x7) << 13);
 			tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
 			tx_flags |= IXGBE_TX_FLAGS_VLAN;
 		} else {
@@ -5677,7 +5677,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
 		}
 	}
 
-	tx_ring = adapter->tx_ring[skb->queue_mapping];
+	tx_ring = adapter->tx_ring[skb_get_queue_mapping(skb)];
 
 	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
 	    (skb->protocol == htons(ETH_P_FCOE))) {
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 3d1396a..c1bca72 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -624,7 +624,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto tx_drop;
 	}
 
-	tx_ind = skb->queue_mapping;
+	tx_ind = skb_get_queue_mapping(skb);
 	ring = &priv->tx_ring[tx_ind];
 	if (priv->vlgrp && vlan_tx_tag_present(skb))
 		vlan_tag = vlan_tx_tag_get(skb);
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 0678f31..0819cb2 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3516,7 +3516,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
 	rp->rx_bytes += skb->len;
 
 	skb->protocol = eth_type_trans(skb, np->dev);
-	skb_record_rx_queue(skb, rp->rx_channel);
+	skb_set_queue_mapping(skb, rp->rx_channel);
 	napi_gro_receive(napi, skb);
 
 	return num_rcr;
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index c26ec5d..f645d42 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2525,7 +2525,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
 	struct ql_adapter *qdev = netdev_priv(ndev);
 	int tso;
 	struct tx_ring *tx_ring;
-	u32 tx_ring_idx = (u32) skb->queue_mapping;
+	u32 tx_ring_idx = (u32) skb_get_queue_mapping(skb);
 
 	tx_ring = &qdev->tx_ring[tx_ring_idx];
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 43bc66a..afdab06 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -7549,7 +7549,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 
 	swstats->mem_freed += skb->truesize;
 send_up:
-	skb_record_rx_queue(skb, ring_no);
+	skb_set_queue_mapping(skb, ring_no);
 	queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
 aggregate:
 	sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ba0f8e3..c01cc1d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2013,12 +2013,12 @@ static inline void skb_init_secmark(struct sk_buff *skb)
 
 static inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping)
 {
-	skb->queue_mapping = queue_mapping;
+	skb->queue_mapping = queue_mapping + 1;
 }
 
 static inline u16 skb_get_queue_mapping(const struct sk_buff *skb)
 {
-	return skb->queue_mapping;
+	return skb_rx_queue_recorded(skb) ? skb->queue_mapping - 1 : 0;
 }
 
 static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
@@ -2026,16 +2026,6 @@ static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_bu
 	to->queue_mapping = from->queue_mapping;
 }
 
-static inline void skb_record_rx_queue(struct sk_buff *skb, u16 rx_queue)
-{
-	skb->queue_mapping = rx_queue + 1;
-}
-
-static inline u16 skb_get_rx_queue(const struct sk_buff *skb)
-{
-	return skb->queue_mapping - 1;
-}
-
 static inline bool skb_rx_queue_recorded(const struct sk_buff *skb)
 {
 	return (skb->queue_mapping != 0);
diff --git a/net/core/dev.c b/net/core/dev.c
index eb7f1a4..3beaa21 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1916,7 +1916,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
 	u32 hash;
 
 	if (skb_rx_queue_recorded(skb)) {
-		hash = skb_get_rx_queue(skb);
+		hash = skb->queue_mapping - 1;
 		while (unlikely(hash >= dev->real_num_tx_queues))
 			hash -= dev->real_num_tx_queues;
 		return hash;
---

-- 
wbr, Oleg.

^ permalink raw reply related

* Re: [PATCH 4/7] cxgb4: Add packet queues and packet DMA code
From: David Miller @ 2010-02-27  9:48 UTC (permalink / raw)
  To: dm; +Cc: shemminger, netdev
In-Reply-To: <8A71B368A89016469F72CD08050AD33401359B69@maui.asicdesigners.com>

From: "Dimitrios Michailidis" <dm@chelsio.com>
Date: Fri, 26 Feb 2010 16:10:07 -0800

> I believe this function does not generate any code, the compiler
> statically figures out the result and optimizes any conditionals that
> call it.  What option do you have in mind that would tell the compiler
> if unmap is nop?

I've got better questions:

1) Why is your driver so damn special?

   If this optimization is useful, it dosn't belong privately in
   some driver, it belongs in some generic spot.

2) What configuration does this even help for?  Even bog standard x86
   and x86_64 uses IOMMUs and thus make use of the unmap address.

   I cannot think of one platform that matters where this will even
   trigger.

Get rid of this junk, please.  Because even if it's valid, it doesn't
belong privately in your driver.


^ permalink raw reply

* Re: [PATCH 4/7] cxgb4: Add packet queues and packet DMA code
From: David Miller @ 2010-02-27  9:46 UTC (permalink / raw)
  To: shemminger; +Cc: dm, netdev
In-Reply-To: <20100226155756.09c0485c@nehalam>

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Fri, 26 Feb 2010 15:57:56 -0800

> On Fri, 26 Feb 2010 15:35:36 -0800
> Dimitris Michailidis <dm@chelsio.com> wrote:
> 
>> +
>> +/**
>> + *	need_skb_unmap - does the platform need unmapping of sk_buffs?
>> + *
>> + *	Returns true if the platfrom needs sk_buff unmapping.  The compiler
>> + *	optimizes away unecessary code if this returns true.
>> + */
>> +static inline int need_skb_unmap(void)
>> +{
>> +	/*
>> +	 * This structure is used to tell if the platfrom needs buffer
>> +	 * unmapping by checking if DECLARE_PCI_UNMAP_ADDR defines anything.
>> +	 */
>> +	struct dummy {
>> +		DECLARE_PCI_UNMAP_ADDR(addr);
>> +	};
>> +
>> +	return sizeof(struct dummy) != 0;
>> +}
>> +
> 
> I would prefer one code path and let the compiler decide if unmap
> should be nop; rather than this kind of trick code.

Agreed, this is rediculious.  And there is currently no platform that
matters where this will trigger.

With IOMMUs and even the swiommu layer, even bog standard x86 systems
need the unmap addresses.

Therefore optimizing this is totally unreasonable.  Just use the provided
APIs and let the compiler and the platform defines do the work.

I'm amazed at how people do stuff like this.  If it's a reasonable
opimization, maybe, JUST MAYBE, it's better to optimize it generically
so that every driver gets the benefit NOT JUST YOUR individual driver.


^ permalink raw reply

* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Eric W. Biederman @ 2010-02-27  9:42 UTC (permalink / raw)
  To: Pavel Emelyanov
  Cc: hadi, Daniel Lezcano, Patrick McHardy, Linux Netdev List,
	containers, Netfilter Development Mailinglist, Ben Greear,
	Serge Hallyn, Matt Helsley
In-Reply-To: <4B88E431.6040609@parallels.com>

Pavel Emelyanov <xemul@parallels.com> writes:

> Thanks. What's the problem with setns?

joining a preexisting namespace is roughly the same problem as
unsharing a namespace.  We simply haven't figure out how to do it
safely for the pid and the uid namespaces.

>> I have designed these file descriptors to pin the namespaces, so
>> waiting for them to exit isn't something they can do now.  It makes a
>> lot of sense to have similar ones that take  weak references to the namespaces
>> that we can use to wait for a namespace to exit.
>
> Yes, I saw this from patches. Eric, I'd very much appreciate if we
> workout a solution that will allow us to kill two birds with one stone.
> I do not want to invent yet another bunch of system calls for "taking
> weak reference".

Definitely.  I only consider the current interface to be a mushy not
set in stone.

> As a "brain storm" start up. Can we use inotify/dnotify for this? 
> Or maybe we should better equip the nsfd call with flags argument and 
> add a flag for weak reference? In that case - how shall we get a 
> notification about namespace is dead? With poll? Maybe worth making
> the sys_close return only when the namespace is dead (by providing a
> proper ->release callback of a file)?

We would want poll to work, anything else is a weird work-around.
The challenging part is that we don't have any infrastructure for
notifying when a namespace goes away.  So that has to be built before
we can wire it up to userspace.  I don't expect it is too difficult
but there is work to be done.

Eric


^ permalink raw reply

* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Pavel Emelyanov @ 2010-02-27  9:21 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Ben Greear, Linux Netdev List,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Netfilter Development Mailinglist, Daniel Lezcano
In-Reply-To: <m1mxyvrqvk.fsf-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>

Eric W. Biederman wrote:
> Pavel Emelyanov <xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org> writes:
> 
>> Eric W. Biederman wrote:
>>> Pavel Emelyanov <xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org> writes:
>>>
>>>>>> Yet another set of per-namespace IDs along with CLONE_NEWXXX ones?
>>>>>> I currently have a way to create all namespaces we have with one
>>>>>> syscall. Why don't we have an ability to enter them all with one syscall?
>>>>> The CLONE_NEWXXX series of bits has been an royal pain to work with,
>>>>> and it appears to be unnecessary complications for no gain.
>>>> That's the answer for the "Yet another set..." question.
>>>> How about the "Why don't we have..." one?
>>> I am not certain which question you are asking:
>>>
>>> Why don't we have an ability to enter all namespaces with one syscall
>>> invocation?
>> Exactly. Please add at least the NSTYPE_NSPROXY or whatever, that will
>> pin all namespaces of a given pid from the very beginning.
> 
> For nsfd(2) that is doable.  At least for now setns can't restore it.

Thanks. What's the problem with setns?

>>> Why don't we have a syscall that allows us to enter every namespace?
>> This one is done in the patch, no?
>>
>> Although the approach is OK for me, there's one design issue, that came
>> up to my mind recently: can we use this fd to wail for a namespace to 
>> stop? I currently don't see this ability, but this is something I require
>> badly.
> 
> I have designed these file descriptors to pin the namespaces, so
> waiting for them to exit isn't something they can do now.  It makes a
> lot of sense to have similar ones that take  weak references to the namespaces
> that we can use to wait for a namespace to exit.

Yes, I saw this from patches. Eric, I'd very much appreciate if we
workout a solution that will allow us to kill two birds with one stone.
I do not want to invent yet another bunch of system calls for "taking
weak reference".

As a "brain storm" start up. Can we use inotify/dnotify for this? 
Or maybe we should better equip the nsfd call with flags argument and 
add a flag for weak reference? In that case - how shall we get a 
notification about namespace is dead? With poll? Maybe worth making
the sys_close return only when the namespace is dead (by providing a
proper ->release callback of a file)?

> Eric
> 

^ permalink raw reply

* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Eric W. Biederman @ 2010-02-27  9:04 UTC (permalink / raw)
  To: Pavel Emelyanov
  Cc: hadi, Daniel Lezcano, Patrick McHardy, Linux Netdev List,
	containers, Netfilter Development Mailinglist, Ben Greear,
	Serge Hallyn, Matt Helsley
In-Reply-To: <4B88D80A.8010701@parallels.com>

Pavel Emelyanov <xemul@parallels.com> writes:

> Eric W. Biederman wrote:
>> Pavel Emelyanov <xemul@parallels.com> writes:
>> 
>>>>> Yet another set of per-namespace IDs along with CLONE_NEWXXX ones?
>>>>> I currently have a way to create all namespaces we have with one
>>>>> syscall. Why don't we have an ability to enter them all with one syscall?
>>>> The CLONE_NEWXXX series of bits has been an royal pain to work with,
>>>> and it appears to be unnecessary complications for no gain.
>>> That's the answer for the "Yet another set..." question.
>>> How about the "Why don't we have..." one?
>> 
>> I am not certain which question you are asking:
>> 
>> Why don't we have an ability to enter all namespaces with one syscall
>> invocation?
>
> Exactly. Please add at least the NSTYPE_NSPROXY or whatever, that will
> pin all namespaces of a given pid from the very beginning.

For nsfd(2) that is doable.  At least for now setns can't restore it.

>> Why don't we have a syscall that allows us to enter every namespace?
>
> This one is done in the patch, no?
>
> Although the approach is OK for me, there's one design issue, that came
> up to my mind recently: can we use this fd to wail for a namespace to 
> stop? I currently don't see this ability, but this is something I require
> badly.

I have designed these file descriptors to pin the namespaces, so
waiting for them to exit isn't something they can do now.  It makes a
lot of sense to have similar ones that take  weak references to the namespaces
that we can use to wait for a namespace to exit.

Eric

^ permalink raw reply

* Re: [RFC][PATCH] ns: Syscalls for better namespace sharing control.
From: Pavel Emelyanov @ 2010-02-27  8:30 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: hadi, Daniel Lezcano, Patrick McHardy, Linux Netdev List,
	containers, Netfilter Development Mailinglist, Ben Greear,
	Serge Hallyn, Matt Helsley
In-Reply-To: <m13a0nwu6p.fsf@fess.ebiederm.org>

Eric W. Biederman wrote:
> Pavel Emelyanov <xemul@parallels.com> writes:
> 
>>>> Yet another set of per-namespace IDs along with CLONE_NEWXXX ones?
>>>> I currently have a way to create all namespaces we have with one
>>>> syscall. Why don't we have an ability to enter them all with one syscall?
>>> The CLONE_NEWXXX series of bits has been an royal pain to work with,
>>> and it appears to be unnecessary complications for no gain.
>> That's the answer for the "Yet another set..." question.
>> How about the "Why don't we have..." one?
> 
> I am not certain which question you are asking:
> 
> Why don't we have an ability to enter all namespaces with one syscall
> invocation?

Exactly. Please add at least the NSTYPE_NSPROXY or whatever, that will
pin all namespaces of a given pid from the very beginning.

> Why don't we have a syscall that allows us to enter every namespace?

This one is done in the patch, no?

Although the approach is OK for me, there's one design issue, that came
up to my mind recently: can we use this fd to wail for a namespace to 
stop? I currently don't see this ability, but this is something I require
badly.

Thoughts?

> Eric
> 
> 


^ permalink raw reply

* [PATCH] e1000e: export some settings using ethtool private flags
From: Jeff Garzik @ 2010-02-27  8:23 UTC (permalink / raw)
  To: netdev


The ethtool private flags interface exists to get/set driver-specific
settings at runtime, in a flexible manner.

Use this facility to export a couple e1000e features, that were
previously only set at module initialization time.

Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
---
 drivers/net/e1000e/ethtool.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index b33e3cb..4bda27f 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -112,6 +112,30 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 };
 #define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
 
+enum e1000_pflags {
+	E1000_PF_SMART_POWERDOWN	= (1 << 0),
+	E1000_PF_RO_NVM			= (1 << 1),
+};
+
+#define E1000_N_PFLAGS ARRAY_SIZE(e1000_gstrings_pflags)
+static const char e1000_gstrings_pflags[][ETH_GSTRING_LEN] = {
+	"smart_power_down",
+	"read_only_nvm",
+};
+
+u32 e1000_get_priv_flags(struct net_device *netdev)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	u32 ret = 0;
+
+	if (adapter->flags & FLAG_SMART_POWER_DOWN)
+		ret |= E1000_PF_SMART_POWERDOWN;
+	if (adapter->flags & FLAG_READ_ONLY_NVM)
+		ret |= E1000_PF_RO_NVM;
+
+	return ret;
+}
+
 static int e1000_get_settings(struct net_device *netdev,
 			      struct ethtool_cmd *ecmd)
 {
@@ -1666,6 +1690,8 @@ static int e1000e_get_sset_count(struct net_device *netdev, int sset)
 		return E1000_TEST_LEN;
 	case ETH_SS_STATS:
 		return E1000_STATS_LEN;
+	case ETH_SS_PRIV_FLAGS:
+		return E1000_N_PFLAGS;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -2014,6 +2040,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.set_coalesce		= e1000_set_coalesce,
 	.get_flags		= ethtool_op_get_flags,
 	.set_flags		= ethtool_op_set_flags,
+	.get_priv_flags		= e1000_get_priv_flags,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)

^ permalink raw reply related

* [PATCH] ethtool: do not set some flags, if others failed
From: Jeff Garzik @ 2010-02-27  7:43 UTC (permalink / raw)
  To: netdev


NETIF_F_NTUPLE flag setting introduced a bug:  non-ntuple flags
like LRO may be successfully set, before ioctl(2) returns failure
to userspace.

The set-flags operation should be all-or-none, rather than leaving
things in an inconsistent state prior to reporting failure to
userspace.

Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
---
 net/core/ethtool.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 31b1edd..0f2f821 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -135,21 +135,23 @@ u32 ethtool_op_get_flags(struct net_device *dev)
 int ethtool_op_set_flags(struct net_device *dev, u32 data)
 {
 	const struct ethtool_ops *ops = dev->ethtool_ops;
+	unsigned long features = dev->features;
 
 	if (data & ETH_FLAG_LRO)
-		dev->features |= NETIF_F_LRO;
+		features |= NETIF_F_LRO;
 	else
-		dev->features &= ~NETIF_F_LRO;
+		features &= ~NETIF_F_LRO;
 
 	if (data & ETH_FLAG_NTUPLE) {
 		if (!ops->set_rx_ntuple)
 			return -EOPNOTSUPP;
-		dev->features |= NETIF_F_NTUPLE;
+		features |= NETIF_F_NTUPLE;
 	} else {
 		/* safe to clear regardless */
-		dev->features &= ~NETIF_F_NTUPLE;
+		features &= ~NETIF_F_NTUPLE;
 	}
 
+	dev->features = features;
 	return 0;
 }
 

^ permalink raw reply related

* Re: [net-next-2.6 PATCH] ethtool: Add n-tuple string length to drvinfo and return it
From: Jeff Garzik @ 2010-02-27  7:25 UTC (permalink / raw)
  To: Peter P Waskiewicz Jr, Kirsher, Jeffrey T
  Cc: davem@davemloft.net, netdev@vger.kernel.org, gospo@redhat.com,
	Ben Hutchings
In-Reply-To: <4B88BC2C.1030304@garzik.org>

On 02/27/2010 01:31 AM, Jeff Garzik wrote:
> On 02/26/2010 06:49 PM, Peter P Waskiewicz Jr wrote:
>> On Fri, 2010-02-26 at 05:56 -0800, Jeff Garzik wrote:
>>> On 02/26/2010 06:54 AM, Jeff Kirsher wrote:
>>>> From: Peter Waskiewicz<peter.p.waskiewicz.jr@intel.com>
>>>>
>>>> The drvinfo struct should include the number of strings that
>>>> get_rx_ntuple will return. It will be variable if an underlying
>>>> driver implements its own get_rx_ntuple routine, so userspace
>>>> needs to know how much data is coming.
>>>>
>>>> Signed-off-by: Peter P Waskiewicz Jr<peter.p.waskiewicz.jr@intel.com>
>>>> Signed-off-by: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
>>>> ---
>>>>
>>>> include/linux/ethtool.h | 1 +
>>>> net/core/ethtool.c | 3 +++
>>>> 2 files changed, 4 insertions(+), 0 deletions(-)
>>>
>>> (resending reply, standard patch-sending box is having trouble sending
>>> to vger)
>>>
>>>
>>> As noted in the other email, your patch breaks ABI. The proper path is
>>> to decrease the size of reserved struct member, and NOT shift the offset
>>> of other members.
>>>
>>>
>>>
>>> However, perhaps consider the following patch for returning n-tuple
>>> count, for four reasons:
>>>
>>> 1) space in ethtool_drvinfo is limited
>>>
>>> 2) the patch below permits trivial string set addition, without
>>> ABI changes beyond adding a new ETH_SS_xxx constant.
>>>
>>> 3) the patch below permits direct access to ops->get_sset_count(),
>>> rather than implicit access via ethtool_drvinfo
>>>
>>> 4) ethtool_drvinfo interface does not permit indication of
>>> ops->get_sset_count() failure, versus returning zero value. The
>>> patch below does so, via output sset_mask.
>>>
>>> WARNING: this patch is compile-tested only.
>>>
>>> NOTE: I added a cosmetic fix to ETHTOOL_[GS]RXNTUPLE constants, making
>>> their indentation consistent with the rest of the list of constants.
>>>
>>> Signed-off-by: Jeff Garzik<jgarzik@redhat.com>
>>
>> I'm updating your patch since I found an issue. The mask is passing in
>> the ETH_SS_* flags, but then they're treated as bits, not enumerated
>> flags. I'm thinking of the best non-intrusive way to correct it.
>
> As Ben noted, you cannot change those enumerated values, as they are
> already part of the ABI.
>
> For ETHTOOL_GSSET_INFO, you initialize the sset_mask like this:
>
> info.sset_mask = (1ULL << ETH_SS_NTUPLE_FILTERS);
>
> A multiple initialization would look like this:
>
> info.sset_mask = (1ULL << ETH_SS_NTUPLE_FILTERS) |
> (1ULL << ETH_SS_STATS) |
> (1ULL << ETH_SS_PRIV_FLAGS);

Additionally, upon ioctl(2) completion, info.sset_mask will contain 
(1<<ETH_SS_NTUPLE_FILTERS) if and only if the kernel 
ops->get_sset_count() function call returned successfully.

Thus, the absence of that bit in info.sset_mask indicates the driver 
returned failure.

This condition needs to be checked in your userspace ethtool patch.

	Jeff



^ permalink raw reply

* [RFC PATCH net-next 7/7 v2]IPv6:netfilter: Add IPSTATS_MIB_REASMFAILS MIB counter value when evicting fragment queue
From: Shan Wei @ 2010-02-27  6:40 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

This patch adds MIB counter value about IPSTATS_MIB_REASMFAILS
if mem member of netns_frags exceeds high thresh, just like IPv4/v6 stack.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index fc97a68..501aca7 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -200,9 +200,13 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
 	inet_frag_kill(&fq->q, &nf_frags);
 }
 
-static void nf_ct_frag6_evictor(struct net *net)
+static void nf_ct_frag6_evictor(struct net *net, struct inet6_dev *idev)
 {
-	inet_frag_evictor(&net->ipv6.frags, &nf_frags);
+	int evicted;
+
+	evicted = inet_frag_evictor(&net->ipv6.frags, &nf_frags);
+	if (evicted)
+		IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
 }
 
 static void nf_ct_frag6_expire(unsigned long data)
@@ -712,7 +716,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 	fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
 	if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
-		nf_ct_frag6_evictor(net);
+		nf_ct_frag6_evictor(net, idev);
 
 	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
 	if (fq == NULL) {
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 6/7 v2]IPv6:netfilter: Record MIB counter after a fragment reached
From: Shan Wei @ 2010-02-27  6:40 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

This patch records MIB counter about fragments reassembly after a fragment reached.

Note: 
For the lack of memory, if fails to clone skb, pull skb or create fragment queue,
then not to forward skb to IPv6 stack, and drop it, just like IPv4.

v1->v2:
1. Conntrack can track a single fragment with MF=0,offset=0 now.
   (applied patch with title [nf_conntrack_reasm: properly handle packets fragmented into a single fragment])
   So delete the changes when seeing a single fragment with MF=0,offset=0.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 4640795..fc97a68 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -680,27 +680,31 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 	u8 prevhdr;
 	struct sk_buff *ret_skb = NULL;
 	struct net *net = dev ? dev_net(dev) : dev_net(skb_dst(skb)->dev);
+	struct inet6_dev *idev;
 
+	idev = dev ? in6_dev_get(dev) : ip6_dst_idev(skb_dst(skb));
 	/* Jumbo payload inhibits frag. header */
 	if (ipv6_hdr(skb)->payload_len == 0) {
 		pr_debug("payload len = 0\n");
-		return skb;
+		goto out_nofrag;
 	}
 
 	if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
-		return skb;
+		goto out_nofrag;
+
+	IP6_INC_STATS(net, idev, IPSTATS_MIB_REASMREQDS);
 
 	clone = skb_clone(skb, GFP_ATOMIC);
 	if (clone == NULL) {
 		pr_debug("Can't clone skb\n");
-		return skb;
+		goto out_drop_skb;
 	}
 
 	NFCT_FRAG6_CB(clone)->orig = skb;
 
 	if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
 		pr_debug("message is too short.\n");
-		goto ret_orig;
+		goto out_drop_skb;
 	}
 
 	skb_set_transport_header(clone, fhoff);
@@ -713,7 +717,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
 	if (fq == NULL) {
 		pr_debug("Can't find and can't create new queue\n");
-		goto ret_orig;
+		goto out_drop_skb;
 	}
 
 	spin_lock(&fq->q.lock);
@@ -732,13 +736,24 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 			pr_debug("Can't reassemble fragmented packets\n");
 	}
 	spin_unlock(&fq->q.lock);
+	if (dev && idev)
+		in6_dev_put(idev);
 
 	fq_put(fq);
 	return ret_skb;
 
 ret_orig:
 	kfree_skb(clone);
+out_nofrag:
+	if (dev && idev)
+		in6_dev_put(idev);
 	return skb;
+out_drop_skb:
+	IP6_INC_STATS(net, idev, IPSTATS_MIB_REASMFAILS);
+	kfree_skb(clone);
+	kfree_skb(skb);
+	skb = NULL;
+	goto out_nofrag;
 }
 
 void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 5/7 v2]IPv6:netfilter: Record MIB counter when reassembling all fragments
From: Shan Wei @ 2010-02-27  6:40 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

According to RFC4293, this patch records MIB counter of IPSTATS_MIB_REASMFAILS, 
IPSTATS_MIB_REASMOKS, when reassembling fragments after all fragments reached.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 27d8ac1..4640795 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -485,6 +485,7 @@ static struct sk_buff *
 nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 {
 	struct sk_buff *fp, *op, *head = fq->q.fragments;
+	struct net *net = container_of(fq->q.net, struct net, ipv6.frags);
 	int    payload_len;
 
 	fq_kill(fq);
@@ -586,6 +587,9 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 		NFCT_FRAG6_CB(fp)->orig = NULL;
 	}
 
+	rcu_read_lock();
+	IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
+	rcu_read_unlock();
 	return head;
 
 out_oversize:
@@ -596,6 +600,9 @@ out_oom:
 	if (net_ratelimit())
 		printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n");
 out_fail:
+	rcu_read_lock();
+	IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
+	rcu_read_unlock();
 	return NULL;
 }
 
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 4/7]IPv6:netfilter: Send an ICMPv6 "Fragment Reassembly Timeout" message when enabling connection track
From: Shan Wei @ 2010-02-27  6:40 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

An end host with IPv6 connection track enable should send an 
ICMP "Fragment Reassembly Timeout" message when defraging timeout
according to the section 4.5 in RFC2460.

This patch supports it and adds counter value of Ip6ReasmTimeout and Ip6ReasmFails.


Quote Begin:
 Section 4.5 in RFC2460.
   If insufficient fragments are received to complete reassembly of a
   packet within 60 seconds of the reception of the first-arriving
   fragment of that packet, reassembly of that packet must be
   abandoned and all the fragments that have been received for that
   packet must be discarded.  If the first fragment (i.e., the one
   with a Fragment Offset of zero) has been received, an ICMP Time
   Exceeded -- Fragment Reassembly Time Exceeded message should be
   sent to the source of that fragment.
Quote End.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 include/linux/skbuff.h                  |    5 +++
 net/ipv6/netfilter/nf_conntrack_reasm.c |   48 ++++++++++++++++++++++++++++++-
 net/ipv6/route.c                        |    1 +
 3 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ba0f8e3..e0b72e4 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -431,6 +431,11 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
 	return (struct rtable *)skb_dst(skb);
 }
 
+static inline struct rt6_info *skb_r6table(const struct sk_buff *skb)
+{
+	return (struct rt6_info *)skb_dst(skb);
+}
+
 extern void kfree_skb(struct sk_buff *skb);
 extern void consume_skb(struct sk_buff *skb);
 extern void	       __kfree_skb(struct sk_buff *skb);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 8f68373..27d8ac1 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -27,10 +27,12 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/random.h>
+#include <linux/ipv6_route.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
 #include <net/inet_frag.h>
+#include <net/ip6_route.h>
 
 #include <net/ipv6.h>
 #include <net/protocol.h>
@@ -64,6 +66,7 @@ struct nf_ct_frag6_queue
 	struct in6_addr		saddr;
 	struct in6_addr		daddr;
 
+	int			iif;
 	unsigned int		csum;
 	__u16			nhoffset;
 };
@@ -205,6 +208,8 @@ static void nf_ct_frag6_evictor(struct net *net)
 static void nf_ct_frag6_expire(unsigned long data)
 {
 	struct nf_ct_frag6_queue *fq;
+	struct net_device *dev = NULL;
+	struct net *net;
 
 	fq = container_of((struct inet_frag_queue *)data,
 			struct nf_ct_frag6_queue, q);
@@ -215,7 +220,44 @@ static void nf_ct_frag6_expire(unsigned long data)
 		goto out;
 
 	fq_kill(fq);
+	net = container_of(fq->q.net, struct net, ipv6.frags);
+	rcu_read_lock();
+	dev = dev_get_by_index_rcu(net, fq->iif);
+	if (!dev)
+		goto out_rcu_unlock;
+
+	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
+	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
+
+	/* Don't send error if the first segment did not arrive. */
+	if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments)
+		goto out_rcu_unlock;
+
+	/*
+	 * Only search router table for the head fragment,
+	 * when defraging timeout at PRE_ROUTING HOOK.
+	 */
+	if (fq->user == IP6_DEFRAG_CONNTRACK_IN) {
+		struct sk_buff *head = fq->q.fragments;
+
+		head->dev = dev;
+		ip6_route_input(head);
+		if (!skb_dst(head))
+			goto out_rcu_unlock;
+
+		/*
+		 * Only an end host needs to send an ICMP "Fragment Reassembly
+		 * Timeout" message, per section 4.5 of RFC2460.
+		 */
+		if (!(skb_r6table(head)->rt6i_flags & RTF_LOCAL))
+			goto out_rcu_unlock;
 
+		/* Send an ICMP "Fragment Reassembly Timeout" message. */
+		icmpv6_send(head, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0);
+	}
+
+out_rcu_unlock:
+	rcu_read_unlock();
 out:
 	spin_unlock(&fq->q.lock);
 	fq_put(fq);
@@ -405,7 +447,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 	else
 		fq->q.fragments = skb;
 
-	skb->dev = NULL;
+	if (skb->dev) {
+		fq->iif = skb->dev->ifindex;
+		skb->dev = NULL;
+	}
+
 	fq->q.stamp = skb->tstamp;
 	fq->q.meat += skb->len;
 	atomic_add(skb->truesize, &fq->q.net->mem);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 88c0a5c..ef4bdd9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -802,6 +802,7 @@ void ip6_route_input(struct sk_buff *skb)
 
 	skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input));
 }
+EXPORT_SYMBOL(ip6_route_input);
 
 static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
 					     struct flowi *fl, int flags)
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 3/7 v2]IPv6:netfilter: defrag: Disable button half when reassembling a fragment
From: Shan Wei @ 2010-02-27  6:39 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

After doing introduction of network name spaces to conntrack,
disable button half when reassembling a fragment.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    3 +++
 net/ipv6/netfilter/nf_conntrack_reasm.c        |   11 ++++-------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 03a6b8d..f153b2c 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -221,7 +221,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
 	if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
 		return NF_ACCEPT;
 
+	local_bh_disable();
 	reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
+	local_bh_enable();
+
 	/* queued */
 	if (reasm == NULL)
 		return NF_STOLEN;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 99ec35d..8f68373 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -199,9 +199,7 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
 
 static void nf_ct_frag6_evictor(struct net *net)
 {
-	local_bh_disable();
 	inet_frag_evictor(&net->ipv6.frags, &nf_frags);
-	local_bh_enable();
 }
 
 static void nf_ct_frag6_expire(unsigned long data)
@@ -238,11 +236,10 @@ fq_find(struct net *net, __be32 id, u32 user, struct in6_addr *src,
 	arg.src = src;
 	arg.dst = dst;
 
-	read_lock_bh(&nf_frags.lock);
+	read_lock(&nf_frags.lock);
 	hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
 
 	q = inet_frag_find(&net->ipv6.frags, &nf_frags, &arg, hash);
-	local_bh_enable();
 	if (q == NULL)
 		goto oom;
 
@@ -666,10 +663,10 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 		goto ret_orig;
 	}
 
-	spin_lock_bh(&fq->q.lock);
+	spin_lock(&fq->q.lock);
 
 	if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
-		spin_unlock_bh(&fq->q.lock);
+		spin_unlock(&fq->q.lock);
 		pr_debug("Can't insert skb to queue\n");
 		fq_put(fq);
 		goto ret_orig;
@@ -681,7 +678,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 		if (ret_skb == NULL)
 			pr_debug("Can't reassemble fragmented packets\n");
 	}
-	spin_unlock_bh(&fq->q.lock);
+	spin_unlock(&fq->q.lock);
 
 	fq_put(fq);
 	return ret_skb;
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 2/7 v2]IPv6:netfilter: defrag: Introduce per-netns to conntrack and kill nf_init_frags
From: Shan Wei @ 2010-02-27  6:39 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

Introduce network name spaces to conntrack and share netns_frags with IPv6 stack.  
So kill private member of nf_init_frags in nf_conntrack_reasm.c.

v1-v2:
1. Separate sysctls handles from this patch to patch-1.
2. Separate locking changes from this patch to patch-3.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 net/ipv6/netfilter/nf_conntrack_reasm.c |   41 +++++++++++++-----------------
 1 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 1095676..99ec35d 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -69,7 +69,6 @@ struct nf_ct_frag6_queue
 };
 
 static struct inet_frags nf_frags;
-static struct netns_frags nf_init_frags;
 
 #ifdef CONFIG_SYSCTL
 struct ctl_table nf_ct_ipv6_sysctl_table[] = {
@@ -173,11 +172,12 @@ static void nf_skb_free(struct sk_buff *skb)
 }
 
 /* Memory Tracking Functions. */
-static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
+static inline void
+frag_kfree_skb(struct netns_frags *nf, struct sk_buff *skb, unsigned int *work)
 {
 	if (work)
 		*work -= skb->truesize;
-	atomic_sub(skb->truesize, &nf_init_frags.mem);
+	atomic_sub(skb->truesize, &nf->mem);
 	nf_skb_free(skb);
 	kfree_skb(skb);
 }
@@ -197,10 +197,10 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
 	inet_frag_kill(&fq->q, &nf_frags);
 }
 
-static void nf_ct_frag6_evictor(void)
+static void nf_ct_frag6_evictor(struct net *net)
 {
 	local_bh_disable();
-	inet_frag_evictor(&nf_init_frags, &nf_frags);
+	inet_frag_evictor(&net->ipv6.frags, &nf_frags);
 	local_bh_enable();
 }
 
@@ -226,7 +226,8 @@ out:
 /* Creation primitives. */
 
 static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
+fq_find(struct net *net, __be32 id, u32 user, struct in6_addr *src,
+	struct in6_addr *dst)
 {
 	struct inet_frag_queue *q;
 	struct ip6_create_arg arg;
@@ -240,7 +241,7 @@ fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
 	read_lock_bh(&nf_frags.lock);
 	hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
 
-	q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
+	q = inet_frag_find(&net->ipv6.frags, &nf_frags, &arg, hash);
 	local_bh_enable();
 	if (q == NULL)
 		goto oom;
@@ -394,7 +395,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 				fq->q.fragments = next;
 
 			fq->q.meat -= free_it->len;
-			frag_kfree_skb(free_it, NULL);
+			frag_kfree_skb(fq->q.net, free_it, NULL);
 		}
 	}
 
@@ -410,7 +411,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 	skb->dev = NULL;
 	fq->q.stamp = skb->tstamp;
 	fq->q.meat += skb->len;
-	atomic_add(skb->truesize, &nf_init_frags.mem);
+	atomic_add(skb->truesize, &fq->q.net->mem);
 
 	/* The first fragment.
 	 * nhoffset is obtained from the first fragment, of course.
@@ -420,7 +421,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 		fq->q.last_in |= INET_FRAG_FIRST_IN;
 	}
 	write_lock(&nf_frags.lock);
-	list_move_tail(&fq->q.lru_list, &nf_init_frags.lru_list);
+	list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
 	write_unlock(&nf_frags.lock);
 	return 0;
 
@@ -487,7 +488,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 		clone->ip_summed = head->ip_summed;
 
 		NFCT_FRAG6_CB(clone)->orig = NULL;
-		atomic_add(clone->truesize, &nf_init_frags.mem);
+		atomic_add(clone->truesize, &fq->q.net->mem);
 	}
 
 	/* We have to remove fragment header from datagram and to relocate
@@ -501,7 +502,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 	skb_shinfo(head)->frag_list = head->next;
 	skb_reset_transport_header(head);
 	skb_push(head, head->data - skb_network_header(head));
-	atomic_sub(head->truesize, &nf_init_frags.mem);
+	atomic_sub(head->truesize, &fq->q.net->mem);
 
 	for (fp=head->next; fp; fp = fp->next) {
 		head->data_len += fp->len;
@@ -511,7 +512,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 		else if (head->ip_summed == CHECKSUM_COMPLETE)
 			head->csum = csum_add(head->csum, fp->csum);
 		head->truesize += fp->truesize;
-		atomic_sub(fp->truesize, &nf_init_frags.mem);
+		atomic_sub(fp->truesize, &fq->q.net->mem);
 	}
 
 	head->next = NULL;
@@ -628,6 +629,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 	int fhoff, nhoff;
 	u8 prevhdr;
 	struct sk_buff *ret_skb = NULL;
+	struct net *net = dev ? dev_net(dev) : dev_net(skb_dst(skb)->dev);
 
 	/* Jumbo payload inhibits frag. header */
 	if (ipv6_hdr(skb)->payload_len == 0) {
@@ -655,10 +657,10 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 	hdr = ipv6_hdr(clone);
 	fhdr = (struct frag_hdr *)skb_transport_header(clone);
 
-	if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
-		nf_ct_frag6_evictor();
+	if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
+		nf_ct_frag6_evictor(net);
 
-	fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
+	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
 	if (fq == NULL) {
 		pr_debug("Can't find and can't create new queue\n");
 		goto ret_orig;
@@ -731,10 +733,6 @@ int nf_ct_frag6_init(void)
 	nf_frags.match = ip6_frag_match;
 	nf_frags.frag_expire = nf_ct_frag6_expire;
 	nf_frags.secret_interval = 10 * 60 * HZ;
-	nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
-	nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
-	nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
-	inet_frags_init_net(&nf_init_frags);
 	inet_frags_init(&nf_frags);
 
 	return 0;
@@ -743,8 +741,5 @@ int nf_ct_frag6_init(void)
 void nf_ct_frag6_cleanup(void)
 {
 	inet_frags_fini(&nf_frags);
-
-	nf_init_frags.low_thresh = 0;
-	nf_ct_frag6_evictor();
 	unregister_pernet_subsys(&ip6_nf_frags_ops);
 }
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 1/7 v2]IPv6:netfilter: defrag: Handle sysctls about IPv6 conntrack defragment per-netns
From: Shan Wei @ 2010-02-27  6:39 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI,
	"netdev@vger.kernel.o

Register nf_conntrack_frag6_{timeout,high_thresh,low_thresh} sysctls per-netns.
nf_conntrack_frag6_timeout and ip6frag_time, nf_conntrack_frag6_low_thresh and ip6frag_low_thresh,
nf_conntrack_frag6_high_thresh and ip6frag_high_thresh, the three sets are equivalent.
The former sysctls are just an alias for he latter ones of IPv6.

More discussion about it, see http://marc.info/?l=netfilter-devel&m=126709777922959&w=2.


Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
---
 Documentation/feature-removal-schedule.txt     |   19 +++++
 include/net/netns/ipv6.h                       |    1 +
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    4 -
 net/ipv6/netfilter/nf_conntrack_reasm.c        |   85 ++++++++++++++++++++++--
 4 files changed, 99 insertions(+), 10 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 721a2aa..127b6d6 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -531,3 +531,22 @@ Why:	udev fully replaces this special file system that only contains CAPI
 	NCCI TTY device nodes. User space (pppdcapiplugin) works without
 	noticing the difference.
 Who:	Jan Kiszka <jan.kiszka@web.de>
+
+---------------------------
+
+What:	- /proc/sys/net/netfilter/nf_conntrack_frag6_timeout
+	- /proc/sys/net/netfilter/nf_conntrack_frag6_high_thresh
+	- /proc/sys/net/netfilter/nf_conntrack_frag6_low_thresh
+When:	February 2011
+
+Why:	IPv6 conntrack defragment has introduced network name space, and shares
+	per-netns_frags with IPv6 stack. ip6frag_low_thresh, ip6frag_time and
+	ip6frag_high_thresh manage queue numbers and memory thresh size of
+	both IPv6 conntrack fragment queue and IPv6 stack fragment queue.
+	So nf_conntrack_frag6_timeout and ip6frag_time have the same effect,
+	nf_conntrack_frag6_low_thresh and ip6frag_low_thresh also have the same
+	effect, nf_conntrack_frag6_high_thresh and ip6frag_high_thresh too.
+	These there sysctls of IPv6 conntrack will be removed in the future,
+	please use those of IPv6.
+
+Who:	Shan Wei <shanwei@cn.fujitsu.com>
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 1f11ebc..e8fac24 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -14,6 +14,7 @@ struct netns_sysctl_ipv6 {
 #ifdef CONFIG_SYSCTL
 	struct ctl_table_header *table;
 	struct ctl_table_header *frags_hdr;
+	struct ctl_table_header *nf_ct_frags_hdr;
 #endif
 	int bindv6only;
 	int flush_delay;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 996c3f4..03a6b8d 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -387,10 +387,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
 	.nlattr_to_tuple	= ipv6_nlattr_to_tuple,
 	.nla_policy		= ipv6_nla_policy,
 #endif
-#ifdef CONFIG_SYSCTL
-	.ctl_table_path		= nf_net_netfilter_sysctl_path,
-	.ctl_table		= nf_ct_ipv6_sysctl_table,
-#endif
 	.me			= THIS_MODULE,
 };
 
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f1171b7..6af4497 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -75,27 +75,88 @@ static struct netns_frags nf_init_frags;
 struct ctl_table nf_ct_ipv6_sysctl_table[] = {
 	{
 		.procname	= "nf_conntrack_frag6_timeout",
-		.data		= &nf_init_frags.timeout,
-		.maxlen		= sizeof(unsigned int),
+		.data		= &init_net.ipv6.frags.timeout,
+		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
 		.procname	= "nf_conntrack_frag6_low_thresh",
-		.data		= &nf_init_frags.low_thresh,
-		.maxlen		= sizeof(unsigned int),
+		.data		= &init_net.ipv6.frags.low_thresh,
+		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
 	{
 		.procname	= "nf_conntrack_frag6_high_thresh",
-		.data		= &nf_init_frags.high_thresh,
-		.maxlen		= sizeof(unsigned int),
+		.data		= &init_net.ipv6.frags.high_thresh,
+		.maxlen		= sizeof(int),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
 	{ }
 };
+
+static const char SYSCTLS_WARN_INFO[] = "nf_conntrack_frag6_timeout and \
+ip6frag_time, nf_conntrack_frag6_low_thresh and ip6frag_low_thresh, \
+nf_conntrack_frag6_high_thresh and ip6frag_high_thresh, \
+the three sets are equivalent. nf_conntrack_frag6_timeout is just an alias \
+for ip6frag_time. The former parameters of IPv6 conntrack will be removed \
+in February 2011, please use the latter ones of IPv6.";
+
+static int nf_frags_init_net(struct net *net)
+{
+	struct ctl_table *table;
+	struct ctl_table_header *hdr;
+
+	table = nf_ct_ipv6_sysctl_table;
+	if (!net_eq(net, &init_net)) {
+		table = kmemdup(table, sizeof(nf_ct_ipv6_sysctl_table),
+				GFP_KERNEL);
+		if (table == NULL)
+			goto err_alloc;
+
+		table[0].data = &net->ipv6.frags.high_thresh;
+		table[1].data = &net->ipv6.frags.low_thresh;
+		table[2].data = &net->ipv6.frags.timeout;
+	}
+
+	hdr = register_net_sysctl_table(net, nf_net_netfilter_sysctl_path,
+					table);
+	if (hdr == NULL)
+		goto err_reg;
+
+	printk(KERN_WARNING "Netfilter:%s\n", SYSCTLS_WARN_INFO);
+
+	net->ipv6.sysctl.nf_ct_frags_hdr = hdr;
+	return 0;
+
+err_reg:
+	if (!net_eq(net, &init_net))
+		kfree(table);
+err_alloc:
+	return -ENOMEM;
+}
+
+static void nf_frags_exit_net(struct net *net)
+{
+	struct ctl_table *table;
+
+	table = net->ipv6.sysctl.nf_ct_frags_hdr->ctl_table_arg;
+	unregister_net_sysctl_table(net->ipv6.sysctl.nf_ct_frags_hdr);
+	if (!net_eq(net, &init_net))
+		kfree(table);
+}
+
+#else
+static int nf_frags_init_net(struct net *net)
+{
+	return 0;
+}
+
+static void nf_frags_exit_net(struct net *net)
+{
+}
 #endif
 
 static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -650,8 +711,19 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
 	nf_conntrack_put_reasm(skb);
 }
 
+static struct pernet_operations ip6_nf_frags_ops = {
+	.init = nf_frags_init_net,
+	.exit = nf_frags_exit_net,
+};
+
 int nf_ct_frag6_init(void)
 {
+	int ret;
+
+	ret = register_pernet_subsys(&ip6_nf_frags_ops);
+	if (ret)
+		return ret;
+
 	nf_frags.hashfn = nf_hashfn;
 	nf_frags.constructor = ip6_frag_init;
 	nf_frags.destructor = NULL;
@@ -675,4 +747,5 @@ void nf_ct_frag6_cleanup(void)
 
 	nf_init_frags.low_thresh = 0;
 	nf_ct_frag6_evictor();
+	unregister_pernet_subsys(&ip6_nf_frags_ops);
 }
-- 
1.6.3.3

^ permalink raw reply related

* [RFC PATCH net-next 0/7 v2]IPv6:netfilter: defragment
From: Shan Wei @ 2010-02-27  6:39 UTC (permalink / raw)
  To: Patrick McHardy, David Miller, Alexey Dobriyan, Yasuyuki KOZAKAI
  Cc: netdev@vger.kernel.org, netfilter-devel

 This patch-set solves the problem that an end host with IPv6 connection track enable
can't send an ICMP "Fragment Reassembly Timeout" message when defaging timeout.
And supports MIB counter about fragments reassembly e.g. Ip6ReasmTimeout, Ip6ReasmReqds,
Ip6ReasmOKs, Ip6ReasmFails.

patch-1,2,3: Introduce net namespace to conntrack and share netns_frags with IPv6 stack.  
          But, IPv6 conntrack and IPv6 stack still keep separate fragment queue.
          Like IPv4, proc parameters of ip6frag_low_thresh, ip6frag_time and ip6frag_high_thresh
          manage numbers and memory thresh size of both IPv6 conntrack fragment queue and 
          IPv6 stack fragment queue.

patch-4: Send an ICMP "Fragment Reassembly Timeout" message and record MIB counter 
         when defraging timeout.

patch-5,6,7: According to RFC4293, record MIB counter about fragments reassembly.


This patch-set has been tested using IPv6 Ready Logo Phase-2 tool under host and router type.

---
Shan Wei <shanwei@cn.fujitsu.com> (7):
      IPv6:netfilter: defrag: Handle sysctls about IPv6 conntrack defragment per-netns
      IPv6:netfilter: defrag: Introduce per-netns to conntrack and kill nf_init_frags
      IPv6:netfilter: defrag: Disable button half when reassembling a fragment 
      IPv6:netfilter: Send an ICMPv6 "Fragment Reassembly Timeout" message when enabling connection track
      IPv6:netfilter: Record MIB counter when reassembling all fragments
      IPv6:netfilter: Record MIB counter after a fragment reached
      IPv6:netfilter: Add IPSTATS_MIB_REASMFAILS MIB counter value when evicting fragment queue

 Documentation/feature-removal-schedule.txt     |   19 ++
 include/linux/skbuff.h                         |    5 +
 include/net/netns/ipv6.h                       |    1 +
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    7 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c        |  221 +++++++++++++++++++-----
 net/ipv6/route.c                               |    1 +
 6 files changed, 208 insertions(+), 46 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [net-next-2.6 PATCH] ethtool: Add n-tuple string length to drvinfo and return it
From: Jeff Garzik @ 2010-02-27  6:31 UTC (permalink / raw)
  To: Peter P Waskiewicz Jr, Kirsher, Jeffrey T
  Cc: davem@davemloft.net, netdev@vger.kernel.org, gospo@redhat.com,
	Ben Hutchings
In-Reply-To: <1267228162.2224.38.camel@localhost>

On 02/26/2010 06:49 PM, Peter P Waskiewicz Jr wrote:
> On Fri, 2010-02-26 at 05:56 -0800, Jeff Garzik wrote:
>> On 02/26/2010 06:54 AM, Jeff Kirsher wrote:
>>> From: Peter Waskiewicz<peter.p.waskiewicz.jr@intel.com>
>>>
>>> The drvinfo struct should include the number of strings that
>>> get_rx_ntuple will return.  It will be variable if an underlying
>>> driver implements its own get_rx_ntuple routine, so userspace
>>> needs to know how much data is coming.
>>>
>>> Signed-off-by: Peter P Waskiewicz Jr<peter.p.waskiewicz.jr@intel.com>
>>> Signed-off-by: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
>>> ---
>>>
>>>    include/linux/ethtool.h |    1 +
>>>    net/core/ethtool.c      |    3 +++
>>>    2 files changed, 4 insertions(+), 0 deletions(-)
>>
>> (resending reply, standard patch-sending box is having trouble sending
>> to vger)
>>
>>
>> As noted in the other email, your patch breaks ABI.  The proper path is
>> to decrease the size of reserved struct member, and NOT shift the offset
>> of other members.
>>
>>
>>
>> However, perhaps consider the following patch for returning n-tuple
>> count, for four reasons:
>>
>> 1) space in ethtool_drvinfo is limited
>>
>> 2) the patch below permits trivial string set addition, without
>>      ABI changes beyond adding a new ETH_SS_xxx constant.
>>
>> 3) the patch below permits direct access to ops->get_sset_count(),
>>      rather than implicit access via ethtool_drvinfo
>>
>> 4) ethtool_drvinfo interface does not permit indication of
>>      ops->get_sset_count() failure, versus returning zero value.  The
>>      patch below does so, via output sset_mask.
>>
>> WARNING: this patch is compile-tested only.
>>
>> NOTE: I added a cosmetic fix to ETHTOOL_[GS]RXNTUPLE constants, making
>> their indentation consistent with the rest of the list of constants.
>>
>> Signed-off-by: Jeff Garzik<jgarzik@redhat.com>
>
> I'm updating your patch since I found an issue.  The mask is passing in
> the ETH_SS_* flags, but then they're treated as bits, not enumerated
> flags.  I'm thinking of the best non-intrusive way to correct it.

As Ben noted, you cannot change those enumerated values, as they are 
already part of the ABI.

For ETHTOOL_GSSET_INFO, you initialize the sset_mask like this:

	info.sset_mask = (1ULL << ETH_SS_NTUPLE_FILTERS);

A multiple initialization would look like this:

	info.sset_mask = (1ULL << ETH_SS_NTUPLE_FILTERS) |
			(1ULL << ETH_SS_STATS) |
			(1ULL << ETH_SS_PRIV_FLAGS);

Do you still see an issue in my suggested code, now that sset_mask 
confusion is cleared up?

Regards,

	Jeff




^ permalink raw reply

* [patch] zd1211rw: fix potential array underflow
From: Dan Carpenter @ 2010-02-27  6:12 UTC (permalink / raw)
  To: Daniel Drake
  Cc: Ulrich Kunitz, John W. Linville, Johannes Berg, Luis R. Rodriguez,
	André Goddard Rosa, Benoit PAPILLAULT, linux-wireless,
	netdev, linux-kernel, kernel-janitors

The first chunk fixes a debugging assert to print a warning about array underflows.
The second chunk corrects a potential array underflow.  I also removed an assert
in the second chunk because it can no longer happen.

Signed-off-by: Dan Carpenter <error27@gmail.com>
---
This was found by a static check and compile tested only.  Please review carefully.

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index f14deb0..ead2f2c 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -350,7 +350,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
 	first_idx = info->status.rates[0].idx;
 	ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
 	retries = &zd_retry_rates[first_idx];
-	ZD_ASSERT(0<=retry && retry<=retries->count);
+	ZD_ASSERT(1 <= retry && retry <= retries->count);
 
 	info->status.rates[0].idx = retries->rate[0];
 	info->status.rates[0].count = 1; // (retry > 1 ? 2 : 1);
@@ -360,7 +360,7 @@ static void zd_mac_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
 		info->status.rates[i].count = 1; // ((i==retry-1) && success ? 1:2);
 	}
 	for (; i<IEEE80211_TX_MAX_RATES && i<retry; i++) {
-		info->status.rates[i].idx = retries->rate[retry-1];
+		info->status.rates[i].idx = retries->rate[retry - 1];
 		info->status.rates[i].count = 1; // (success ? 1:2);
 	}
 	if (i<IEEE80211_TX_MAX_RATES)
@@ -424,12 +424,10 @@ void zd_mac_tx_failed(struct urb *urb)
 		first_idx = info->status.rates[0].idx;
 		ZD_ASSERT(0<=first_idx && first_idx<ARRAY_SIZE(zd_retry_rates));
 		retries = &zd_retry_rates[first_idx];
-		if (retry < 0 || retry > retries->count) {
+		if (retry <= 0 || retry > retries->count)
 			continue;
-		}
 
-		ZD_ASSERT(0<=retry && retry<=retries->count);
-		final_idx = retries->rate[retry-1];
+		final_idx = retries->rate[retry - 1];
 		final_rate = zd_rates[final_idx].hw_value;
 
 		if (final_rate != tx_status->rate) {

^ permalink raw reply related

* Re: [net-next-2.6 PATCH] infiniband: convert to use netdev_for_each_mc_addr
From: Jason Gunthorpe @ 2010-02-27  6:01 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Or Gerlitz, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20100225084915.GA3171-YzwxZg+R7et1/kRsl7OVgNvLeJWuRmrY@public.gmane.org>

On Thu, Feb 25, 2010 at 09:49:15AM +0100, Jiri Pirko wrote:
> Thu, Feb 25, 2010 at 09:00:07AM CET, ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org wrote:
> >Jiri Pirko wrote:
> >> +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> >> @@ -767,11 +767,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
> >> -static int ipoib_mcast_addr_is_valid(const u8 *addr, unsigned int addrlen,
> >> -				     const u8 *broadcast)
> >> +static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
> >>  {
> >> -	if (addrlen != INFINIBAND_ALEN)
> >> -		return 0;
> >
> >This check was added by commit 5e47596b "IPoIB: Check multicast address format", may I ask what is the reason for removing it now?
> 
> Yes, at this very moment the check is not needless but it will be in a brief
> future. dev_mc_add will look very similar like dev_unicast_add. But ok. Here's
> patch adding the check in dev_mc_add right now to correct this state. Thanks Or.

Is this enough?

The problem this statement is trying to solve had to do with bonding
creating multicast addresess for ethernet rather than infiniband in
some cases. This happens because bonding makes a device that switches
from ethernet to infiniband during its lifetime. I'm not quite
sure what kind of life cycle those addresses go through, but if they
somehow stay on the mc_list then ipoib_mcast_addr_is_valid will still
need to have the check.

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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


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