* Re: [PATCH 6/6][NETNS]: Udp sockets per-net lookup.
From: David Miller @ 2008-01-31 13:20 UTC (permalink / raw)
To: yoshfuji; +Cc: xemul, netdev, devel
In-Reply-To: <20080201.001138.95019632.yoshfuji@wide.ad.jp>
From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@wide.ad.jp>
Date: Fri, 01 Feb 2008 00:11:38 +1100 (EST)
> In article <47A1C216.9000303@openvz.org> (at Thu, 31 Jan 2008 15:41:58 +0300), Pavel Emelyanov <xemul@openvz.org> says:
>
> > Add the net parameter to udp_get_port family of calls and
> > udp_lookup one and use it to filter sockets.
>
> I may miss something, but I'm afraid that I have to disagree.
> Port is identified only by family, address, protocol and port,
> and should not be split by name space.
It is like being on a totally different system.
Without sockets in namespaces, there is no point.
The networking devices are even per-namespace already,
so you can even say that each namespace is even
physically different.
^ permalink raw reply
* Re: [PATCH 2/6][INET]: Consolidate inet(6)_hash_connect.
From: Pavel Emelyanov @ 2008-01-31 13:18 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <20080131130153.GP1819@ghostprotocols.net>
Arnaldo Carvalho de Melo wrote:
> Em Thu, Jan 31, 2008 at 03:32:09PM +0300, Pavel Emelyanov escreveu:
>> These two functions are the same except for what they call
>> to "check_established" and "hash" for a socket.
>>
>> This saves half-a-kilo for ipv4 and ipv6.
>
> Good stuff!
>
> Yesterday I was perusing tcp_hash and I think we could have the hashinfo
> pointer stored perhaps in sk->sk_prot.
>
> That way we would be able to kill tcp_hash(), inet_put_port() could
> receive just sk, etc.
But each proto will still have its own hashfn, so proto's
callbacks will be called to hash/unhash sockets, so this will
give us just one extra dereference. No?
> What do you think?
Hmmm... Even raw_hash, etc may become simpler. On the other hand
maybe this is a good idea, but I'm not very common with this code
yet to foresee such things in advance... I think that we should
try to prepare a patch and look, but if you have smth ready, then
it's better to review your stuff first.
> - Arnaldo
>
Thanks,
Pavel
^ permalink raw reply
* Re: Null pointer dereference when bringing up bonding device on kernel-2.6.24-2.fc9.i686
From: Siim Põder @ 2008-01-31 12:51 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: netdev
In-Reply-To: <7908.1201551451@death>
Yo!
Jay Vosburgh wrote:
> Benny Amorsen <benny+usenet@amorsen.dk> wrote:
>
>> https://bugzilla.redhat.com/show_bug.cgi?id=430391
>
> I know what this is, I'll fix it.
do you know when this happend, so we would know which kernel is ok to
use (not to start trying blindly)?
Siim
^ permalink raw reply
* Re: [PATCH 2/6][INET]: Consolidate inet(6)_hash_connect.
From: David Miller @ 2008-01-31 13:15 UTC (permalink / raw)
To: acme; +Cc: xemul, netdev, devel
In-Reply-To: <20080131130153.GP1819@ghostprotocols.net>
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Thu, 31 Jan 2008 11:01:53 -0200
> Em Thu, Jan 31, 2008 at 03:32:09PM +0300, Pavel Emelyanov escreveu:
> > These two functions are the same except for what they call
> > to "check_established" and "hash" for a socket.
> >
> > This saves half-a-kilo for ipv4 and ipv6.
>
> Good stuff!
>
> Yesterday I was perusing tcp_hash and I think we could have the hashinfo
> pointer stored perhaps in sk->sk_prot.
>
> That way we would be able to kill tcp_hash(), inet_put_port() could
> receive just sk, etc.
>
> What do you think?
Sounds good to me.
^ permalink raw reply
* Re: [PATCH 1/6] [IPV4]: Fix memory leak on error path during FIB initialization.
From: David Miller @ 2008-01-31 13:14 UTC (permalink / raw)
To: den; +Cc: netdev, linux-kernel, devel
In-Reply-To: <1201780850-22216-1-git-send-email-den@openvz.org>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 31 Jan 2008 15:00:45 +0300
> commit c8050bf6d84785a7edd2e81591e8f833231477e8
> Author: Denis V. Lunev <den@openvz.org>
> Date: Thu Jan 10 03:28:24 2008 -0800
I am fixing it up for you this time, but please do not
reference the commit this way.
Say something like:
blah blah blah in commit $(SHA1_HASH) ("commit head line").
The author and date give no real useful information in
this context, the important part is giving the reader
enough information to find the commit should they wish
to gain more information.
If they have the commit hash they can usually find the
commit, but if that fails they can search the commit
messages for the head line text string.
I feel like I've had to explain this 10 times in the past week...
:-/
^ permalink raw reply
* Re: [PATCH 6/6][NETNS]: Udp sockets per-net lookup.
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2008-01-31 13:11 UTC (permalink / raw)
To: xemul; +Cc: davem, netdev, devel, yoshfuji
In-Reply-To: <47A1C216.9000303@openvz.org>
In article <47A1C216.9000303@openvz.org> (at Thu, 31 Jan 2008 15:41:58 +0300), Pavel Emelyanov <xemul@openvz.org> says:
> Add the net parameter to udp_get_port family of calls and
> udp_lookup one and use it to filter sockets.
I may miss something, but I'm afraid that I have to disagree.
Port is identified only by family, address, protocol and port,
and should not be split by name space.
--yoshfuji
^ permalink raw reply
* Re: [PATCH retry] bluetooth : add conn add/del workqueues to avoid connection fail
From: Jens Axboe @ 2008-01-31 13:09 UTC (permalink / raw)
To: Dave Young; +Cc: marcel, davem, linux-kernel, bluez-devel, netdev
In-Reply-To: <20080130022354.GA3132@darkstar.te-china.tietoenator.com>
On Wed, Jan 30 2008, Dave Young wrote:
>
> The bluetooth hci_conn sysfs add/del executed in the default workqueue.
> If the del_conn is executed after the new add_conn with same target,
> add_conn will failed with warning of "same kobject name".
>
> Here add btaddconn & btdelconn workqueues,
> flush the btdelconn workqueue in the add_conn function to avoid the issue.
>
> Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
>
> ---
> diff -upr a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
> --- a/net/bluetooth/hci_sysfs.c 2008-01-30 10:14:27.000000000 +0800
> +++ b/net/bluetooth/hci_sysfs.c 2008-01-30 10:14:14.000000000 +0800
> @@ -12,6 +12,8 @@
> #undef BT_DBG
> #define BT_DBG(D...)
> #endif
> +static struct workqueue_struct *btaddconn;
> +static struct workqueue_struct *btdelconn;
>
> static inline char *typetostr(int type)
> {
> @@ -279,6 +281,7 @@ static void add_conn(struct work_struct
> struct hci_conn *conn = container_of(work, struct hci_conn, work);
> int i;
>
> + flush_workqueue(btdelconn);
> if (device_add(&conn->dev) < 0) {
> BT_ERR("Failed to register connection device");
> return;
> @@ -313,6 +316,7 @@ void hci_conn_add_sysfs(struct hci_conn
>
> INIT_WORK(&conn->work, add_conn);
>
> + queue_work(btaddconn, &conn->work);
> schedule_work(&conn->work);
> }
So you queue &conn->work on both btaddconn and keventd_wq?
--
Jens Axboe
^ permalink raw reply
* Re: [PATCH 6/6][NETNS]: Udp sockets per-net lookup.
From: David Miller @ 2008-01-31 13:08 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1C216.9000303@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:41:58 +0300
> Add the net parameter to udp_get_port family of calls and
> udp_lookup one and use it to filter sockets.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied.
^ permalink raw reply
* Re: [PATCH 5/6][NETNS]: Tcp-v6 sockets per-net lookup.
From: David Miller @ 2008-01-31 13:07 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1C1B0.3020807@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:40:16 +0300
> Add a net argument to inet6_lookup and propagate it further.
> Actually, this is tcp-v6 implementation of what was done for
> tcp-v4 sockets in a previous patch.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied.
^ permalink raw reply
* Re: [PATCH 4/6][NETNS]: Tcp-v4 sockets per-net lookup.
From: David Miller @ 2008-01-31 13:06 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1C137.4030306@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:38:15 +0300
> Add a net argument to inet_lookup and propagate it further
> into lookup calls. Plus tune the __inet_check_established.
>
> The dccp and inet_diag, which use that lookup functions
> pass the init_net into them.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied.
^ permalink raw reply
* Re: [PATCH 3/6][NETNS]: Make bind buckets live in net namespaces.
From: David Miller @ 2008-01-31 13:06 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1C09B.6090202@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:35:39 +0300
> This tags the inet_bind_bucket struct with net pointer,
> initializes it during creation and makes a filtering
> during lookup.
>
> A better hashfn, that takes the net into account is to
> be done in the future, but currently all bind buckets
> with similar port will be in one hash chain.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied.
^ permalink raw reply
* Re: [PATCH 2/6][INET]: Consolidate inet(6)_hash_connect.
From: David Miller @ 2008-01-31 13:04 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1BFC9.2030603@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:32:09 +0300
> These two functions are the same except for what they call
> to "check_established" and "hash" for a socket.
>
> This saves half-a-kilo for ipv4 and ipv6.
>
> add/remove: 1/0 grow/shrink: 1/4 up/down: 582/-1128 (-546)
> function old new delta
> __inet_hash_connect - 577 +577
> arp_ignore 108 113 +5
> static.hint 8 4 -4
> rt_worker_func 376 372 -4
> inet6_hash_connect 584 25 -559
> inet_hash_connect 586 25 -561
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied.
^ permalink raw reply
* Re: [PATCH 0/6][IPV6]: Introduce the INET6_TW_MATCH macro.
From: David Miller @ 2008-01-31 13:03 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <47A1BF20.7070509@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 31 Jan 2008 15:29:20 +0300
"0/6"? :-)
> We have INET_MATCH, INET_TW_MATCH and INET6_MATCH to test
> sockets and twbuckets for matching, but ipv6 twbuckets are
> tested manually.
>
> Here's the INET6_TW_MATCH to help with it.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2/6][INET]: Consolidate inet(6)_hash_connect.
From: Arnaldo Carvalho de Melo @ 2008-01-31 13:01 UTC (permalink / raw)
To: Pavel Emelyanov; +Cc: David Miller, Linux Netdev List, devel
In-Reply-To: <47A1BFC9.2030603@openvz.org>
Em Thu, Jan 31, 2008 at 03:32:09PM +0300, Pavel Emelyanov escreveu:
> These two functions are the same except for what they call
> to "check_established" and "hash" for a socket.
>
> This saves half-a-kilo for ipv4 and ipv6.
Good stuff!
Yesterday I was perusing tcp_hash and I think we could have the hashinfo
pointer stored perhaps in sk->sk_prot.
That way we would be able to kill tcp_hash(), inet_put_port() could
receive just sk, etc.
What do you think?
- Arnaldo
^ permalink raw reply
* [PATCH] Disable TSO for non standard qdiscs
From: Andi Kleen @ 2008-01-31 12:46 UTC (permalink / raw)
To: netdev, davem
TSO interacts badly with many queueing disciplines because they rely on
reordering packets from different streams and the large TSO packets can
make this difficult. This patch disables TSO for sockets that send over
devices with non standard queueing disciplines. That's anything but noop
or pfifo_fast and pfifo right now.
Longer term other queueing disciplines could be checked if they
are also ok with TSO. If yes they can set the TCQ_F_GSO_OK flag too.
It is still enabled for the standard pfifo_fast because that will never
reorder packets with the same type-of-service. This means 99+% of all users
will still be able to use TSO just fine.
The status is only set up at socket creation so a shifted route
will not reenable TSO on a existing socket. I don't think that's a
problem though.
Signed-off-by: Andi Kleen <ak@suse.de>
---
include/net/sch_generic.h | 1 +
net/core/sock.c | 3 +++
net/sched/sch_generic.c | 5 +++--
3 files changed, 7 insertions(+), 2 deletions(-)
Index: linux/include/net/sch_generic.h
===================================================================
--- linux.orig/include/net/sch_generic.h
+++ linux/include/net/sch_generic.h
@@ -31,6 +31,7 @@ struct Qdisc
#define TCQ_F_BUILTIN 1
#define TCQ_F_THROTTLED 2
#define TCQ_F_INGRESS 4
+#define TCQ_F_GSO_OK 8
int padded;
struct Qdisc_ops *ops;
u32 handle;
Index: linux/net/sched/sch_generic.c
===================================================================
--- linux.orig/net/sched/sch_generic.c
+++ linux/net/sched/sch_generic.c
@@ -307,7 +307,7 @@ struct Qdisc_ops noop_qdisc_ops __read_m
struct Qdisc noop_qdisc = {
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
- .flags = TCQ_F_BUILTIN,
+ .flags = TCQ_F_BUILTIN | TCQ_F_GSO_OK,
.ops = &noop_qdisc_ops,
.list = LIST_HEAD_INIT(noop_qdisc.list),
};
@@ -325,7 +325,7 @@ static struct Qdisc_ops noqueue_qdisc_op
static struct Qdisc noqueue_qdisc = {
.enqueue = NULL,
.dequeue = noop_dequeue,
- .flags = TCQ_F_BUILTIN,
+ .flags = TCQ_F_BUILTIN | TCQ_F_GSO_OK,
.ops = &noqueue_qdisc_ops,
.list = LIST_HEAD_INIT(noqueue_qdisc.list),
};
@@ -538,6 +538,7 @@ void dev_activate(struct net_device *dev
printk(KERN_INFO "%s: activation failed\n", dev->name);
return;
}
+ qdisc->flags |= TCQ_F_GSO_OK;
list_add_tail(&qdisc->list, &dev->qdisc_list);
} else {
qdisc = &noqueue_qdisc;
Index: linux/net/core/sock.c
===================================================================
--- linux.orig/net/core/sock.c
+++ linux/net/core/sock.c
@@ -112,6 +112,7 @@
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/highmem.h>
+#include <net/sch_generic.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -1062,6 +1063,8 @@ void sk_setup_caps(struct sock *sk, stru
{
__sk_dst_set(sk, dst);
sk->sk_route_caps = dst->dev->features;
+ if (!(dst->dev->qdisc->flags & TCQ_F_GSO_OK))
+ sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
if (sk->sk_route_caps & NETIF_F_GSO)
sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
if (sk_can_gso(sk)) {
Index: linux/net/sched/sch_fifo.c
===================================================================
--- linux.orig/net/sched/sch_fifo.c
+++ linux/net/sched/sch_fifo.c
@@ -62,6 +62,7 @@ static int fifo_init(struct Qdisc *sch,
q->limit = ctl->limit;
}
+ sch->flags |= TCQ_F_GSO_OK;
return 0;
}
^ permalink raw reply
* Re: hard hang through qdisc II
From: Andi Kleen @ 2008-01-31 12:43 UTC (permalink / raw)
To: netdev
In-Reply-To: <200801311321.01015.ak@suse.de>
On Thursday 31 January 2008 13:21:00 Andi Kleen wrote:
>
> I just managed to hang a 2.6.24 (+ some non network patches) kernel
> with the following (non sensical) command
Correction: the kernel was actually a git linus kernel with David's
recent merge included.
I found it's pretty easy to hang the kernel with various tbf parameters.
-Andi
> tc qdisc add dev eth0 root tbf rate 1000 burst 10 limit 100
>
> No oops or anything just hangs. While I understand root can
> do bad things just hanging like this seems a little extreme.
>
> -Andi
>
^ permalink raw reply
* [PATCH 6/6][NETNS]: Udp sockets per-net lookup.
From: Pavel Emelyanov @ 2008-01-31 12:41 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
Add the net parameter to udp_get_port family of calls and
udp_lookup one and use it to filter sockets.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
net/ipv4/udp.c | 25 ++++++++++++++-----------
net/ipv6/udp.c | 10 ++++++----
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2fb8d73..7ea1b67 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -130,14 +130,14 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
atomic_t udp_memory_allocated;
EXPORT_SYMBOL(udp_memory_allocated);
-static inline int __udp_lib_lport_inuse(__u16 num,
+static inline int __udp_lib_lport_inuse(struct net *net, __u16 num,
const struct hlist_head udptable[])
{
struct sock *sk;
struct hlist_node *node;
sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
- if (sk->sk_hash == num)
+ if (sk->sk_net == net && sk->sk_hash == num)
return 1;
return 0;
}
@@ -159,6 +159,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
struct hlist_head *head;
struct sock *sk2;
int error = 1;
+ struct net *net = sk->sk_net;
write_lock_bh(&udp_hash_lock);
@@ -198,7 +199,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
/* 2nd pass: find hole in shortest hash chain */
rover = best;
for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++) {
- if (! __udp_lib_lport_inuse(rover, udptable))
+ if (! __udp_lib_lport_inuse(net, rover, udptable))
goto gotit;
rover += UDP_HTABLE_SIZE;
if (rover > high)
@@ -218,6 +219,7 @@ gotit:
sk_for_each(sk2, node, head)
if (sk2->sk_hash == snum &&
sk2 != sk &&
+ sk2->sk_net == net &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
(!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
|| sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
@@ -261,9 +263,9 @@ static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
* harder than this. -DaveM
*/
-static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
- __be32 daddr, __be16 dport,
- int dif, struct hlist_head udptable[])
+static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
+ __be16 sport, __be32 daddr, __be16 dport,
+ int dif, struct hlist_head udptable[])
{
struct sock *sk, *result = NULL;
struct hlist_node *node;
@@ -274,7 +276,8 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
struct inet_sock *inet = inet_sk(sk);
- if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) {
+ if (sk->sk_net == net && sk->sk_hash == hnum &&
+ !ipv6_only_sock(sk)) {
int score = (sk->sk_family == PF_INET ? 1 : 0);
if (inet->rcv_saddr) {
if (inet->rcv_saddr != daddr)
@@ -361,8 +364,8 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
int harderr;
int err;
- sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
- skb->dev->ifindex, udptable );
+ sk = __udp4_lib_lookup(skb->dev->nd_net, iph->daddr, uh->dest,
+ iph->saddr, uh->source, skb->dev->ifindex, udptable);
if (sk == NULL) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
return; /* No socket for error */
@@ -1185,8 +1188,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
- sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
- inet_iif(skb), udptable);
+ sk = __udp4_lib_lookup(skb->dev->nd_net, saddr, uh->source, daddr,
+ uh->dest, inet_iif(skb), udptable);
if (sk != NULL) {
int ret = 0;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index bd4b9df..53739de 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -56,7 +56,8 @@ static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
}
-static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
+static struct sock *__udp6_lib_lookup(struct net *net,
+ struct in6_addr *saddr, __be16 sport,
struct in6_addr *daddr, __be16 dport,
int dif, struct hlist_head udptable[])
{
@@ -69,7 +70,8 @@ static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
struct inet_sock *inet = inet_sk(sk);
- if (sk->sk_hash == hnum && sk->sk_family == PF_INET6) {
+ if (sk->sk_net == net && sk->sk_hash == hnum &&
+ sk->sk_family == PF_INET6) {
struct ipv6_pinfo *np = inet6_sk(sk);
int score = 0;
if (inet->dport) {
@@ -233,7 +235,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct sock *sk;
int err;
- sk = __udp6_lib_lookup(daddr, uh->dest,
+ sk = __udp6_lib_lookup(skb->dev->nd_net, daddr, uh->dest,
saddr, uh->source, inet6_iif(skb), udptable);
if (sk == NULL)
return;
@@ -478,7 +480,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
* check socket cache ... must talk to Alan about his plans
* for sock caches... i'll skip this for now.
*/
- sk = __udp6_lib_lookup(saddr, uh->source,
+ sk = __udp6_lib_lookup(skb->dev->nd_net, saddr, uh->source,
daddr, uh->dest, inet6_iif(skb), udptable);
if (sk == NULL) {
--
1.5.3.4
^ permalink raw reply related
* [PATCH 5/6][NETNS]: Tcp-v6 sockets per-net lookup.
From: Pavel Emelyanov @ 2008-01-31 12:40 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
Add a net argument to inet6_lookup and propagate it further.
Actually, this is tcp-v6 implementation of what was done for
tcp-v4 sockets in a previous patch.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
include/linux/ipv6.h | 8 ++++----
include/net/inet6_hashtables.h | 17 ++++++++++-------
net/dccp/ipv6.c | 8 ++++----
net/ipv4/inet_diag.c | 2 +-
net/ipv6/inet6_hashtables.c | 25 ++++++++++++++-----------
net/ipv6/tcp_ipv6.c | 19 ++++++++++---------
6 files changed, 43 insertions(+), 36 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c347860..4aaefc3 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -457,16 +457,16 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
#define inet_v6_ipv6only(__sk) 0
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-#define INET6_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET6_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
((__sk)->sk_family == AF_INET6) && \
ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET6_TW_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif) \
- (((__sk)->sk_hash == (__hash)) && \
+#define INET6_TW_MATCH(__sk, __net, __hash, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
(*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports)) && \
((__sk)->sk_family == PF_INET6) && \
(ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))) && \
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 668056b..fdff630 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -57,34 +57,37 @@ extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
*
* The sockhash lock must be held as a reader here.
*/
-extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet6_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif);
-extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *daddr,
const unsigned short hnum,
const int dif);
-static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet6_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
const u16 hnum,
const int dif)
{
- struct sock *sk = __inet6_lookup_established(hashinfo, saddr, sport,
- daddr, hnum, dif);
+ struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr,
+ sport, daddr, hnum, dif);
if (sk)
return sk;
- return inet6_lookup_listener(hashinfo, daddr, hnum, dif);
+ return inet6_lookup_listener(net, hashinfo, daddr, hnum, dif);
}
-extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+extern struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index f42b75c..ed0a005 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -101,8 +101,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int err;
__u64 seq;
- sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
- &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
+ sk = inet6_lookup(&init_net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+ &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
if (sk == NULL) {
ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -366,7 +366,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
if (req != NULL)
return dccp_check_req(sk, skb, req, prev);
- nsk = __inet6_lookup_established(&dccp_hashinfo,
+ nsk = __inet6_lookup_established(&init_net, &dccp_hashinfo,
&iph->saddr, dh->dccph_sport,
&iph->daddr, ntohs(dh->dccph_dport),
inet6_iif(skb));
@@ -797,7 +797,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
/* Step 2:
* Look up flow ID in table and get corresponding socket */
- sk = __inet6_lookup(&dccp_hashinfo, &ipv6_hdr(skb)->saddr,
+ sk = __inet6_lookup(&init_net, &dccp_hashinfo, &ipv6_hdr(skb)->saddr,
dh->dccph_sport,
&ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
inet6_iif(skb));
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 95c9f14..da97695 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -274,7 +274,7 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
}
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
else if (req->idiag_family == AF_INET6) {
- sk = inet6_lookup(hashinfo,
+ sk = inet6_lookup(&init_net, hashinfo,
(struct in6_addr *)req->id.idiag_dst,
req->id.idiag_dport,
(struct in6_addr *)req->id.idiag_src,
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index ece6d0e..d325a99 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -54,7 +54,8 @@ EXPORT_SYMBOL(__inet6_hash);
*
* The sockhash lock must be held as a reader here.
*/
-struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock *__inet6_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr,
const __be16 sport,
const struct in6_addr *daddr,
@@ -75,12 +76,12 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
read_lock(lock);
sk_for_each(sk, node, &head->chain) {
/* For IPV6 do the cheaper port and family tests first. */
- if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk, net, hash, 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->twchain) {
- if (INET6_TW_MATCH(sk, hash, saddr, daddr, ports, dif))
+ if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif))
goto hit;
}
read_unlock(lock);
@@ -93,9 +94,9 @@ hit:
}
EXPORT_SYMBOL(__inet6_lookup_established);
-struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
- const struct in6_addr *daddr,
- const unsigned short hnum, const int dif)
+struct sock *inet6_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo, const struct in6_addr *daddr,
+ const unsigned short hnum, const int dif)
{
struct sock *sk;
const struct hlist_node *node;
@@ -104,7 +105,8 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
read_lock(&hashinfo->lhash_lock);
sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) {
- if (inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) {
+ if (sk->sk_net == net && inet_sk(sk)->num == hnum &&
+ sk->sk_family == PF_INET6) {
const struct ipv6_pinfo *np = inet6_sk(sk);
score = 1;
@@ -136,7 +138,7 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
EXPORT_SYMBOL_GPL(inet6_lookup_listener);
-struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
+struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
const struct in6_addr *saddr, const __be16 sport,
const struct in6_addr *daddr, const __be16 dport,
const int dif)
@@ -144,7 +146,7 @@ struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
struct sock *sk;
local_bh_disable();
- sk = __inet6_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
+ sk = __inet6_lookup(net, hashinfo, saddr, sport, daddr, ntohs(dport), dif);
local_bh_enable();
return sk;
@@ -170,6 +172,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ struct net *net = sk->sk_net;
prefetch(head->chain.first);
write_lock(lock);
@@ -178,7 +181,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
sk_for_each(sk2, node, &head->twchain) {
tw = inet_twsk(sk2);
- if (INET6_TW_MATCH(sk2, hash, saddr, daddr, ports, dif)) {
+ if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) {
if (twsk_unique(sk, sk2, twp))
goto unique;
else
@@ -189,7 +192,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+ if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif))
goto not_unique;
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 00c0839..59d0029 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -330,8 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
struct tcp_sock *tp;
__u32 seq;
- sk = inet6_lookup(&tcp_hashinfo, &hdr->daddr, th->dest, &hdr->saddr,
- th->source, skb->dev->ifindex);
+ sk = inet6_lookup(skb->dev->nd_net, &tcp_hashinfo, &hdr->daddr,
+ th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
if (sk == NULL) {
ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
@@ -1208,9 +1208,9 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
if (req)
return tcp_check_req(sk, skb, req, prev);
- nsk = __inet6_lookup_established(&tcp_hashinfo, &ipv6_hdr(skb)->saddr,
- th->source, &ipv6_hdr(skb)->daddr,
- ntohs(th->dest), inet6_iif(skb));
+ nsk = __inet6_lookup_established(sk->sk_net, &tcp_hashinfo,
+ &ipv6_hdr(skb)->saddr, th->source,
+ &ipv6_hdr(skb)->daddr, ntohs(th->dest), inet6_iif(skb));
if (nsk) {
if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1710,9 +1710,10 @@ static int tcp_v6_rcv(struct sk_buff *skb)
TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
TCP_SKB_CB(skb)->sacked = 0;
- sk = __inet6_lookup(&tcp_hashinfo, &ipv6_hdr(skb)->saddr, th->source,
- &ipv6_hdr(skb)->daddr, ntohs(th->dest),
- inet6_iif(skb));
+ sk = __inet6_lookup(skb->dev->nd_net, &tcp_hashinfo,
+ &ipv6_hdr(skb)->saddr, th->source,
+ &ipv6_hdr(skb)->daddr, ntohs(th->dest),
+ inet6_iif(skb));
if (!sk)
goto no_tcp_socket;
@@ -1792,7 +1793,7 @@ do_time_wait:
{
struct sock *sk2;
- sk2 = inet6_lookup_listener(&tcp_hashinfo,
+ sk2 = inet6_lookup_listener(skb->dev->nd_net, &tcp_hashinfo,
&ipv6_hdr(skb)->daddr,
ntohs(th->dest), inet6_iif(skb));
if (sk2 != NULL) {
--
1.5.3.4
^ permalink raw reply related
* [PATCH 4/6][NETNS]: Tcp-v4 sockets per-net lookup.
From: Pavel Emelyanov @ 2008-01-31 12:38 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
Add a net argument to inet_lookup and propagate it further
into lookup calls. Plus tune the __inet_check_established.
The dccp and inet_diag, which use that lookup functions
pass the init_net into them.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
include/net/inet_hashtables.h | 48 +++++++++++++++++++++++------------------
net/dccp/ipv4.c | 6 ++--
net/ipv4/inet_diag.c | 2 +-
net/ipv4/inet_hashtables.c | 29 ++++++++++++++++--------
net/ipv4/tcp_ipv4.c | 15 ++++++------
5 files changed, 58 insertions(+), 42 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 55532b9..c23c4ed 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -302,15 +302,17 @@ out:
wake_up(&hashinfo->lhash_wait);
}
-extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+extern struct sock *__inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 daddr,
const unsigned short hnum,
const int dif);
-static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo,
- __be32 daddr, __be16 dport, int dif)
+static inline struct sock *inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
+ __be32 daddr, __be16 dport, int dif)
{
- return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif);
+ return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif);
}
/* Socket demux engine toys. */
@@ -344,26 +346,26 @@ typedef __u64 __bitwise __addrpair;
(((__force __u64)(__be32)(__daddr)) << 32) | \
((__force __u64)(__be32)(__saddr)));
#endif /* __BIG_ENDIAN */
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
#else /* 32-bit arch */
#define INET_ADDR_COOKIE(__name, __saddr, __daddr)
-#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
(inet_sk(__sk)->daddr == (__saddr)) && \
(inet_sk(__sk)->rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
-#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
- (((__sk)->sk_hash == (__hash)) && \
+#define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \
(inet_twsk(__sk)->tw_daddr == (__saddr)) && \
(inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \
((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
@@ -376,32 +378,36 @@ typedef __u64 __bitwise __addrpair;
*
* Local BH must be disabled here.
*/
-extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+extern struct sock * __inet_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum, const int dif);
static inline struct sock *
- inet_lookup_established(struct inet_hashinfo *hashinfo,
+ inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
- return __inet_lookup_established(hashinfo, saddr, sport, daddr,
+ return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
ntohs(dport), dif);
}
-static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *__inet_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
{
u16 hnum = ntohs(dport);
- struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
- hnum, dif);
- return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif);
+ struct sock *sk = __inet_lookup_established(net, hashinfo,
+ saddr, sport, daddr, hnum, dif);
+
+ return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif);
}
-static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
+static inline struct sock *inet_lookup(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const __be16 dport,
const int dif)
@@ -409,7 +415,7 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
struct sock *sk;
local_bh_disable();
- sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif);
+ sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
local_bh_enable();
return sk;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 9e38b0d..c982ad8 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -218,7 +218,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
return;
}
- sk = inet_lookup(&dccp_hashinfo, iph->daddr, dh->dccph_dport,
+ sk = inet_lookup(&init_net, &dccp_hashinfo, iph->daddr, dh->dccph_dport,
iph->saddr, dh->dccph_sport, inet_iif(skb));
if (sk == NULL) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
@@ -436,7 +436,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
if (req != NULL)
return dccp_check_req(sk, skb, req, prev);
- nsk = inet_lookup_established(&dccp_hashinfo,
+ nsk = inet_lookup_established(&init_net, &dccp_hashinfo,
iph->saddr, dh->dccph_sport,
iph->daddr, dh->dccph_dport,
inet_iif(skb));
@@ -817,7 +817,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
/* Step 2:
* Look up flow ID in table and get corresponding socket */
- sk = __inet_lookup(&dccp_hashinfo,
+ sk = __inet_lookup(&init_net, &dccp_hashinfo,
iph->saddr, dh->dccph_sport,
iph->daddr, dh->dccph_dport, inet_iif(skb));
/*
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 4cfb15c..95c9f14 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -268,7 +268,7 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
err = -EINVAL;
if (req->idiag_family == AF_INET) {
- sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
+ sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0],
req->id.idiag_dport, req->id.idiag_src[0],
req->id.idiag_sport, req->id.idiag_if);
}
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index db1e53a..48d4500 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -127,7 +127,8 @@ EXPORT_SYMBOL(inet_listen_wlock);
* remote address for the connection. So always assume those are both
* wildcarded during the search since they can never be otherwise.
*/
-static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
+static struct sock *inet_lookup_listener_slow(struct net *net,
+ const struct hlist_head *head,
const __be32 daddr,
const unsigned short hnum,
const int dif)
@@ -139,7 +140,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
sk_for_each(sk, node, head) {
const struct inet_sock *inet = inet_sk(sk);
- if (inet->num == hnum && !ipv6_only_sock(sk)) {
+ if (sk->sk_net == net && inet->num == hnum &&
+ !ipv6_only_sock(sk)) {
const __be32 rcv_saddr = inet->rcv_saddr;
int score = sk->sk_family == PF_INET ? 1 : 0;
@@ -165,7 +167,8 @@ static struct sock *inet_lookup_listener_slow(const struct hlist_head *head,
}
/* Optimize the common listener case. */
-struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
+struct sock *__inet_lookup_listener(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 daddr, const unsigned short hnum,
const int dif)
{
@@ -180,9 +183,9 @@ struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
if (inet->num == hnum && !sk->sk_node.next &&
(!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
(sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
- !sk->sk_bound_dev_if)
+ !sk->sk_bound_dev_if && sk->sk_net == net)
goto sherry_cache;
- sk = inet_lookup_listener_slow(head, daddr, hnum, dif);
+ sk = inet_lookup_listener_slow(net, head, daddr, hnum, dif);
}
if (sk) {
sherry_cache:
@@ -193,7 +196,8 @@ sherry_cache:
}
EXPORT_SYMBOL_GPL(__inet_lookup_listener);
-struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+struct sock * __inet_lookup_established(struct net *net,
+ struct inet_hashinfo *hashinfo,
const __be32 saddr, const __be16 sport,
const __be32 daddr, const u16 hnum,
const int dif)
@@ -212,13 +216,15 @@ struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
prefetch(head->chain.first);
read_lock(lock);
sk_for_each(sk, node, &head->chain) {
- if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk, net, 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->twchain) {
- if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_TW_MATCH(sk, net, hash, acookie,
+ saddr, daddr, ports, dif))
goto hit;
}
sk = NULL;
@@ -249,6 +255,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
struct sock *sk2;
const struct hlist_node *node;
struct inet_timewait_sock *tw;
+ struct net *net = sk->sk_net;
prefetch(head->chain.first);
write_lock(lock);
@@ -257,7 +264,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
sk_for_each(sk2, node, &head->twchain) {
tw = inet_twsk(sk2);
- if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+ if (INET_TW_MATCH(sk2, net, hash, acookie,
+ saddr, daddr, ports, dif)) {
if (twsk_unique(sk, sk2, twp))
goto unique;
else
@@ -268,7 +276,8 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
/* And established part... */
sk_for_each(sk2, node, &head->chain) {
- if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+ if (INET_MATCH(sk2, net, hash, acookie,
+ saddr, daddr, ports, dif))
goto not_unique;
}
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9aea88b..77c1939 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -369,8 +369,8 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
return;
}
- sk = inet_lookup(&tcp_hashinfo, iph->daddr, th->dest, iph->saddr,
- th->source, inet_iif(skb));
+ sk = inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->daddr, th->dest,
+ iph->saddr, th->source, inet_iif(skb));
if (!sk) {
ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
return;
@@ -1503,8 +1503,8 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
if (req)
return tcp_check_req(sk, skb, req, prev);
- nsk = inet_lookup_established(&tcp_hashinfo, iph->saddr, th->source,
- iph->daddr, th->dest, inet_iif(skb));
+ nsk = inet_lookup_established(sk->sk_net, &tcp_hashinfo, iph->saddr,
+ th->source, iph->daddr, th->dest, inet_iif(skb));
if (nsk) {
if (nsk->sk_state != TCP_TIME_WAIT) {
@@ -1661,8 +1661,8 @@ int tcp_v4_rcv(struct sk_buff *skb)
TCP_SKB_CB(skb)->flags = iph->tos;
TCP_SKB_CB(skb)->sacked = 0;
- sk = __inet_lookup(&tcp_hashinfo, iph->saddr, th->source,
- iph->daddr, th->dest, inet_iif(skb));
+ sk = __inet_lookup(skb->dev->nd_net, &tcp_hashinfo, iph->saddr,
+ th->source, iph->daddr, th->dest, inet_iif(skb));
if (!sk)
goto no_tcp_socket;
@@ -1735,7 +1735,8 @@ do_time_wait:
}
switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
case TCP_TW_SYN: {
- struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
+ struct sock *sk2 = inet_lookup_listener(skb->dev->nd_net,
+ &tcp_hashinfo,
iph->daddr, th->dest,
inet_iif(skb));
if (sk2) {
--
1.5.3.4
^ permalink raw reply related
* [PATCH 3/6][NETNS]: Make bind buckets live in net namespaces.
From: Pavel Emelyanov @ 2008-01-31 12:35 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
This tags the inet_bind_bucket struct with net pointer,
initializes it during creation and makes a filtering
during lookup.
A better hashfn, that takes the net into account is to
be done in the future, but currently all bind buckets
with similar port will be in one hash chain.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
include/net/inet_hashtables.h | 2 ++
net/ipv4/inet_connection_sock.c | 8 +++++---
net/ipv4/inet_hashtables.c | 8 ++++++--
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index a34a8f2..55532b9 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -74,6 +74,7 @@ struct inet_ehash_bucket {
* ports are created in O(1) time? I thought so. ;-) -DaveM
*/
struct inet_bind_bucket {
+ struct net *ib_net;
unsigned short port;
signed short fastreuse;
struct hlist_node node;
@@ -194,6 +195,7 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
extern struct inet_bind_bucket *
inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct net *net,
struct inet_bind_hashbucket *head,
const unsigned short snum);
extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 7801cce..de5a41d 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -87,6 +87,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
struct hlist_node *node;
struct inet_bind_bucket *tb;
int ret;
+ struct net *net = sk->sk_net;
local_bh_disable();
if (!snum) {
@@ -100,7 +101,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
spin_lock(&head->lock);
inet_bind_bucket_for_each(tb, node, &head->chain)
- if (tb->port == rover)
+ if (tb->ib_net == net && tb->port == rover)
goto next;
break;
next:
@@ -127,7 +128,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
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->ib_net == net && tb->port == snum)
goto tb_found;
}
tb = NULL;
@@ -147,7 +148,8 @@ tb_found:
}
tb_not_found:
ret = 1;
- if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep, head, snum)) == NULL)
+ if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep,
+ net, head, snum)) == NULL)
goto fail_unlock;
if (hlist_empty(&tb->owners)) {
if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index b93d40f..db1e53a 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -28,12 +28,14 @@
* The bindhash mutex for snum's hash chain must be held here.
*/
struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
+ struct net *net,
struct inet_bind_hashbucket *head,
const unsigned short snum)
{
struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
if (tb != NULL) {
+ tb->ib_net = net;
tb->port = snum;
tb->fastreuse = 0;
INIT_HLIST_HEAD(&tb->owners);
@@ -359,6 +361,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct inet_bind_hashbucket *head;
struct inet_bind_bucket *tb;
int ret;
+ struct net *net = sk->sk_net;
if (!snum) {
int i, remaining, low, high, port;
@@ -381,7 +384,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
* unique enough.
*/
inet_bind_bucket_for_each(tb, node, &head->chain) {
- if (tb->port == port) {
+ if (tb->ib_net == net && tb->port == port) {
BUG_TRAP(!hlist_empty(&tb->owners));
if (tb->fastreuse >= 0)
goto next_port;
@@ -392,7 +395,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
}
}
- tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+ tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+ net, head, port);
if (!tb) {
spin_unlock(&head->lock);
break;
--
1.5.3.4
^ permalink raw reply related
* [PATCH 2/6][INET]: Consolidate inet(6)_hash_connect.
From: Pavel Emelyanov @ 2008-01-31 12:32 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
These two functions are the same except for what they call
to "check_established" and "hash" for a socket.
This saves half-a-kilo for ipv4 and ipv6.
add/remove: 1/0 grow/shrink: 1/4 up/down: 582/-1128 (-546)
function old new delta
__inet_hash_connect - 577 +577
arp_ignore 108 113 +5
static.hint 8 4 -4
rt_worker_func 376 372 -4
inet6_hash_connect 584 25 -559
inet_hash_connect 586 25 -561
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
include/net/inet_hashtables.h | 5 ++
net/ipv4/inet_hashtables.c | 32 +++++++++-----
net/ipv6/inet6_hashtables.c | 93 +----------------------------------------
3 files changed, 28 insertions(+), 102 deletions(-)
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 761bdc0..a34a8f2 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -413,6 +413,11 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
return sk;
}
+extern int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk,
+ int (*check_established)(struct inet_timewait_death_row *,
+ struct sock *, __u16, struct inet_timewait_sock **),
+ void (*hash)(struct inet_hashinfo *, struct sock *));
extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk);
#endif /* _INET_HASHTABLES_H */
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 619c63c..b93d40f 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -348,11 +348,11 @@ void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
}
EXPORT_SYMBOL_GPL(__inet_hash);
-/*
- * Bind a port for a connect operation and hash it.
- */
-int inet_hash_connect(struct inet_timewait_death_row *death_row,
- struct sock *sk)
+int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk,
+ int (*check_established)(struct inet_timewait_death_row *,
+ struct sock *, __u16, struct inet_timewait_sock **),
+ void (*hash)(struct inet_hashinfo *, struct sock *))
{
struct inet_hashinfo *hinfo = death_row->hashinfo;
const unsigned short snum = inet_sk(sk)->num;
@@ -385,9 +385,8 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
BUG_TRAP(!hlist_empty(&tb->owners));
if (tb->fastreuse >= 0)
goto next_port;
- if (!__inet_check_established(death_row,
- sk, port,
- &tw))
+ if (!check_established(death_row, sk,
+ port, &tw))
goto ok;
goto next_port;
}
@@ -415,7 +414,7 @@ ok:
inet_bind_hash(sk, tb, port);
if (sk_unhashed(sk)) {
inet_sk(sk)->sport = htons(port);
- __inet_hash_nolisten(hinfo, sk);
+ hash(hinfo, sk);
}
spin_unlock(&head->lock);
@@ -432,17 +431,28 @@ ok:
tb = inet_csk(sk)->icsk_bind_hash;
spin_lock_bh(&head->lock);
if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
- __inet_hash_nolisten(hinfo, sk);
+ hash(hinfo, sk);
spin_unlock_bh(&head->lock);
return 0;
} else {
spin_unlock(&head->lock);
/* No definite answer... Walk to established hash table */
- ret = __inet_check_established(death_row, sk, snum, NULL);
+ ret = check_established(death_row, sk, snum, NULL);
out:
local_bh_enable();
return ret;
}
}
+EXPORT_SYMBOL_GPL(__inet_hash_connect);
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+ struct sock *sk)
+{
+ return __inet_hash_connect(death_row, sk,
+ __inet_check_established, __inet_hash_nolisten);
+}
EXPORT_SYMBOL_GPL(inet_hash_connect);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 06b01be..ece6d0e 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -233,97 +233,8 @@ static inline u32 inet6_sk_port_offset(const struct sock *sk)
int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk)
{
- struct inet_hashinfo *hinfo = death_row->hashinfo;
- const unsigned short snum = inet_sk(sk)->num;
- struct inet_bind_hashbucket *head;
- struct inet_bind_bucket *tb;
- int ret;
-
- if (snum == 0) {
- int i, port, low, high, remaining;
- static u32 hint;
- const u32 offset = hint + inet6_sk_port_offset(sk);
- struct hlist_node *node;
- struct inet_timewait_sock *tw = NULL;
-
- inet_get_local_port_range(&low, &high);
- remaining = (high - low) + 1;
-
- local_bh_disable();
- for (i = 1; i <= remaining; i++) {
- port = low + (i + offset) % remaining;
- head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
- spin_lock(&head->lock);
-
- /* Does not bother with rcv_saddr checks,
- * because the established check is already
- * unique enough.
- */
- inet_bind_bucket_for_each(tb, node, &head->chain) {
- if (tb->port == port) {
- BUG_TRAP(!hlist_empty(&tb->owners));
- if (tb->fastreuse >= 0)
- goto next_port;
- if (!__inet6_check_established(death_row,
- sk, port,
- &tw))
- goto ok;
- goto next_port;
- }
- }
-
- tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
- head, port);
- if (!tb) {
- spin_unlock(&head->lock);
- break;
- }
- tb->fastreuse = -1;
- goto ok;
-
- next_port:
- spin_unlock(&head->lock);
- }
- local_bh_enable();
-
- return -EADDRNOTAVAIL;
-
-ok:
- hint += i;
-
- /* Head lock still held and bh's disabled */
- inet_bind_hash(sk, tb, port);
- if (sk_unhashed(sk)) {
- inet_sk(sk)->sport = htons(port);
- __inet6_hash(hinfo, sk);
- }
- spin_unlock(&head->lock);
-
- if (tw) {
- inet_twsk_deschedule(tw, death_row);
- inet_twsk_put(tw);
- }
-
- ret = 0;
- goto out;
- }
-
- head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
- tb = inet_csk(sk)->icsk_bind_hash;
- spin_lock_bh(&head->lock);
-
- if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
- __inet6_hash(hinfo, sk);
- spin_unlock_bh(&head->lock);
- return 0;
- } else {
- spin_unlock(&head->lock);
- /* No definite answer... Walk to established hash table */
- ret = __inet6_check_established(death_row, sk, snum, NULL);
-out:
- local_bh_enable();
- return ret;
- }
+ return __inet_hash_connect(death_row, sk,
+ __inet6_check_established, __inet6_hash);
}
EXPORT_SYMBOL_GPL(inet6_hash_connect);
--
1.5.3.4
^ permalink raw reply related
* [PATCH 0/6][IPV6]: Introduce the INET6_TW_MATCH macro.
From: Pavel Emelyanov @ 2008-01-31 12:29 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
We have INET_MATCH, INET_TW_MATCH and INET6_MATCH to test
sockets and twbuckets for matching, but ipv6 twbuckets are
tested manually.
Here's the INET6_TW_MATCH to help with it.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
include/linux/ipv6.h | 8 ++++++++
net/ipv6/inet6_hashtables.c | 21 +++------------------
2 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 5d35a4c..c347860 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -465,6 +465,14 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+#define INET6_TW_MATCH(__sk, __hash, __saddr, __daddr, __ports, __dif) \
+ (((__sk)->sk_hash == (__hash)) && \
+ (*((__portpair *)&(inet_twsk(__sk)->tw_dport)) == (__ports)) && \
+ ((__sk)->sk_family == PF_INET6) && \
+ (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_daddr, (__saddr))) && \
+ (ipv6_addr_equal(&inet6_twsk(__sk)->tw_v6_rcv_saddr, (__daddr))) && \
+ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
+
#endif /* __KERNEL__ */
#endif /* _IPV6_H */
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index a66a7d8..06b01be 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -80,17 +80,8 @@ struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
}
/* Must check for a TIME_WAIT'er before going to listener hash. */
sk_for_each(sk, node, &head->twchain) {
- const struct inet_timewait_sock *tw = inet_twsk(sk);
-
- if(*((__portpair *)&(tw->tw_dport)) == ports &&
- sk->sk_family == PF_INET6) {
- const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
-
- if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
- ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
- (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
- goto hit;
- }
+ if (INET6_TW_MATCH(sk, hash, saddr, daddr, ports, dif))
+ goto hit;
}
read_unlock(lock);
return NULL;
@@ -185,15 +176,9 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
/* Check TIME-WAIT sockets first. */
sk_for_each(sk2, node, &head->twchain) {
- const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
-
tw = inet_twsk(sk2);
- if(*((__portpair *)&(tw->tw_dport)) == ports &&
- sk2->sk_family == PF_INET6 &&
- ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
- ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
- (!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) {
+ if (INET6_TW_MATCH(sk2, hash, saddr, daddr, ports, dif)) {
if (twsk_unique(sk, sk2, twp))
goto unique;
else
--
1.5.3.4
^ permalink raw reply related
* hard hang through qdisc
From: Andi Kleen @ 2008-01-31 12:21 UTC (permalink / raw)
To: netdev
I just managed to hang a 2.6.24 (+ some non network patches) kernel
with the following (non sensical) command
tc qdisc add dev eth0 root tbf rate 1000 burst 10 limit 100
No oops or anything just hangs. While I understand root can
do bad things just hanging like this seems a little extreme.
-Andi
^ permalink raw reply
* Re: e1000 full-duplex TCP performance well below wire speed
From: Carsten Aulbert @ 2008-01-31 11:35 UTC (permalink / raw)
To: Rick Jones
Cc: Brandeburg, Jesse, Bruce Allen, netdev, Henning Fehrmann,
Bruce Allen
In-Reply-To: <47A0C5B2.1000500@hp.com>
Good morning (my TZ),
I'll try to answer all questions, hoewver if I miss something big,
please point my nose to it again.
Rick Jones wrote:
>> As asked in LKML thread, please post the exact netperf command used to
>> start the client/server, whether or not you're using irqbalanced (aka
>> irqbalance) and what cat /proc/interrupts looks like (you ARE using MSI,
>> right?)
>
netperf was used without any special tuning parameters. Usually we start
two processes on two hosts which start (almost) simultaneously, last for
20-60 seconds and simply use UDP_STREAM (works well) and TCP_STREAM, i.e.
on 192.168.0.202: netperf -H 192.168.2.203 -t TCP_STREAL -l 20
on 192.168.0.203: netperf -H 192.168.2.202 -t TCP_STREAL -l 20
192.168.0.20[23] here is on eth0 which cannot do jumbo frames, thus we
use the .2. part for eth1 for a range of mtus.
The server is started on both nodes with the start-stop-daemon and no
special parameters I'm aware of.
/proc/interrupts shows me PCI_MSI-edge thus, I think YES.
> In particular, it would be good to know if you are doing two concurrent
> streams, or if you are using the "burst mode" TCP_RR with large
> request/response sizes method which then is only using one connection.
>
As outlined above: Two concurrent streams right now. If you think TCP_RR
should be better I'm happy to rerun some tests.
More in other emails.
I'll wade through them slowly.
Carsten
^ permalink raw reply
* [PATCH] macb: Fix section mismatch and shrink runtime footprint
From: Haavard Skinnemoen @ 2008-01-31 12:10 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, David Brownell, Haavard Skinnemoen
macb devices are only found integrated on SoCs, so they can't be
hotplugged. Thus, the probe() and exit() functions can be __init and
__exit, respectively. By using platform_driver_probe() instead of
platform_driver_register(), there won't be any references to the
discarded probe() function after the driver has loaded.
This also fixes a section mismatch due to macb_probe(), defined as
__devinit, calling macb_get_hwaddr, defined as __init.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
---
drivers/net/macb.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index e10528e..81bf005 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -1084,7 +1084,7 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(phydev, if_mii(rq), cmd);
}
-static int __devinit macb_probe(struct platform_device *pdev)
+static int __init macb_probe(struct platform_device *pdev)
{
struct eth_platform_data *pdata;
struct resource *regs;
@@ -1248,7 +1248,7 @@ err_out:
return err;
}
-static int __devexit macb_remove(struct platform_device *pdev)
+static int __exit macb_remove(struct platform_device *pdev)
{
struct net_device *dev;
struct macb *bp;
@@ -1276,8 +1276,7 @@ static int __devexit macb_remove(struct platform_device *pdev)
}
static struct platform_driver macb_driver = {
- .probe = macb_probe,
- .remove = __devexit_p(macb_remove),
+ .remove = __exit_p(macb_remove),
.driver = {
.name = "macb",
},
@@ -1285,7 +1284,7 @@ static struct platform_driver macb_driver = {
static int __init macb_init(void)
{
- return platform_driver_register(&macb_driver);
+ return platform_driver_probe(&macb_driver, macb_probe);
}
static void __exit macb_exit(void)
--
1.5.3.8
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox