Netdev List
 help / color / mirror / Atom feed
* LIBIPQ: problem with Injecting encapsulated packet  (plz somebody )     reply)]
From: Vasantha Kumar Puttappa @ 2006-06-10 16:03 UTC (permalink / raw)
  To: netdev

Hi,
 I am posting this query again. plz somebody reply. Also I am new to
IPtables and LIBIPQ

 I am working on a application that involves encapsulatting the packets .
Suppose there are 3 machines A B C. Assume that machine A is sending some
some information to machine B. All I do is to capture packets(using
libipq) destined for machine B  on machine A and send it to machine C . I
encapuslate this captured packet in a new packet with(adding both IP/UDP
header, although UDP header is not really required, with destinatin
address as machine C IP).

The issue is that after the call to set_verdict function, instead of the
encapsulated packet, original packet is getting transmitted. I tried my
best to find the solution with no success. I am updating the checksum
correctly after adding new header.

Below is snippet of my code

**************

unsigned char *new_packet = NULL;
struct iphdr *new_iphdr;
struct iphdr *original_iphdr = (struct iphdr *)(m->payload);
int status;


new_packet = (unsigned char *) calloc(1,sizeof(struct iphdr) +
(m->data_len) + sizeof(struct udphdr));
new_iphdr = (struct iphdr *) calloc(1,sizeof(struct iphdr));




    /* extra Udp header */

    struct udphdr *new_udp;

    new_udp = (struct udphdr *) calloc(1,sizeof(struct udphdr));
    new_udp->source = htons(50000);
    new_udp->dest = htons(50000);
    new_udp->len =  original_iphdr->tot_len;
    new_udp->check = 0;

    /* udp*/


     /** New IP header **/
     new_iphdr->version = original_iphdr->version;
     new_iphdr->ihl = original_iphdr->ihl;
     new_iphdr->tos = original_iphdr->tos;
     new_iphdr->id  = original_iphdr->id;;
     new_iphdr->frag_off = original_iphdr->frag_off;
     new_iphdr->ttl = original_iphdr->ttl;
     new_iphdr->protocol = original_iphdr->protocol;
     new_iphdr->saddr= inet_addr("10.107.26.27");//original_iphdr->saddr;
     new_iphdr->daddr=inet_addr("10.12.25.7");//daddr.s_addr;

     new_iphdr->tot_len=htons(ntohs(original_iphdr->tot_len)+
(sizeof(struct iphdr))+ sizeof(struct udphdr));


     new_iphdr->check=0;
     new_iphdr->check=(((ip_sum_calc((unsigned short
*)new_iphdr,sizeof(struct iphdr)))));


     // Place the IP packet inside another IP packet
     memcpy(new_packet,new_iphdr,(unsigned int)sizeof(struct iphdr));

     memcpy(new_packet+sizeof(struct iphdr),new_udp,(unsigned
int)sizeof(struct udphdr));

     memcpy(new_packet+sizeof(struct iphdr)+sizeof(struct
udphdr),m->payload,m->data_len);



     size_t length = ntohs(new_iphdr->tot_len);;

     status =
ipq_set_verdict(handle,m->packet_id,NF_ACCEPT,length,(unsigned char
*) new_packet);


     if(status < 0)
       {
	 printf("\n Packet Modification failed \n");
	 die();
       }


     printf("\n  Packet Transmitted Successfull \n");



*********checksum function**********
unsigned short ip_sum_calc(unsigned short *addr,int len)
{

  int nleft = len;
  int sum = 0;
  unsigned short *w = addr;
  unsigned short answer = 0;

  printf(" \nsize %d", sizeof(sum));

  while (nleft > 1)
    {
      sum += *w++;
      nleft -= 2;
    }


  if (nleft == 1)
    {
      *(unsigned char *)(&answer) = *(unsigned char *) w;
      sum += answer;
    }
  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  answer = ~sum;


    return answer;

}












^ permalink raw reply

* Wrong IPv4 source address selected
From: Meelis Roos @ 2006-06-10 13:30 UTC (permalink / raw)
  To: netdev

This is 2.6.17-rc6 running on a 32-bit ppc (the same ARC=ppc PReP 
machine that had the x_tables problem, so it has the x_tables 
alignment first fix too).

The problem: IPv4 source addresses are sometimes selected wrong (packets 
are sent to the internal 172.30 network with external 193.40 source 
address). I have seen this with ARP requests for 172.30.0.x addresses 
and UDP multicast traffic (avahi query from 193.40.37.61:5353 to 
224.0.0.251:5353 on eth1).

I have 2 physical network interfaces (+ loopback + unconfiured sit0)

2: eth0: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 08:00:3e:28:c4:a2 brd ff:ff:ff:ff:ff:ff
     inet 193.40.37.61/23 brd 193.40.37.255 scope global eth0
     inet6 2001:bb8:2002:2400:a00:3eff:fe28:c4a2/64 scope global dynamic
        valid_lft 2591964sec preferred_lft 604764sec
     inet6 fe80::a00:3eff:fe28:c4a2/64 scope link
        valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:00:94:7a:31:8c brd ff:ff:ff:ff:ff:ff
     inet 172.30.0.1/24 brd 172.30.0.255 scope global eth1
     inet6 fe80::200:94ff:fe7a:318c/64 scope link
        valid_lft forever preferred_lft forever

ip route ls:
172.30.0.0/24 dev eth1  proto kernel  scope link  src 172.30.0.1 
193.40.36.0/23 dev eth0  proto kernel  scope link  src 193.40.37.61 
default via 193.40.36.1 dev eth0

-- 
Meelis Roos (mroos@linux.ee)

^ permalink raw reply

* Re: netif_tx_disable vs netif_stop_queue (possible races?)
From: Evgeniy Polyakov @ 2006-06-10 12:59 UTC (permalink / raw)
  To: Daniel Drake; +Cc: Herbert Xu, netdev, david-b
In-Reply-To: <448ABE2D.8040401@gentoo.org>

On Sat, Jun 10, 2006 at 01:42:21PM +0100, Daniel Drake (dsd@gentoo.org) wrote:
> Herbert Xu wrote:
> >Correct.  All callers of hard_start_xmit do so under RCU or equivalent
> >locks so they must be complete by the time synchronize_net() returns.
> 
> Does this hold for other operations? Such as:
> 
> - The netdev->set_mac_address function
> - The wireless ioctl's (SIOCSIWESSID, etc)
> 
> Are these also guaranteed to have returned after synchronize_net()?

None of above calls is protected with RCU (except set_mac_address()
called through ioctl, which is performed under read_lock which disables
preemtption), so they still can run after synchronize_net().

But if you are talking about synchronize_net() inside
unregister_netdevice(), which is called from 
usbnet_disconnect()->unregister_netdev(), than it is safe.

> Thanks,
> Daniel

-- 
	Evgeniy Polyakov

^ permalink raw reply

* Re: netif_tx_disable vs netif_stop_queue (possible races?)
From: Daniel Drake @ 2006-06-10 12:42 UTC (permalink / raw)
  To: Herbert Xu; +Cc: netdev, david-b
In-Reply-To: <20060609233531.GA15756@gondor.apana.org.au>

Herbert Xu wrote:
> Correct.  All callers of hard_start_xmit do so under RCU or equivalent
> locks so they must be complete by the time synchronize_net() returns.

Does this hold for other operations? Such as:

- The netdev->set_mac_address function
- The wireless ioctl's (SIOCSIWESSID, etc)

Are these also guaranteed to have returned after synchronize_net()?

Thanks,
Daniel

^ permalink raw reply

* Re: [linux-usb-devel] [PATCH RFC] ZyDAS ZD1211 USB-WLAN driver
From: Daniel Drake @ 2006-06-10 12:40 UTC (permalink / raw)
  To: Oliver Neukum, Daniel Drake, linux-usb-devel, John W. Linville,
	netdev
In-Reply-To: <20060610112306.GA19198@p15091797.pureserver.info>

Ulrich Kunitz wrote:
> Not so fast, because I don't know what to fix.

I am working on it. A couple more mails to Herbert Xu should clarify it, 
then I'll post a patch. On first glance I was quite worried that there 
are a lot of potential races, but now I think there will only be a few 
places.

Daniel

^ permalink raw reply

* [2.6.17-rc6] Section mismatch in drivers/net/ne.o during modpost
From: Mikael Pettersson @ 2006-06-10 12:11 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev

While compiling 2.6.17-rc6 for a 486 with an NE2000 ISA ethernet card, I got:

  Building modules, stage 2.
make -rR -f /tmp/linux-2.6.17-rc6/scripts/Makefile.modpost
  scripts/mod/modpost   -o /tmp/linux-2.6.17-rc6/Module.symvers   vmlinux drivers/net/8390.o drivers/net/ne.o lib/crc32.o net/packet/af_packet.o
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x158) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x176) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x183) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x1ea) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.data:isapnp_clone_list from .text between 'init_module' (at offset 0x251) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.text: from .text between 'init_module' (at offset 0x266) and 'ne_block_input'
WARNING: drivers/net/ne.o - Section mismatch: reference to .init.text: from .text between 'init_module' (at offset 0x29b) and 'ne_block_input'

Not sure how serious this is; the driver seems to work fine later on.

/Mikael

^ permalink raw reply

* Re: [RFT] Realtek 8168 ethernet support
From: Francois Romieu @ 2006-06-10 12:05 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Randy.Dunlap, Daniel Drake, netdev
In-Reply-To: <4489C290.6020705@garzik.org>

Jeff Garzik <jeff@garzik.org> :
> Francois Romieu wrote:
> >Jeff Garzik <jeff@garzik.org> :
> >>Randy.Dunlap wrote:
> >>>Conversely, any reason to use the RealTek r1000 driver?
> >>FWIW, RealTek emailed me about merging r1000.  I suggested that, if the 
> >
> >Which one ?
> >
> >r1000_n.c where #define RELEASE_DATE "2006/02/23"
> 
> They didn't say.  Just "r1000"

Can you ask your Realtek person if he is really sure about the following
snippet in r1000_n.c::r1000_init_one:

		if((priv->mcfg!=MCFG_METHOD_13)&&(priv->mcfg!=MCFG_METHOD_14)&&(priv->mcfg!=MCFG_METHOD_15))
			printk("This Realtek NIC doesn't support 1000Mbps\n");
		else
			Cap1000 = PHY_Cap_1000_Full|PHY_Cap_1000_Half;

-> in forced 1000 mode, 1000_{Half/Full} would only be written to the
   advertisement register for MCFG_METHOD_1{3/4/5}. It excludes all
   the adapters that the in-kernel driver support (huh ?).

Later in the same function:
[...]
	if(( priv->mcfg == MCFG_METHOD_11 )||( priv->mcfg == MCFG_METHOD_12 ))
		printk("Realtek RTL8168/8111 Family PCI-E Gigabit Ethernet Network Adapter\n");
	else if((priv->mcfg==MCFG_METHOD_13)||(priv->mcfg==MCFG_METHOD_14)||(priv->mcfg==MCFG_METHOD_15))
		printk("Realtek RTL8139/810x Family Fast Ethernet Network Adapter\n");

-> the != ... && ... != test above seems inverted.

Btw, it would be nice if he could confirm that the 0x10ec/0x8129 ID
sent by Yoichi Yuasa is really allowed (and not a random bitflip).

-- 
Ueimor

^ permalink raw reply

* [PATCH] bnx2: endian fixes
From: Alexey Dobriyan @ 2006-06-10 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Michael Chan

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

 drivers/net/bnx2.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1820,7 +1820,7 @@ reuse_rx:
 		skb->protocol = eth_type_trans(skb, bp->dev);
 
 		if ((len > (bp->dev->mtu + ETH_HLEN)) &&
-			(htons(skb->protocol) != 0x8100)) {
+			(ntohs(skb->protocol) != 0x8100)) {
 
 			dev_kfree_skb_irq(skb);
 			goto next_rx;
@@ -4310,7 +4310,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
 		ip_tcp_len = (skb->nh.iph->ihl << 2) + sizeof(struct tcphdr);
 
 		skb->nh.iph->check = 0;
-		skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
+		skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
 		skb->h.th->check =
 			~csum_tcpudp_magic(skb->nh.iph->saddr,
 					    skb->nh.iph->daddr,


^ permalink raw reply

* Re: [PATCH RFC] ZyDAS ZD1211 USB-WLAN driver
From: Oliver Neukum @ 2006-06-10 11:49 UTC (permalink / raw)
  To: Ulrich Kunitz; +Cc: Daniel Drake, netdev, linux-usb-devel, John W. Linville
In-Reply-To: <20060610112306.GA19198@p15091797.pureserver.info>

Am Samstag, 10. Juni 2006 13:23 schrieb Ulrich Kunitz:
> On 06-06-04 00:25 Oliver Neukum wrote:
> 
> > > > +static void disconnect(struct usb_interface *intf)
> > > > This is racy. It allows io to disconnected devices. You must take the
> > > > lock and set a flag that you test after you've taken the lock elsewhere.
> > > 
> > > Will fix, thanks.
> > 
> > You're welcome
> 
> Not so fast, because I don't know what to fix.
> 
> Actually there are two cases, when disconnect is called. The first

There are three cases. It can also be triggered by sysfs and usbfs.

> is, when the device is removed. The second is, when the kernel
> module is removed from the kernel. It should also be recognized
> that disconnect() must always succeed, so we have to ignore IO
> errors anyhow.

You can ignore IO errors in disconnect(). They are harmless.

> In the first case we don't need the IO and in the second case we
> have to do it, because otherwise, the device will not come up, if
> we load the driver again.
> 
> Testing shows, that doing the IO doesn't create a lot of issues,
> there are some errors reported, but that's it and the second case
> just works fine. So there doesn't appear a problem and even if
> want to be "clean", I would like to know, how to distinguish both
> cases without trying to do IO with the device.

The problem is not that you may do IO _during_ disconnect. You may
do IO _after_ disconnect, even if usbfs might already have claimed
the device. Disconnect() must either terminate ongoing IO or wait for
it to end. And it must make sure that there'll be no IO afterwards.

	Regards
		Oliver


_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

^ permalink raw reply

* Re: [linux-usb-devel] [PATCH RFC] ZyDAS ZD1211 USB-WLAN driver
From: Ulrich Kunitz @ 2006-06-10 11:23 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: Daniel Drake, linux-usb-devel, John W. Linville, netdev
In-Reply-To: <200606040025.32275.oliver@neukum.org>

On 06-06-04 00:25 Oliver Neukum wrote:

> > > +static void disconnect(struct usb_interface *intf)
> > > This is racy. It allows io to disconnected devices. You must take the
> > > lock and set a flag that you test after you've taken the lock elsewhere.
> > 
> > Will fix, thanks.
> 
> You're welcome

Not so fast, because I don't know what to fix.

Actually there are two cases, when disconnect is called. The first
is, when the device is removed. The second is, when the kernel
module is removed from the kernel. It should also be recognized
that disconnect() must always succeed, so we have to ignore IO
errors anyhow.

In the first case we don't need the IO and in the second case we
have to do it, because otherwise, the device will not come up, if
we load the driver again.

Testing shows, that doing the IO doesn't create a lot of issues,
there are some errors reported, but that's it and the second case
just works fine. So there doesn't appear a problem and even if
want to be "clean", I would like to know, how to distinguish both
cases without trying to do IO with the device.

In  the meanwhile I removed the misleading comment about locking.
I would like also like to know, that beside the fact that device
IO fails, which races can happen?

-- 
Uli Kunitz

^ permalink raw reply

* Re: [RFC] [patch 0/6] [Network namespace] introduction
From: Kari Hurtta @ 2006-06-10  7:16 UTC (permalink / raw)
  To: linux-kernel; +Cc: netdev
In-Reply-To: <20060609210202.215291000@localhost.localdomain>

dlezcano@fr.ibm.com writes in gmane.linux.network,gmane.linux.kernel:

> The following patches create a private "network namespace" for use
> within containers. This is intended for use with system containers
> like vserver, but might also be useful for restricting individual
> applications' access to the network stack.
> 
> These patches isolate traffic inside the network namespace. The
> network ressources, the incoming and the outgoing packets are
> identified to be related to a namespace. 
> 
> It hides network resource not contained in the current namespace, but
> still allows administration of the network with normal commands like
> ifconfig.
> 
> It applies to the kernel version 2.6.17-rc6-mm1
> 
> It provides the following:
> -------------------------
>    - when an application unshares its network namespace, it looses its
>      view of all network devices by default. The administrator can
>      choose to make any devices to become visible again. The container
>      then gains a view to the device but without the ip address
>      configured on it. It is up to the container administrator to use
>      ifconfig or ip command to setup a new ip address. This ip address
>      is only visible inside the container.

Do other namespaces work differently ?
When namespace is unshared, it has initially the same resources
(for example compare to CLONE_NEWNS)

 
>    - the loopback is isolated inside the container and it is not
>      possible to communicate between containers via the
>      loopback. 
> 
>    - several containers can have an application bind to the same
>      address:port without conflicting. 

That of course be problem, if initially unshared namespace shares
same resources.

/ Kari Hurtta

^ permalink raw reply

* Re: wireless (was Re: 2.6.18 -mm merge plans)
From: Pavel Machek @ 2006-06-10  6:58 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Alan Cox, Andreas Mohr, Andrew Morton, Jeff Garzik, linux-kernel,
	netdev, linville, Denis Vlasenko, acx100-devel, acx100-users
In-Reply-To: <1149503730.3111.46.camel@laptopd505.fenrus.org>

Hi!

> > >  It's just that a cleanroom approach is a sure way to prove
> > > you didn't copy. That's all.
> > 
> > Which is an extremely important detail especially if you have been
> > reverse engineering another driver for the same or similar OS where it
> > is likely that people will retain knowledge and copy rather than
> > re-implement th?ngs.
> 
> oh don't get me wrong, it's important to not copy from the original.
> (even if that original did copy from linux ;)

Well, if original did copy from linux, it surely is GPLed and case
closed, no? Being sued from vendor not respecting the GPL would
probably only do harm to them.

Like US courts are crazy, but hopefully not _that_ crazy.
							Pavel
-- 
Thanks for all the (sleeping) penguins.

^ permalink raw reply

* libiptc linking problem under AMD64
From: Tommy W @ 2006-06-10  2:07 UTC (permalink / raw)
  To: netdev

Hi,
I'm writing an application that uses libiptc and iptables for various 
monitoring applications.

http://www.freshmeat.net/projects/natstat

and I've come upon a small problem with libiptc on AMD64

It won't link into my program, because of lack of the flag -fPIC during 
compile time.

I edited the Makefile for libiptc and put -fPIC in there, voila, everything 
worked.
So my questions now are:

* is there a reason for not having -fPIC ?
* could you add -fPIC ?

Thanks in advance
/Tommy Wallberrg

^ permalink raw reply

* Re: [RFC] [patch 5/6] [Network namespace] ipv4 isolation
From: James Morris @ 2006-06-10  0:47 UTC (permalink / raw)
  To: Rick Jones; +Cc: dlezcano, linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <448A1208.3060602@hp.com>

On Fri, 9 Jun 2006, Rick Jones wrote:

> > I think you'll need to make it so this code has zero impact when not
> > configured.
> 
> Indeed, and over stuff other than loopback too.  I'll not so humbly suggest :)

Yes, I meant the whole lot.



- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply

* Re: [RFC] [patch 5/6] [Network namespace] ipv4 isolation
From: Rick Jones @ 2006-06-10  0:27 UTC (permalink / raw)
  To: James Morris; +Cc: dlezcano, linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <Pine.LNX.4.64.0606092022320.17380@d.namei>

James Morris wrote:
> On Fri, 9 Jun 2006, dlezcano@fr.ibm.com wrote:
> 
> 
>>When an outgoing packet has the loopback destination addres, the
>>skbuff is filled with the network namespace. So the loopback packets
>>never go outside the namespace. This approach facilitate the migration
>>of loopback because identification is done by network namespace and
>>not by address. The loopback has been benchmarked by tbench and the
>>overhead is roughly 1.5 %
> 
> 
> I think you'll need to make it so this code has zero impact when not 
> configured.

Indeed, and over stuff other than loopback too.  I'll not so humbly 
suggest :)  netperf TCP_STREAM and TCP_RR figures _with_ CPU 
utilization/service demand measures.

rick jones

^ permalink raw reply

* Re: [RFC] [patch 5/6] [Network namespace] ipv4 isolation
From: James Morris @ 2006-06-10  0:23 UTC (permalink / raw)
  To: dlezcano; +Cc: linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <20060609210631.346330000@localhost.localdomain>

On Fri, 9 Jun 2006, dlezcano@fr.ibm.com wrote:

> When an outgoing packet has the loopback destination addres, the
> skbuff is filled with the network namespace. So the loopback packets
> never go outside the namespace. This approach facilitate the migration
> of loopback because identification is done by network namespace and
> not by address. The loopback has been benchmarked by tbench and the
> overhead is roughly 1.5 %

I think you'll need to make it so this code has zero impact when not 
configured.


- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply

* Re: netif_tx_disable vs netif_stop_queue (possible races?)
From: Herbert Xu @ 2006-06-09 23:35 UTC (permalink / raw)
  To: Daniel Drake; +Cc: netdev, david-b
In-Reply-To: <448993C9.8040400@gentoo.org>

On Fri, Jun 09, 2006 at 04:29:13PM +0100, Daniel Drake wrote:
> 
> Can I interpret your response as: If the TX queue is disabled in 
> advance, no hard_start_xmit functions will be running on any CPU after 
> synchronize_net() has returned?

Correct.  All callers of hard_start_xmit do so under RCU or equivalent
locks so they must be complete by the time synchronize_net() returns.

What you got watch out for though are paths where the driver might
reenable the queue.  That could be a real bug.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [4/3] [NET]: Warn in __skb_trim if skb is paged
From: David Miller @ 2006-06-09 23:13 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20060609075538.GA22828@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Jun 2006 17:55:39 +1000

> [NET]: Warn in __skb_trim if skb is paged
> 
> It's better to warn and fail rather than rarely triggering BUG on paths
> that incorrectly call skb_trim/__skb_trim on a non-linear skb.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Agreed, patch applied, thanks a lot Herbert.

^ permalink raw reply

* Re: [3/3] [NET]: skb_trim audit
From: David Miller @ 2006-06-09 23:13 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20060609074433.GB19524@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Jun 2006 17:44:33 +1000

> [NET]: skb_trim audit
> 
> I found a few more spots where pskb_trim_rcsum could be used but were not.
> This patch changes them to use it.
> 
> Also, sk_filter can get paged skb data.  Therefore we must use pskb_trim
> instead of skb_trim.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied, thanks.

^ permalink raw reply

* Re: [2/3] [NET] ppp: Remove unnecessary pskb_may_pull
From: David Miller @ 2006-06-09 23:12 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20060609074344.GA19524@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Jun 2006 17:43:44 +1000

> [NET] ppp: Remove unnecessary pskb_may_pull

Applied, thanks a lot.

^ permalink raw reply

* Re: [1/3] [NET]: Clean up skb_linearize
From: David Miller @ 2006-06-09 23:11 UTC (permalink / raw)
  To: herbert; +Cc: netdev
In-Reply-To: <20060609074234.GA17580@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 9 Jun 2006 17:42:34 +1000

> [NET]: Clean up skb_linearize

Looks good, applied to net-2.6.18

^ permalink raw reply

* Re: [patch] workaround zd1201 interference problem
From: Pavel Machek @ 2006-06-09 22:38 UTC (permalink / raw)
  To: Daniel Drake; +Cc: Jiri Benc, linville, kernel list, netdev
In-Reply-To: <4489ECD0.1030908@gentoo.org>

Hi!

I'll try to.

> >if you plug zd1201 into USB, it starts jamming radio,
> >immediately. Enable/disable, or iwlist wlan0 scan, or basically any
> >operation unjams the radio. This patch works it around:
> 
> Can we be any more specific?
> 
> What is the interference - is it transmitting random packets, or just 
> emitting a magical cloud of invisible anti-wifi?

Magical cloud, I'm afraid.

> At which precise point does the interference start? 

When the card is inserted.

> Does it happen even 
> without the driver loaded?

Will try.

> Which operation is the one which stops the interference, the enable or 
> the disable?

Disable alone was not enough to stop interference.

> Does this happen on every plug in, or just sometimes? 

In 70% or so.

> Is it affected by 
> usage patterns such as having the device plugged in throughout boot, 
> reloading the module, etc?

Will try.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [patch] workaround zd1201 interference problem
From: Daniel Drake @ 2006-06-09 21:49 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Jiri Benc, linville, kernel list, netdev
In-Reply-To: <20060608070525.GE3688@elf.ucw.cz>

Pavel Machek wrote:
> if you plug zd1201 into USB, it starts jamming radio,
> immediately. Enable/disable, or iwlist wlan0 scan, or basically any
> operation unjams the radio. This patch works it around:

Can we be any more specific?

What is the interference - is it transmitting random packets, or just 
emitting a magical cloud of invisible anti-wifi?

At which precise point does the interference start? Does it happen even 
without the driver loaded?

Which operation is the one which stops the interference, the enable or 
the disable?

Does this happen on every plug in, or just sometimes? Is it affected by 
usage patterns such as having the device plugged in throughout boot, 
reloading the module, etc?

Thanks,
Daniel


^ permalink raw reply

* [RFC] [patch 6/6] [Network namespace] Network namespace debugfs
From: dlezcano @ 2006-06-09 21:02 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: serue, haveblue, clg, dlezcano
In-Reply-To: <20060609210202.215291000@localhost.localdomain>

[-- Attachment #1: net_ns_debugfs.patch --]
[-- Type: text/plain, Size: 4800 bytes --]

This patch is for testing purpose. It allows to read which network
devices are accessible and to add a network device to the view.
This RFC hack is purely for discussing the best way to do that.

After unsharing with CLONE_NEWNET flag:
--------------------------------------
 To see which devices are accessible:
	 cat /sys/kernel/debug/net_ns/dev

 To add a device:
	 echo eth1 > /sys/kernel/debug/net_ns/dev

This functionnality is intended to be implemented in an higher level
container configuration.

Replace-Subject: [Network namespace] Network namespace debugfs
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> 
--
 fs/debugfs/Makefile |    2 
 fs/debugfs/net_ns.c |  141 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 net/Kconfig         |    4 +
 3 files changed, 146 insertions(+), 1 deletion(-)

Index: 2.6-mm/fs/debugfs/Makefile
===================================================================
--- 2.6-mm.orig/fs/debugfs/Makefile
+++ 2.6-mm/fs/debugfs/Makefile
@@ -1,4 +1,4 @@
 debugfs-objs	:= inode.o file.o
 
 obj-$(CONFIG_DEBUG_FS)	+= debugfs.o
-
+obj-$(CONFIG_NET_NS_DEBUG) += net_ns.o
Index: 2.6-mm/fs/debugfs/net_ns.c
===================================================================
--- /dev/null
+++ 2.6-mm/fs/debugfs/net_ns.c
@@ -0,0 +1,141 @@
+/*
+ *  net_ns.c - adds a net_ns/ directory to debug NET namespaces
+ *
+ *  Copyright (C) 2006 IBM
+ *
+ *  Author: Daniel Lezcano <dlezcano@fr.ibm.com>
+ *
+ *     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, version 2 of the
+ *     License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pagemap.h>
+#include <linux/debugfs.h>
+#include <linux/sched.h>
+#include <linux/netdevice.h>
+#include <linux/net_ns.h>
+
+static struct dentry *net_ns_dentry;
+static struct dentry *net_ns_dentry_dev;
+
+static ssize_t net_ns_dev_read_file(struct file *file, char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	size_t len;
+	char *buf;
+	struct net_ns_dev_list *devlist = &(net_ns()->dev_list);
+	struct net_ns_dev *db;
+	struct net_device *dev;
+	struct list_head *l;
+
+	if (*ppos < 0)
+		return -EINVAL;
+	if (*ppos >= count)
+		return 0;
+
+	/* It's for debug, everything should fit */
+	buf = kmalloc(4096, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	buf[0] = '\0';
+
+	read_lock(&devlist->lock);
+	list_for_each(l, &devlist->list) {
+		db = list_entry(l, struct net_ns_dev, list);
+		dev = db->dev;
+		strcat(buf,dev->name);
+		strcat(buf,"\n");
+	}
+	read_unlock(&devlist->lock);
+
+	len = strlen(buf);
+
+	if (len > count)
+		len = count;
+
+	if (copy_to_user(user_buf, buf, len)) {
+		kfree(buf);
+		return -EFAULT;
+	}
+
+	*ppos += count;
+	kfree(buf);
+
+	return count;
+}
+
+static ssize_t net_ns_dev_write_file(struct file *file,
+				     const char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	int ret;
+	size_t len;
+	const char __user *p;
+	char c;
+	char devname[IFNAMSIZ];
+	struct net_ns_dev_list *dev_list = &(net_ns()->dev_list);
+
+	len = 0;
+	p = user_buf;
+	while (len < count) {
+		if (get_user(c, p++))
+			return -EFAULT;
+		if (c == 0 || c == '\n')
+			break;
+		len++;
+	}
+
+	if (len >= IFNAMSIZ)
+		return -EINVAL;
+
+	if (copy_from_user(devname, user_buf, len))
+		return -EFAULT;
+
+	devname[len] = '\0';
+
+	ret = net_ns_dev_add(devname, dev_list);
+	if (ret)
+		return ret;
+
+	*ppos += count;
+	return count;
+}
+
+static int net_ns_dev_open_file(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static struct file_operations net_ns_dev_fops = {
+       .read =         net_ns_dev_read_file,
+       .write =        net_ns_dev_write_file,
+       .open =         net_ns_dev_open_file,
+};
+
+static int __init net_ns_init(void)
+{
+	net_ns_dentry = debugfs_create_dir("net_ns", NULL);
+
+	net_ns_dentry_dev = debugfs_create_file("dev", 0666,
+						net_ns_dentry,
+						NULL,
+						&net_ns_dev_fops);
+	return 0;
+}
+
+static void __exit net_ns_exit(void)
+{
+	debugfs_remove(net_ns_dentry_dev);
+	debugfs_remove(net_ns_dentry);
+}
+
+module_init(net_ns_init);
+module_exit(net_ns_exit);
+
+MODULE_DESCRIPTION("NET namespace debugfs");
+MODULE_AUTHOR("Daniel Lezcano <dlezcano@fr.ibm.com>");
+MODULE_LICENSE("GPL");
Index: 2.6-mm/net/Kconfig
===================================================================
--- 2.6-mm.orig/net/Kconfig
+++ 2.6-mm/net/Kconfig
@@ -69,6 +69,10 @@ config NET_NS
 	  vservers, to use network namespaces to provide isolated
 	  network for different servers.  If unsure, say N.
 
+config NET_NS_DEBUG
+	bool "Debug fs for network namespace"
+	depends on DEBUG_FS && NET_NS
+
 if INET
 source "net/ipv4/Kconfig"
 source "net/ipv6/Kconfig"

--

^ permalink raw reply

* [RFC] [patch 5/6] [Network namespace] ipv4 isolation
From: dlezcano @ 2006-06-09 21:02 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: serue, haveblue, clg, dlezcano
In-Reply-To: <20060609210202.215291000@localhost.localdomain>

[-- Attachment #1: inet_isolation.patch --]
[-- Type: text/plain, Size: 15639 bytes --]

This patch partially isolates ipv4 by adding the network namespace
structure in the structure sock, bind bucket and skbuf. When a socket
is created, the pointer to the network namespace is stored in the
struct sock and the socket belongs to the namespace by this way. That
allows to identify sockets related to a namespace for lookup and
procfs. 

The lookup is extended with a network namespace pointer, in
order to identify listen points binded to the same port. That allows
to have several applications binded to INADDR_ANY:port in different
network namespace without conflicting. The bind is checked against
port and network namespace.

When an outgoing packet has the loopback destination addres, the
skbuff is filled with the network namespace. So the loopback packets
never go outside the namespace. This approach facilitate the migration
of loopback because identification is done by network namespace and
not by address. The loopback has been benchmarked by tbench and the
overhead is roughly 1.5 %

Replace-Subject: [Network namespace] ipv4 isolation
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> 
--
 include/linux/skbuff.h           |    2 ++
 include/net/inet_hashtables.h    |   34 ++++++++++++++++++++++++----------
 include/net/inet_timewait_sock.h |    1 +
 include/net/sock.h               |    4 ++++
 net/dccp/ipv4.c                  |    7 ++++---
 net/ipv4/af_inet.c               |    2 ++
 net/ipv4/inet_connection_sock.c  |    3 ++-
 net/ipv4/inet_diag.c             |    3 ++-
 net/ipv4/inet_hashtables.c       |    6 +++++-
 net/ipv4/inet_timewait_sock.c    |    1 +
 net/ipv4/ip_output.c             |    4 ++++
 net/ipv4/tcp_ipv4.c              |   25 ++++++++++++++++---------
 net/ipv4/udp.c                   |    7 +++++--
 13 files changed, 72 insertions(+), 27 deletions(-)

Index: 2.6-mm/include/linux/skbuff.h
===================================================================
--- 2.6-mm.orig/include/linux/skbuff.h
+++ 2.6-mm/include/linux/skbuff.h
@@ -27,6 +27,7 @@
 #include <linux/poll.h>
 #include <linux/net.h>
 #include <linux/textsearch.h>
+#include <linux/net_ns.h>
 #include <net/checksum.h>
 #include <linux/dmaengine.h>
 
@@ -301,6 +302,7 @@
 				*data,
 				*tail,
 				*end;
+	struct net_namespace    *net_ns;
 };
 
 #ifdef __KERNEL__
Index: 2.6-mm/include/net/inet_hashtables.h
===================================================================
--- 2.6-mm.orig/include/net/inet_hashtables.h
+++ 2.6-mm/include/net/inet_hashtables.h
@@ -23,6 +23,8 @@
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/wait.h>
+#include <linux/in.h>
+#include <linux/net_ns.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_sock.h>
@@ -78,6 +80,7 @@
 	signed short		fastreuse;
 	struct hlist_node	node;
 	struct hlist_head	owners;
+	struct net_namespace    *net_ns;
 };
 
 #define inet_bind_bucket_for_each(tb, node, head) \
@@ -274,13 +277,15 @@
 extern struct sock *__inet_lookup_listener(const struct hlist_head *head,
 					   const u32 daddr,
 					   const unsigned short hnum,
-					   const int dif);
+					   const int dif,
+					   const struct net_namespace *net_ns);
 
 /* Optimize the common listener case. */
 static inline struct sock *
 		inet_lookup_listener(struct inet_hashinfo *hashinfo,
 				     const u32 daddr,
-				     const unsigned short hnum, const int dif)
+				     const unsigned short hnum, const int dif,
+				     const struct net_namespace *net_ns)
 {
 	struct sock *sk = NULL;
 	const struct hlist_head *head;
@@ -294,8 +299,9 @@
 		    (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
 		    (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
 		    !sk->sk_bound_dev_if)
-			goto sherry_cache;
-		sk = __inet_lookup_listener(head, daddr, hnum, dif);
+			if (sk->sk_net_ns == net_ns && LOOPBACK(daddr))
+				goto sherry_cache;
+		sk = __inet_lookup_listener(head, daddr, hnum, dif, net_ns);
 	}
 	if (sk) {
 sherry_cache:
@@ -358,7 +364,8 @@
 	__inet_lookup_established(struct inet_hashinfo *hashinfo,
 				  const u32 saddr, const u16 sport,
 				  const u32 daddr, const u16 hnum,
-				  const int dif)
+				  const int dif,
+				  const struct net_namespace *net_ns)
 {
 	INET_ADDR_COOKIE(acookie, saddr, daddr)
 	const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
@@ -373,12 +380,16 @@
 	prefetch(head->chain.first);
 	read_lock(&head->lock);
 	sk_for_each(sk, node, &head->chain) {
+		if (sk->sk_net_ns != net_ns && LOOPBACK(daddr))
+			continue;
 		if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
 			goto hit; /* You sunk my battleship! */
 	}
 
 	/* Must check for a TIME_WAIT'er before going to listener hash. */
 	sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
+		if (sk->sk_net_ns != net_ns && LOOPBACK(daddr))
+			continue;
 		if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
 			goto hit;
 	}
@@ -394,22 +405,25 @@
 static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
 					 const u32 saddr, const u16 sport,
 					 const u32 daddr, const u16 hnum,
-					 const int dif)
+					 const int dif,
+					 const struct net_namespace *net_ns)
 {
 	struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
-						    hnum, dif);
-	return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif);
+						    hnum, dif, net_ns);
+	return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif, net_ns);
 }
 
 static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
 				       const u32 saddr, const u16 sport,
 				       const u32 daddr, const u16 dport,
-				       const int dif)
+				       const int dif,
+				       const struct net_namespace *net_ns)
 {
 	struct sock *sk;
 
 	local_bh_disable();
-	sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
+	sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport),
+			   dif, net_ns);
 	local_bh_enable();
 
 	return sk;
Index: 2.6-mm/include/net/inet_timewait_sock.h
===================================================================
--- 2.6-mm.orig/include/net/inet_timewait_sock.h
+++ 2.6-mm/include/net/inet_timewait_sock.h
@@ -115,6 +115,7 @@
 #define tw_refcnt		__tw_common.skc_refcnt
 #define tw_hash			__tw_common.skc_hash
 #define tw_prot			__tw_common.skc_prot
+#define tw_net_ns               __tw_common.skc_net_ns
 	volatile unsigned char	tw_substate;
 	/* 3 bits hole, try to pack */
 	unsigned char		tw_rcv_wscale;
Index: 2.6-mm/include/net/sock.h
===================================================================
--- 2.6-mm.orig/include/net/sock.h
+++ 2.6-mm/include/net/sock.h
@@ -47,6 +47,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>	/* struct sk_buff */
 #include <linux/security.h>
+#include <linux/net_ns.h>
 
 #include <linux/filter.h>
 
@@ -94,6 +95,7 @@
  *	@skc_refcnt: reference count
  *	@skc_hash: hash value used with various protocol lookup tables
  *	@skc_prot: protocol handlers inside a network family
+ *      @skc_net_ns: network namespace owning the socket
  *
  *	This is the minimal network layer representation of sockets, the header
  *	for struct sock and struct inet_timewait_sock.
@@ -108,6 +110,7 @@
 	atomic_t		skc_refcnt;
 	unsigned int		skc_hash;
 	struct proto		*skc_prot;
+	struct net_namespace    *skc_net_ns;
 };
 
 /**
@@ -183,6 +186,7 @@
 #define sk_refcnt		__sk_common.skc_refcnt
 #define sk_hash			__sk_common.skc_hash
 #define sk_prot			__sk_common.skc_prot
+#define sk_net_ns               __sk_common.skc_net_ns
 	unsigned char		sk_shutdown : 2,
 				sk_no_check : 2,
 				sk_userlocks : 4;
Index: 2.6-mm/net/dccp/ipv4.c
===================================================================
--- 2.6-mm.orig/net/dccp/ipv4.c
+++ 2.6-mm/net/dccp/ipv4.c
@@ -308,7 +308,8 @@
 	}
 
 	sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
-			 iph->saddr, dh->dccph_sport, inet_iif(skb));
+			 iph->saddr, dh->dccph_sport, inet_iif(skb),
+			 skb->net_ns);
 	if (sk == NULL) {
 		ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
 		return;
@@ -610,7 +611,7 @@
 	nsk = __inet_lookup_established(&dccp_hashinfo,
 					iph->saddr, dh->dccph_sport,
 					iph->daddr, ntohs(dh->dccph_dport),
-					inet_iif(skb));
+					inet_iif(skb), skb->net_ns);
 	if (nsk != NULL) {
 		if (nsk->sk_state != DCCP_TIME_WAIT) {
 			bh_lock_sock(nsk);
@@ -924,7 +925,7 @@
 	sk = __inet_lookup(&dccp_hashinfo,
 			   skb->nh.iph->saddr, dh->dccph_sport,
 			   skb->nh.iph->daddr, ntohs(dh->dccph_dport),
-			   inet_iif(skb));
+			   inet_iif(skb), skb->net_ns);
 
 	/* 
 	 * Step 2:
Index: 2.6-mm/net/ipv4/af_inet.c
===================================================================
--- 2.6-mm.orig/net/ipv4/af_inet.c
+++ 2.6-mm/net/ipv4/af_inet.c
@@ -325,6 +325,7 @@
 	sk->sk_family	   = PF_INET;
 	sk->sk_protocol	   = protocol;
 	sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+	sk->sk_net_ns      = net_ns();
 
 	inet->uc_ttl	= -1;
 	inet->mc_loop	= 1;
@@ -616,6 +617,7 @@
 
 	sock_graft(sk2, newsock);
 
+	sk2->sk_net_ns = net_ns();
 	newsock->state = SS_CONNECTED;
 	err = 0;
 	release_sock(sk2);
Index: 2.6-mm/net/ipv4/inet_connection_sock.c
===================================================================
--- 2.6-mm.orig/net/ipv4/inet_connection_sock.c
+++ 2.6-mm/net/ipv4/inet_connection_sock.c
@@ -116,7 +116,7 @@
 		head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)];
 		spin_lock(&head->lock);
 		inet_bind_bucket_for_each(tb, node, &head->chain)
-			if (tb->port == snum)
+			if (tb->port == snum && tb->net_ns == net_ns())
 				goto tb_found;
 	}
 	tb = NULL;
@@ -146,6 +146,7 @@
 	} else if (tb->fastreuse &&
 		   (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
 		tb->fastreuse = 0;
+	tb->net_ns = net_ns();
 success:
 	if (!inet_csk(sk)->icsk_bind_hash)
 		inet_bind_hash(sk, tb, snum);
Index: 2.6-mm/net/ipv4/inet_diag.c
===================================================================
--- 2.6-mm.orig/net/ipv4/inet_diag.c
+++ 2.6-mm/net/ipv4/inet_diag.c
@@ -241,7 +241,8 @@
 	if (req->idiag_family == AF_INET) {
 		sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
 				 req->id.idiag_dport, req->id.idiag_src[0],
-				 req->id.idiag_sport, req->id.idiag_if);
+				 req->id.idiag_sport, req->id.idiag_if,
+				 in_skb->net_ns);
 	}
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 	else if (req->idiag_family == AF_INET6) {
Index: 2.6-mm/net/ipv4/inet_hashtables.c
===================================================================
--- 2.6-mm.orig/net/ipv4/inet_hashtables.c
+++ 2.6-mm/net/ipv4/inet_hashtables.c
@@ -126,7 +126,8 @@
  * wildcarded during the search since they can never be otherwise.
  */
 struct sock *__inet_lookup_listener(const struct hlist_head *head, const u32 daddr,
-				    const unsigned short hnum, const int dif)
+				    const unsigned short hnum, const int dif,
+				    const struct net_namespace *net_ns)
 {
 	struct sock *result = NULL, *sk;
 	const struct hlist_node *node;
@@ -139,6 +140,9 @@
 			const __u32 rcv_saddr = inet->rcv_saddr;
 			int score = sk->sk_family == PF_INET ? 1 : 0;
 
+			if (sk->sk_net_ns != net_ns && LOOPBACK(daddr))
+				continue;
+
 			if (rcv_saddr) {
 				if (rcv_saddr != daddr)
 					continue;
Index: 2.6-mm/net/ipv4/inet_timewait_sock.c
===================================================================
--- 2.6-mm.orig/net/ipv4/inet_timewait_sock.c
+++ 2.6-mm/net/ipv4/inet_timewait_sock.c
@@ -110,6 +110,7 @@
 		tw->tw_hash	    = sk->sk_hash;
 		tw->tw_ipv6only	    = 0;
 		tw->tw_prot	    = sk->sk_prot_creator;
+		tw->tw_net_ns       = sk->sk_net_ns;
 		atomic_set(&tw->tw_refcnt, 1);
 		inet_twsk_dead_node_init(tw);
 		__module_get(tw->tw_prot->owner);
Index: 2.6-mm/net/ipv4/ip_output.c
===================================================================
--- 2.6-mm.orig/net/ipv4/ip_output.c
+++ 2.6-mm/net/ipv4/ip_output.c
@@ -284,6 +284,10 @@
 
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);
+	if ((skb->nh.iph->protocol == IPPROTO_TCP ||
+	     skb->nh.iph->protocol == IPPROTO_UDP) &&
+	    LOOPBACK(skb->nh.iph->daddr))
+			skb->net_ns = skb->sk->sk_net_ns;
 
 	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
 		            ip_finish_output,
Index: 2.6-mm/net/ipv4/tcp_ipv4.c
===================================================================
--- 2.6-mm.orig/net/ipv4/tcp_ipv4.c
+++ 2.6-mm/net/ipv4/tcp_ipv4.c
@@ -349,7 +349,7 @@
 	}
 
 	sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
-			 th->source, inet_iif(skb));
+			 th->source, inet_iif(skb), skb->net_ns);
 	if (!sk) {
 		ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
 		return;
@@ -933,7 +933,8 @@
 
 	nsk = __inet_lookup_established(&tcp_hashinfo, skb->nh.iph->saddr,
 					th->source, skb->nh.iph->daddr,
-					ntohs(th->dest), inet_iif(skb));
+					ntohs(th->dest), inet_iif(skb),
+					skb->net_ns);
 
 	if (nsk) {
 		if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1071,7 +1072,7 @@
 
 	sk = __inet_lookup(&tcp_hashinfo, skb->nh.iph->saddr, th->source,
 			   skb->nh.iph->daddr, ntohs(th->dest),
-			   inet_iif(skb));
+			   inet_iif(skb), skb->net_ns);
 
 	if (!sk)
 		goto no_tcp_socket;
@@ -1149,7 +1150,8 @@
 		struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
 							skb->nh.iph->daddr,
 							ntohs(th->dest),
-							inet_iif(skb));
+							inet_iif(skb),
+							skb->net_ns);
 		if (sk2) {
 			inet_twsk_deschedule((struct inet_timewait_sock *)sk,
 					     &tcp_death_row);
@@ -1395,7 +1397,8 @@
 	}
 get_sk:
 	sk_for_each_from(sk, node) {
-		if (sk->sk_family == st->family) {
+		if (sk->sk_family == st->family &&
+		    sk->sk_net_ns == net_ns()) {
 			cur = sk;
 			goto out;
 		}
@@ -1446,7 +1449,8 @@
 
 		read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
 		sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
-			if (sk->sk_family != st->family) {
+			if (sk->sk_family != st->family ||
+			    sk->sk_net_ns != net_ns()) {
 				continue;
 			}
 			rc = sk;
@@ -1455,7 +1459,8 @@
 		st->state = TCP_SEQ_STATE_TIME_WAIT;
 		inet_twsk_for_each(tw, node,
 				   &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) {
-			if (tw->tw_family != st->family) {
+			if (tw->tw_family != st->family ||
+			    tw->tw_net_ns != net_ns()) {
 				continue;
 			}
 			rc = tw;
@@ -1481,7 +1486,8 @@
 		tw = cur;
 		tw = tw_next(tw);
 get_tw:
-		while (tw && tw->tw_family != st->family) {
+		while (tw && (tw->tw_family != st->family ||
+			      tw->tw_net_ns != net_ns())) {
 			tw = tw_next(tw);
 		}
 		if (tw) {
@@ -1505,7 +1511,8 @@
 		sk = sk_next(sk);
 
 	sk_for_each_from(sk, node) {
-		if (sk->sk_family == st->family)
+		if (sk->sk_family == st->family &&
+		    sk->sk_net_ns == net_ns())
 			goto found;
 	}
 
Index: 2.6-mm/net/ipv4/udp.c
===================================================================
--- 2.6-mm.orig/net/ipv4/udp.c
+++ 2.6-mm/net/ipv4/udp.c
@@ -184,6 +184,7 @@
 			    (!inet2->rcv_saddr ||
 			     !inet->rcv_saddr ||
 			     inet2->rcv_saddr == inet->rcv_saddr) &&
+			    sk2->sk_net_ns == sk->sk_net_ns &&
 			    (!sk2->sk_reuse || !sk->sk_reuse))
 				goto fail;
 		}
@@ -1404,7 +1405,8 @@
 	for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
 		struct hlist_node *node;
 		sk_for_each(sk, node, &udp_hash[state->bucket]) {
-			if (sk->sk_family == state->family)
+			if (sk->sk_family == state->family &&
+			    sk->sk_net_ns == net_ns())
 				goto found;
 		}
 	}
@@ -1421,7 +1423,8 @@
 		sk = sk_next(sk);
 try_again:
 		;
-	} while (sk && sk->sk_family != state->family);
+	} while (sk && (sk->sk_family != state->family ||
+			sk->sk_net_ns != net_ns()));
 
 	if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
 		sk = sk_head(&udp_hash[state->bucket]);

--

^ 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