* [PATCH net-next-2.6 0/5] XFRM,IPv6: Removal of RH2/HAO from IPsec-protected MIPv6 traffic
From: Arnaud Ebalard @ 2010-09-24 19:18 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Herbert Xu, Hideaki YOSHIFUJI; +Cc: netdev
Hi,
First off, patches for discussion are in following emails. They are
*against current linux-2.6* (on which they were tested) but will be
rebased against net-next-2.6 for next round.
Simply put, the patches provides the ability to remove annoying Routing
Header Type 2 and Destination Options Header with Home Address Option
from IPsec-protected MIPv6 signaling traffic, changing on-wire format
from:
MN ------------ IPv6() / HAO / ESP(BU) ----------> HA
MN <----------- IPv6() / RH2 / ESP(BA) ----------- HA
to
MN ------------ IPv6() / ESP(BU) --------------> HA
MN <----------- IPv6() / ESP(BA) --------------- HA
This is an *self-contained* part of a set of additional enhancements for
Mobile IPv6 when used w/ IPsec and IKE specified in IRO draft [1]. Once
available, this can also be extended to IPsec-protected route optimized
communications between MN and CN/MN.
Among the operational benefits of the feature is the ability to run in
networks in which (dumb) firewalls drop Routing Headers (Cisco PIX
firewalls are known to do that by default and w/o ways of correcting the
issue). Anonimity is another.
Basically, RH2/HAO are only *explicit* containers for the Home Address
(HoA), which is obviously available in the IPsec stack (transport mode
SA protecting traffic use the HoA). This means that the info is
available on both sides and there is no real need to carry it explictly.
>From an implementation standpoint, some changes are required to allow
finding the SA when the addresses are not expected ones and remap them
if asked to do so (or act as usual if not). Then, most of the other
changes are basically simple versions of what can be found at the moment
for RH2 and HAO in DestOpt handling. Unlike what happens with RH2/HAO,
packets structure is never modified.
I rely on the feature on my MN (my laptop) and HA for 2 kernel versions
to provide me with connectivity (v4 networks are handled using
m6t [1]). Patches for UMIP [2] are available and will be merged upstream
if the feature gets accepted. At the moment, the people using the Debian
package for UMIP [3] can simply benefit from the feature by compiling a
patched kernel (2.6.34 and 2.6.35.5 available [5]), and then doing a
simple apt-get remove umip && apt-get install umip-iro.
Cheers,
a+
[1] http://tools.ietf.org/html/draft-ebalard-mext-ipsec-ro
[2] http://natisbad.org/m6t/
[3] http://umip.org/
[4] http://umip.org/docs/umip-debrepo.html
[5] http://natisbad.org/IRO/
^ permalink raw reply
* [PATCH 15/24] net: change to new flag variable
From: matt mooney @ 2010-09-24 19:17 UTC (permalink / raw)
To: kernel-janitors-u79uwXL29TY76Z2rM5mHXA
Cc: Sjur Braendeland, Jouni Malinen, John W. Linville, Daniel Drake,
Ulrich Kunitz, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <e0bdab5d2e8c52041c003de68ba774c3e706716c.1285355033.git.mfm-Oo0r1OC9pj9iLUuM0BA3LQ@public.gmane.org>
Replace EXTRA_CFLAGS with ccflags-y.
Signed-off-by: matt mooney <mfm-Oo0r1OC9pj9iLUuM0BA3LQ@public.gmane.org>
---
drivers/net/caif/Makefile | 4 +---
drivers/net/skfp/Makefile | 2 +-
drivers/net/wan/lmc/Makefile | 2 +-
drivers/net/wireless/hostap/hostap_config.h | 4 ++--
drivers/net/wireless/zd1211rw/Makefile | 4 +---
5 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
index 3a11d61..b5dc44c 100644
--- a/drivers/net/caif/Makefile
+++ b/drivers/net/caif/Makefile
@@ -1,6 +1,4 @@
-ifeq ($(CONFIG_CAIF_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
# Serial interface
obj-$(CONFIG_CAIF_TTY) += caif_serial.o
diff --git a/drivers/net/skfp/Makefile b/drivers/net/skfp/Makefile
index cb23580..045d815 100644
--- a/drivers/net/skfp/Makefile
+++ b/drivers/net/skfp/Makefile
@@ -17,4 +17,4 @@ skfp-objs := skfddi.o hwmtm.o fplustm.o smt.o cfm.o \
# projects. To keep the source common for all those drivers (and
# thus simplify fixes to it), please do not clean it up!
-EXTRA_CFLAGS += -Idrivers/net/skfp -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes
+ccflags-y := -Idrivers/net/skfp -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes
diff --git a/drivers/net/wan/lmc/Makefile b/drivers/net/wan/lmc/Makefile
index dabdcfe..609710d 100644
--- a/drivers/net/wan/lmc/Makefile
+++ b/drivers/net/wan/lmc/Makefile
@@ -14,4 +14,4 @@ lmc-objs := lmc_debug.o lmc_media.o lmc_main.o lmc_proto.o
# -DDEBUG \
# -DLMC_PACKET_LOG
-EXTRA_CFLAGS += -I. $(DBGDEF)
+ccflags-y := -I. $(DBGDEF)
diff --git a/drivers/net/wireless/hostap/hostap_config.h b/drivers/net/wireless/hostap/hostap_config.h
index 30acd39..2c8f71f 100644
--- a/drivers/net/wireless/hostap/hostap_config.h
+++ b/drivers/net/wireless/hostap/hostap_config.h
@@ -30,9 +30,9 @@
/* Following defines can be used to remove unneeded parts of the driver, e.g.,
* to limit the size of the kernel module. Definitions can be added here in
- * hostap_config.h or they can be added to make command with EXTRA_CFLAGS,
+ * hostap_config.h or they can be added to make command with ccflags-y,
* e.g.,
- * 'make pccard EXTRA_CFLAGS="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
+ * 'make pccard ccflags-y="-DPRISM2_NO_DEBUG -DPRISM2_NO_PROCFS_DEBUG"'
*/
/* Do not include debug messages into the driver */
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile
index 1907eaf..5728a91 100644
--- a/drivers/net/wireless/zd1211rw/Makefile
+++ b/drivers/net/wireless/zd1211rw/Makefile
@@ -5,7 +5,5 @@ zd1211rw-objs := zd_chip.o zd_mac.o \
zd_rf_al7230b.o zd_rf_uw2453.o \
zd_rf.o zd_usb.o
-ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+ccflags-$(CONFIG_ZD1211RW_DEBUG) := -DDEBUG
--
1.7.2.1
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 10/24] isdn: change to new flag variable
From: matt mooney @ 2010-09-24 19:17 UTC (permalink / raw)
To: kernel-janitors; +Cc: Karsten Keil, netdev, linux-kernel
In-Reply-To: <e0bdab5d2e8c52041c003de68ba774c3e706716c.1285355033.git.mfm@muteddisk.com>
Replace EXTRA_CFLAGS with ccflags-y.
Signed-off-by: matt mooney <mfm@muteddisk.com>
---
drivers/isdn/hisax/Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index ab638b08..646368f 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -4,7 +4,7 @@
# Define maximum number of cards
-EXTRA_CFLAGS += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS)
+ccflags-y := -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS)
obj-$(CONFIG_ISDN_DRV_HISAX) += hisax.o
obj-$(CONFIG_HISAX_SEDLBAUER_CS) += sedlbauer_cs.o
--
1.7.2.1
^ permalink raw reply related
* Re: [PATCH net-next-2.6 0/5] XFRM,IPv6: Removal of RH2/HAO from IPsec-protected MIPv6 traffic
From: David Miller @ 2010-09-24 19:01 UTC (permalink / raw)
To: arno; +Cc: eric.dumazet, herbert, yoshfuji, netdev
In-Reply-To: <87ocbnxa0i.fsf@small.ssi.corp>
From: arno@natisbad.org (Arnaud Ebalard)
Date: Fri, 24 Sep 2010 20:38:05 +0200
> Hi,
>
> [This is a resend: after 6 hours, nothing appeared on the list. Sorry
> if you received it twice]
They didn't appear on the list because your email header fields
are all screwed up, I forwarded the bounce messages to you twice
under seperate cover.
^ permalink raw reply
* Re: [PATCH 2/5] AF_UNIX: enable/disable multicast with getsockopt/setsockopt
From: Eric Dumazet @ 2010-09-24 18:02 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel
In-Reply-To: <1285350388.2478.0.camel@edumazet-laptop>
Le vendredi 24 septembre 2010 à 19:46 +0200, Eric Dumazet a écrit :
Hmm
dbus-owner@lists.freedesktop.org is a subscriber only list ....
Please dont use it
^ permalink raw reply
* Re: [PATCH 4/5] AF_UNIX: find peers on multicast Unix stream sockets
From: Eric Dumazet @ 2010-09-24 18:00 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus
In-Reply-To: <1285349116-17529-4-git-send-email-alban.crequy@collabora.co.uk>
Le vendredi 24 septembre 2010 à 18:25 +0100, Alban Crequy a écrit :
> @@ -1612,7 +1671,12 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
> } else {
> sunaddr = NULL;
> err = -ENOTCONN;
> - other = NULL; /* FIXME: get the list of other connection */
> + max_others = atomic_read(&unix_nr_multicast_socks);
> + others = kzalloc((max_others + 1) * sizeof(void *), GFP_KERNEL);
> + unix_find_other(sock_net(sk), u->addr->name,
> + u->addr->len, 0, u->addr->hash, 1, others, max_others, &err);
> + other = others[0];
> + kfree(others);
> if (!other)
> goto out_err;
> }
Seriously, this block sizing against unix_nr_multicast_socks is not
scalable. What happens if we have 1000 sockets ?
kzalloc() to clear 8000 bytes ?
Its also unsafe.
(say you kzalloc() a buffer for 2 sockets, and another cpu inserts a new
socket. unix_find_socket_byname() can overflow the buffer)
You should use a list, and allocates elements in
unix_find_socket_byname()
struct item {
struct item *next;
struct sock *s;
};
^ permalink raw reply
* Re: [PATCH 1/8] posix clocks: introduce a syscall for clock tuning.
From: john stultz @ 2010-09-24 17:55 UTC (permalink / raw)
To: Richard Cochran
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
netdev-u79uwXL29TY76Z2rM5mHXA, Arnd Bergmann, Christoph Lameter,
David Miller, Krzysztof Halasa, Peter Zijlstra, Rodolfo Giometti,
Thomas Gleixner
In-Reply-To: <20100924072946.GA5043-7KxsofuKt4IfAd9E5cN8NEzG7cXyKsk/@public.gmane.org>
On Fri, 2010-09-24 at 09:29 +0200, Richard Cochran wrote:
> On Thu, Sep 23, 2010 at 12:48:51PM -0700, john stultz wrote:
> > So I'd still split this patch up a little bit more.
> >
> > 1) Patch that implements the ADJ_SETOFFSET (*and its implementation*)
> > in do_adjtimex.
> >
> > 2) Patch that adds the new syscall and clock_id multiplexing.
> >
> > 3) Patches that wire it up to the rest of the architectures (there's
> > still a bunch missing here).
>
> I was not sure what the policy is about adding syscalls. Is it the
> syscall author's responsibility to add it into every arch?
>
> The last time (see a2e2725541fad7) the commit only added half of some
> archs, and ignored others. In my patch, the syscall *really* works on
> the archs that are present in the patch.
>
> (Actually, I did not test blackfin, since I don't have one, but I
> included it since I know they have a PTP hardware clock.)
I'm not sure about policy, but I think for completeness sake you should
make sure every arch supports a new syscall. You're not expected to be
able to test every one, but getting the basic support patch sent to
maintainers should be done.
> > > +static inline int common_clock_adj(const clockid_t which_clock, struct timex *t)
> > > +{
> > > + if (CLOCK_REALTIME == which_clock)
> > > + return do_adjtimex(t);
> > > + else
> > > + return -EOPNOTSUPP;
> > > +}
> >
> >
> > Would it make sense to point to the do_adjtimex() in the k_clock
> > definition for CLOCK_REALTIME rather then conditionalizing it here?
>
> But what about CLOCK_MONOTONIC_RAW, for example?
-EOPNOTSUPP
> Does it make sense to allow it to be adjusted?
No. I think only CLOCK_REALTIME would make sense of the existing clocks.
I'm just suggesting you conditionalize it from the function pointer,
rather then in the common function.
thanks
-john
^ permalink raw reply
* Re: [PATCH 2/5] AF_UNIX: enable/disable multicast with getsockopt/setsockopt
From: Eric Dumazet @ 2010-09-24 17:46 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus
In-Reply-To: <1285349116-17529-2-git-send-email-alban.crequy@collabora.co.uk>
Le vendredi 24 septembre 2010 à 18:25 +0100, Alban Crequy a écrit :
> Multicast can be enabled or disabled after a socket is allocated but this
> cannot be changed once the socket is bound or connected.
>
> Userspace applications can enable multicast on an Unix stream socket:
> sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
> #define UNIX_MULTICAST 1
> val = 1;
> len = sizeof(val);
> ret = setsockopt(sockfd, 0, UNIX_MULTICAST, &val, len);
>
> Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
> + if (val != 0) {
> + u->multicast = 1;
> + } else {
> + u->multicast = 0;
> + }
u->multicast = !!val;
^ permalink raw reply
* [PATCH 4/5] AF_UNIX: find peers on multicast Unix stream sockets
From: Alban Crequy @ 2010-09-24 17:25 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Eric Dumazet, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus, Alban Crequy
In-Reply-To: <20100924182257.11abd9a6@chocolatine.cbg.collabora.co.uk>
Multicast sockets are stored in the hash table unix_multicast_socket_table.
unix_find_socket_byname() is extended to return an array of sockets matching
the name instead of only one socket. Then unix_stream_sendmsg() can find all
the multicast peers.
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
net/unix/af_unix.c | 134 ++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 99 insertions(+), 35 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index a8d9de7..f259849 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -115,11 +115,13 @@
#include <net/checksum.h>
#include <linux/security.h>
-static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
+static struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE + 1];
static DEFINE_SPINLOCK(unix_table_lock);
static atomic_t unix_nr_socks = ATOMIC_INIT(0);
+static atomic_t unix_nr_multicast_socks = ATOMIC_INIT(0);
-#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
+#define unix_multicast_socket_table (&unix_socket_table[UNIX_HASH_SIZE])
+#define unix_sockets_unbound (&unix_socket_table[2 * UNIX_HASH_SIZE])
#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
@@ -227,7 +229,6 @@ static void __unix_remove_socket(struct sock *sk)
static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
{
- WARN_ON(!sk_unhashed(sk));
sk_add_node(sk, list);
}
@@ -247,12 +248,14 @@ static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
static struct sock *__unix_find_socket_byname(struct net *net,
struct sockaddr_un *sunname,
- int len, int type, unsigned hash)
+ int len, int type,
+ unsigned hash, int multicast)
{
struct sock *s;
struct hlist_node *node;
+ unsigned int index = (multicast ? UNIX_HASH_SIZE : 0) + (hash ^ type);
- sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
+ sk_for_each(s, node, &unix_socket_table[index]) {
struct unix_sock *u = unix_sk(s);
if (!net_eq(sock_net(s), net))
@@ -267,29 +270,50 @@ found:
return s;
}
-static inline struct sock *unix_find_socket_byname(struct net *net,
- struct sockaddr_un *sunname,
- int len, int type,
- unsigned hash)
+static inline void unix_find_socket_byname(struct net *net,
+ struct sockaddr_un *sunname,
+ int len, int type,
+ unsigned hash,
+ int multicast,
+ struct sock **others, int max_others)
{
struct sock *s;
+ struct hlist_node *node;
+ int i = 0;
+ unsigned int index = (multicast ? UNIX_HASH_SIZE : 0) + (hash ^ type);
spin_lock(&unix_table_lock);
- s = __unix_find_socket_byname(net, sunname, len, type, hash);
- if (s)
- sock_hold(s);
+
+ sk_for_each(s, node, &unix_socket_table[index]) {
+ struct unix_sock *u = unix_sk(s);
+
+ if (!net_eq(sock_net(s), net))
+ continue;
+
+ if (u->addr->len == len &&
+ !memcmp(u->addr->name, sunname, len)) {
+
+ others[i++] = s;
+ sock_hold(s);
+ if (i == max_others)
+ break;
+ }
+ }
+
spin_unlock(&unix_table_lock);
- return s;
}
-static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
+static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i,
+ int multicast)
{
struct sock *s;
struct hlist_node *node;
+ unsigned int index = (multicast ? UNIX_HASH_SIZE : 0)
+ + (i->i_ino & (UNIX_HASH_SIZE - 1));
spin_lock(&unix_table_lock);
sk_for_each(s, node,
- &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
+ &unix_socket_table[index]) {
struct dentry *dentry = unix_sk(s)->dentry;
if (!net_eq(sock_net(s), net))
@@ -363,6 +387,9 @@ static void unix_sock_destructor(struct sock *sk)
if (u->addr)
unix_release_addr(u->addr);
+ if (u->multicast)
+ atomic_dec(&unix_nr_multicast_socks);
+
atomic_dec(&unix_nr_socks);
local_bh_disable();
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
@@ -700,7 +727,7 @@ retry:
ordernum = (ordernum+1)&0xFFFFF;
if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
- addr->hash)) {
+ addr->hash, 0)) {
spin_unlock(&unix_table_lock);
/* Sanity yield. It is unusual case, but yet... */
if (!(ordernum&0xFF))
@@ -719,9 +746,11 @@ out: mutex_unlock(&u->readlock);
return err;
}
-static struct sock *unix_find_other(struct net *net,
- struct sockaddr_un *sunname, int len,
- int type, unsigned hash, int *error)
+static void unix_find_other(struct net *net,
+ struct sockaddr_un *sunname, int len,
+ int type, unsigned hash, int multicast,
+ struct sock **others, int max_others,
+ int *error)
{
struct sock *u;
struct path path;
@@ -740,7 +769,7 @@ static struct sock *unix_find_other(struct net *net,
err = -ECONNREFUSED;
if (!S_ISSOCK(inode->i_mode))
goto put_fail;
- u = unix_find_socket_byinode(net, inode);
+ u = unix_find_socket_byinode(net, inode, multicast);
if (!u)
goto put_fail;
@@ -754,24 +783,26 @@ static struct sock *unix_find_other(struct net *net,
sock_put(u);
goto fail;
}
+ others[0] = u;
} else {
+ int i;
err = -ECONNREFUSED;
- u = unix_find_socket_byname(net, sunname, len, type, hash);
- if (u) {
+ unix_find_socket_byname(net, sunname, len, type, hash,
+ multicast, others, max_others);
+ for(i = 0 ; i < max_others && others[i] != NULL ; i++) {
struct dentry *dentry;
- dentry = unix_sk(u)->dentry;
+ dentry = unix_sk(others[i])->dentry;
if (dentry)
- touch_atime(unix_sk(u)->mnt, dentry);
- } else
- goto fail;
+ touch_atime(unix_sk(others[i])->mnt, dentry);
+ }
}
- return u;
+ return;
put_fail:
path_put(&path);
fail:
*error = err;
- return NULL;
+ return;
}
@@ -862,7 +893,7 @@ out_mknod_drop_write:
if (!sunaddr->sun_path[0]) {
err = -EADDRINUSE;
if (__unix_find_socket_byname(net, sunaddr, addr_len,
- sk->sk_type, hash)) {
+ sk->sk_type, hash, 0)) {
unix_release_addr(addr);
goto out_unlock;
}
@@ -929,7 +960,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
- struct sock *other;
+ struct sock *other = NULL;
unsigned hash;
int err;
@@ -944,7 +975,8 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
goto out;
restart:
- other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
+ unix_find_other(net, sunaddr, alen, sock->type, hash,
+ 0, &other, 1, &err);
if (!other)
goto out;
@@ -1063,7 +1095,8 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
restart:
/* Find listening sock. */
- other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
+ unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, 0, &other,
+ 1, &err);
if (!other && !u->multicast)
goto out;
@@ -1075,6 +1108,26 @@ restart:
if (u->multicast) {
sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
+
+ unix_find_other(net, sunaddr, addr_len, sk->sk_type,
+ hash, 1, &other, 1, &err);
+ if (other) {
+ otheru = unix_sk(other);
+ atomic_inc(&otheru->addr->refcnt);
+ u->addr = otheru->addr;
+ } else {
+ err = -ENOMEM;
+ u->addr = kmalloc(sizeof(*u->addr)+addr_len, GFP_KERNEL);
+ if (!u->addr)
+ return err;
+
+ memcpy(u->addr->name, sunaddr, addr_len);
+ u->addr->len = addr_len;
+ u->addr->hash = hash ^ sk->sk_type;
+ atomic_set(&u->addr->refcnt, 1);
+ }
+
+ unix_insert_socket(&unix_multicast_socket_table[u->addr->hash], sk);
return 0;
}
@@ -1427,8 +1480,8 @@ restart:
if (sunaddr == NULL)
goto out_free;
- other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
- hash, &err);
+ unix_find_other(net, sunaddr, namelen, sk->sk_type,
+ hash, 0, &other, 1, &err);
if (other == NULL)
goto out_free;
}
@@ -1530,8 +1583,12 @@ static int unix_stream_setsockopt(struct socket *sock, int level, int optname,
return -EINVAL;
if (val != 0) {
+ if (!u->multicast)
+ atomic_inc(&unix_nr_multicast_socks);
u->multicast = 1;
} else {
+ if (u->multicast)
+ atomic_dec(&unix_nr_multicast_socks);
u->multicast = 0;
}
break;
@@ -1582,6 +1639,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
struct sock *sk = sock->sk;
struct sock *other = NULL;
+ struct sock **others = NULL;
+ int max_others;
struct sockaddr_un *sunaddr = msg->msg_name;
int err, size;
struct sk_buff *skb;
@@ -1612,7 +1671,12 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
} else {
sunaddr = NULL;
err = -ENOTCONN;
- other = NULL; /* FIXME: get the list of other connection */
+ max_others = atomic_read(&unix_nr_multicast_socks);
+ others = kzalloc((max_others + 1) * sizeof(void *), GFP_KERNEL);
+ unix_find_other(sock_net(sk), u->addr->name,
+ u->addr->len, 0, u->addr->hash, 1, others, max_others, &err);
+ other = others[0];
+ kfree(others);
if (!other)
goto out_err;
}
--
1.7.1
^ permalink raw reply related
* [PATCH 0/5] RFC: Multicast and filtering features on AF_UNIX
From: Alban Crequy @ 2010-09-24 17:22 UTC (permalink / raw)
To: Alban Crequy, David S. Miller, Eric Dumazet, Stephen Hemminger,
Cyrill
Hi,
I am working on improving the performances of D-Bus [1]. dbus-daemon is
connected to the peers with Unix sockets and delivers D-Bus messages
according to match rules set by the peers themselves. Every D-Bus
message goes through dbus-daemon. The number of recipients if often 1
but it can be 0, 1, or more. With this architecture, dbus-daemon has to
wake up for every message on the bus and the context switches are
expensive.
/--------\ unix socket /-------------\ unix socket /-----------\
| sender |------------->| dbus-daemon |------------->| recipient |
\--------/ AF_UNIX \-------------/ AF_UNIX \-----------/
Ian and I wrote a kernel module "dbus" to improve the performances (the
sources are not attached to this email but available there: [2]). This
is a proof-of-concept. It implements a new address family AF_DBUS,
similar to AF_UNIX, but the kernel is smart enough to deliver the
messages directly to the correct recipients, bypassing dbus-daemon. The
only change in userspace is to use AF_DBUS instead of AF_UNIX. I
compared the performances here [2]. It is about 5000 lines of code (a
big part is duplicated from net/unix/af_unix.c).
Another possibility is to add the needed features directly in AF_UNIX
sockets (and avoid to create a new address family for D-Bus):
- multicast
- some kind of BSD socket filters?
- untables?
And hopefully the new features would be useful for other userspace
applications in addition to D-Bus. Wireshark could read and display
AF_UNIX packets.
I am looking for feedback on what is the best way to do this.
The following patches implements multicast on stream Unix socket.
Applications have to enable multicast on the socket with setsockopt()
and then every packets will be delivered to all sockets connected to
the multicast address. The patches are also available on [3].
[1] http://www.freedesktop.org/wiki/Software/dbus
[2] http://alban.apinc.org/blog/2010/09/15/d-bus-in-the-kernel-faster/
[3]
http://git.collabora.co.uk/?p=user/alban/linux-2.6.35.y/.git;a=shortlog;h=refs/heads/unix-multicast
--
Alban Crequy
^ permalink raw reply
* [PATCH 1/5] AF_UNIX: add getsockopt and setsockopt on stream sockets
From: Alban Crequy @ 2010-09-24 17:25 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Eric Dumazet, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus, Alban Crequy
In-Reply-To: <20100924182257.11abd9a6@chocolatine.cbg.collabora.co.uk>
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
net/unix/af_unix.c | 21 +++++++++++++++++++--
1 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index fef2cc5..47d9f77 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -492,6 +492,10 @@ static unsigned int unix_dgram_poll(struct file *, struct socket *,
poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
static int unix_shutdown(struct socket *, int);
+static int unix_stream_setsockopt(struct socket *, int, int,
+ char __user *, unsigned int);
+static int unix_stream_getsockopt(struct socket *, int, int,
+ char __user *, int __user *);
static int unix_stream_sendmsg(struct kiocb *, struct socket *,
struct msghdr *, size_t);
static int unix_stream_recvmsg(struct kiocb *, struct socket *,
@@ -518,8 +522,8 @@ static const struct proto_ops unix_stream_ops = {
.ioctl = unix_ioctl,
.listen = unix_listen,
.shutdown = unix_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
+ .setsockopt = unix_stream_setsockopt,
+ .getsockopt = unix_stream_getsockopt,
.sendmsg = unix_stream_sendmsg,
.recvmsg = unix_stream_recvmsg,
.mmap = sock_no_mmap,
@@ -1494,6 +1498,19 @@ out:
}
+static int unix_stream_setsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, unsigned int optlen)
+{
+ return -EOPNOTSUPP;
+}
+
+int unix_stream_getsockopt(struct socket *sock, int level, int optname,
+ char __user *optval, int __user *optlen)
+{
+ return -EOPNOTSUPP;
+}
+
+
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct msghdr *msg, size_t len)
{
--
1.7.1
^ permalink raw reply related
* [PATCH 5/5] AF_UNIX: deliver the data to all the multicast peers
From: Alban Crequy @ 2010-09-24 17:25 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Eric Dumazet, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus, Alban Crequy
In-Reply-To: <20100924182257.11abd9a6@chocolatine.cbg.collabora.co.uk>
With multicast sockets, unix_stream_sendmsg() needs to deliver the data to
zero, one or several recipients. skb_clone() is used to get as many sk_buff as
recipients.
If a multicast peer is too slow to receive the packets, it will block the
sender at some point in sock_alloc_send_skb().
A sender can receive SIGPIPE caused by an unique peer on the multicast group.
This is probably not what we want.
I tested this with a few peers and either sending data, receiving data or just
sleeping.
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
net/unix/af_unix.c | 77 +++++++++++++++++++++++++++++++++++----------------
1 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f259849..01cb603 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1640,10 +1640,10 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sock *other = NULL;
struct sock **others = NULL;
+ struct sock **others_cur = NULL;
int max_others;
struct sockaddr_un *sunaddr = msg->msg_name;
int err, size;
- struct sk_buff *skb;
int sent = 0;
struct scm_cookie tmp_scm;
bool fds_sent = false;
@@ -1668,15 +1668,22 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
other = unix_peer(sk);
if (!other)
goto out_err;
+ err = -ENOMEM;
+ others = kzalloc(2 * sizeof(void *), GFP_KERNEL);
+ if (!others)
+ goto out_err;
+ others[0] = other;
} else {
sunaddr = NULL;
- err = -ENOTCONN;
max_others = atomic_read(&unix_nr_multicast_socks);
+ err = -ENOMEM;
others = kzalloc((max_others + 1) * sizeof(void *), GFP_KERNEL);
+ if (!others)
+ goto out_err;
unix_find_other(sock_net(sk), u->addr->name,
u->addr->len, 0, u->addr->hash, 1, others, max_others, &err);
+ err = -ENOTCONN;
other = others[0];
- kfree(others);
if (!other)
goto out_err;
}
@@ -1685,6 +1692,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
goto pipe_err;
while (sent < len) {
+ struct sk_buff *skb;
+ struct sk_buff *skb_cloned;
/*
* Optimisation for the fact that under 0.01% of X
* messages typically need breaking up.
@@ -1718,43 +1727,61 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
*/
size = min_t(int, size, skb_tailroom(skb));
- memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
- /* Only send the fds in the first buffer */
- if (siocb->scm->fp && !fds_sent) {
- err = unix_attach_fds(siocb->scm, skb);
- if (err) {
- kfree_skb(skb);
- goto out_err;
- }
- fds_sent = true;
- }
-
err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
if (err) {
kfree_skb(skb);
goto out_err;
}
- unix_state_lock(other);
+ others_cur = others;
+ while (*others_cur != NULL) {
+ skb_cloned = skb_clone(skb, GFP_KERNEL);
+ if (!skb_cloned) {
+ kfree_skb(skb);
+ goto out_err;
+ }
+ skb_set_owner_w(skb_cloned, sk);
+
+ memcpy(UNIXCREDS(skb_cloned), &siocb->scm->creds, sizeof(struct ucred));
+ /* Only send the fds in the first buffer of each
+ * recipient */
+ if (siocb->scm->fp && !fds_sent) {
+ err = unix_attach_fds(siocb->scm, skb_cloned);
+ if (err) {
+ kfree_skb(skb);
+ kfree_skb(skb_cloned);
+ goto out_err;
+ }
+ }
+
+ unix_state_lock(*others_cur);
- if (sock_flag(other, SOCK_DEAD) ||
- (other->sk_shutdown & RCV_SHUTDOWN))
- goto pipe_err_free;
+ if (sock_flag(*others_cur, SOCK_DEAD) ||
+ ((*others_cur)->sk_shutdown & RCV_SHUTDOWN)) {
+ unix_state_unlock(*others_cur);
+ kfree_skb(skb);
+ kfree_skb(skb_cloned);
+ goto pipe_err;
+ }
- skb_queue_tail(&other->sk_receive_queue, skb);
- unix_state_unlock(other);
- other->sk_data_ready(other, size);
+ skb_queue_tail(&(*others_cur)->sk_receive_queue,
+ skb_cloned);
+ unix_state_unlock(*others_cur);
+ (*others_cur)->sk_data_ready(*others_cur, size);
+ others_cur++;
+ }
+ kfree_skb(skb);
+ fds_sent = true;
sent += size;
}
scm_destroy(siocb->scm);
siocb->scm = NULL;
+ if (others)
+ kfree(others);
return sent;
-pipe_err_free:
- unix_state_unlock(other);
- kfree_skb(skb);
pipe_err:
if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
send_sig(SIGPIPE, current, 0);
@@ -1762,6 +1789,8 @@ pipe_err:
out_err:
scm_destroy(siocb->scm);
siocb->scm = NULL;
+ if (others)
+ kfree(others);
return sent ? : err;
}
--
1.7.1
^ permalink raw reply related
* [PATCH 3/5] AF_UNIX: implement connect() on multicast Unix stream socket
From: Alban Crequy @ 2010-09-24 17:25 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Eric Dumazet, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus, Alban Crequy
In-Reply-To: <20100924182257.11abd9a6@chocolatine.cbg.collabora.co.uk>
All multicast peers use connect() without any bound socket.
Multicast Unix socket addresses and non-multicast Unix socket addresses live in
the same namespace. An userspace application cannot connect() a non-multicast
socket if the address is already used for multicast sockets.
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
net/unix/af_unix.c | 22 ++++++++++++++++++++--
1 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c766e88..a8d9de7 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1064,9 +1064,20 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
restart:
/* Find listening sock. */
other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
- if (!other)
+ if (!other && !u->multicast)
goto out;
+ if (other && u->multicast) {
+ err = -ECONNREFUSED;
+ goto out;
+ }
+
+ if (u->multicast) {
+ sock->state = SS_CONNECTED;
+ sk->sk_state = TCP_ESTABLISHED;
+ return 0;
+ }
+
/* Latch state of peer */
unix_state_lock(other);
@@ -1567,6 +1578,7 @@ int unix_stream_getsockopt(struct socket *sock, int level, int optname,
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct msghdr *msg, size_t len)
{
+ struct unix_sock *u = unix_sk(sock->sk);
struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
struct sock *sk = sock->sk;
struct sock *other = NULL;
@@ -1591,12 +1603,18 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (msg->msg_namelen) {
err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
goto out_err;
- } else {
+ } else if (!u->multicast) {
sunaddr = NULL;
err = -ENOTCONN;
other = unix_peer(sk);
if (!other)
goto out_err;
+ } else {
+ sunaddr = NULL;
+ err = -ENOTCONN;
+ other = NULL; /* FIXME: get the list of other connection */
+ if (!other)
+ goto out_err;
}
if (sk->sk_shutdown & SEND_SHUTDOWN)
--
1.7.1
^ permalink raw reply related
* [PATCH 2/5] AF_UNIX: enable/disable multicast with getsockopt/setsockopt
From: Alban Crequy @ 2010-09-24 17:25 UTC (permalink / raw)
To: Alban Crequy
Cc: David S. Miller, Eric Dumazet, Stephen Hemminger, Cyrill Gorcunov,
Alexey Dobriyan, Lennart Poettering, Kay Sievers, Ian Molton,
netdev, linux-kernel, dbus, Alban Crequy
In-Reply-To: <20100924182257.11abd9a6@chocolatine.cbg.collabora.co.uk>
Multicast can be enabled or disabled after a socket is allocated but this
cannot be changed once the socket is bound or connected.
Userspace applications can enable multicast on an Unix stream socket:
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
#define UNIX_MULTICAST 1
val = 1;
len = sizeof(val);
ret = setsockopt(sockfd, 0, UNIX_MULTICAST, &val, len);
Signed-off-by: Alban Crequy <alban.crequy@collabora.co.uk>
---
include/net/af_unix.h | 4 +++
net/unix/af_unix.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 20725e2..4c77c69 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -40,6 +40,9 @@ struct unix_skb_parms {
spin_lock_nested(&unix_sk(s)->lock, \
SINGLE_DEPTH_NESTING)
+/* UNIX socket options */
+#define UNIX_MULTICAST 1 /* Enable multicast Unix sockets */
+
#ifdef __KERNEL__
/* The AF_UNIX socket */
struct unix_sock {
@@ -56,6 +59,7 @@ struct unix_sock {
spinlock_t lock;
unsigned int gc_candidate : 1;
unsigned int gc_maybe_cycle : 1;
+ unsigned int multicast : 1;
struct socket_wq peer_wq;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 47d9f77..c766e88 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1501,13 +1501,66 @@ out:
static int unix_stream_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, unsigned int optlen)
{
- return -EOPNOTSUPP;
+ struct unix_sock *u = unix_sk(sock->sk);
+ int val;
+ int err = 0;
+
+ if (optlen < sizeof(int))
+ return -EINVAL;
+
+ if (get_user(val, (int __user *)optval))
+ return -EFAULT;
+
+ switch (optname) {
+ case UNIX_MULTICAST:
+ /* Multicast feature can only be changed when the socket is
+ * not used yet */
+ if (u->addr || sock->sk->sk_state != TCP_CLOSE)
+ return -EINVAL;
+
+ if (val != 0) {
+ u->multicast = 1;
+ } else {
+ u->multicast = 0;
+ }
+ break;
+
+ default:
+ err = -ENOPROTOOPT;
+ break;
+ }
+
+ return err;
}
int unix_stream_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
- return -EOPNOTSUPP;
+ struct unix_sock *u = unix_sk(sock->sk);
+ int val, len;
+
+ if (get_user(len, optlen))
+ return -EFAULT;
+
+ len = min_t(unsigned int, len, sizeof(int));
+
+ if (len < 0)
+ return -EINVAL;
+
+ switch (optname) {
+ case UNIX_MULTICAST:
+ val = u->multicast;
+ break;
+
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (put_user(len, optlen))
+ return -EFAULT;
+ if (copy_to_user(optval, &val, len))
+ return -EFAULT;
+ return 0;
}
--
1.7.1
^ permalink raw reply related
* Re: [ABI REVIEW][PATCH 0/8] Namespace file descriptors
From: Eric W. Biederman @ 2010-09-24 17:06 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Andrew Lutomirski, Sukadev Bhattiprolu, Pavel Emelyanov,
Pavel Emelyanov, Ulrich Drepper, netdev, Jonathan Corbet,
linux-kernel, Jan Engelhardt, linux-fsdevel, netfilter-devel,
Michael Kerrisk, Linux Containers, Ben Greear, Linus Torvalds,
David Miller, Al Viro
In-Reply-To: <4C9CAC7C.2080900@free.fr>
Daniel Lezcano <daniel.lezcano@free.fr> writes:
> On 09/24/2010 03:02 PM, Andrew Lutomirski wrote:
>> Eric W. Biederman wrote:
>>> Introduce file for manipulating namespaces and related syscalls.
>>> files:
>>> /proc/self/ns/<nstype>
>>>
>>> syscalls:
>>> int setns(unsigned long nstype, int fd);
>>> socketat(int nsfd, int family, int type, int protocol);
>>>
>>
>> How does security work? Are there different kinds of fd that give (say) pin-the-namespace permission, socketat permission, and setns permission?
>
> AFAICS, socketat, setns and "set netns by fd" only accept fd from
> /proc/<pid>/ns/<ns>.
>
> setns does :
>
> file = proc_ns_fget(fd);
> if (IS_ERR(file))
> return PTR_ERR(file);
>
> proc_ns_fget checks if (file->f_op != &ns_file_operations)
>
>
> socketat and get_net_ns_by_fd:
>
> net = get_net_ns_by_fd(fd);
>
> this one calls proc_ns_fget.
>
> We have the guarantee here, the fd is resulting from an open of the file with
> the right permissions.
In particular the default /proc permissions say you have to be the owner
of the process (or root) to access the file. If you are the owner of
the process with a namespace (or root) you already have permission to
access and manipulate the namespace.
Additionally setns like unshare requires CAP_SYS_ADMIN (aka root magic).
> Another way to pin the namespace, would be to mount --bind /proc/<pid>/ns/<ns>
> but we have to be root to do that ...
Simply keeping the process running, pins the namespace. That requires no
new permissions.
Similarly socketat. It is possible to use unix domain sockets to
implement it today without any kernel changes. It is just an
unnecessary pain to run a server process to pin a namespace or to serve
up file descriptors in other network namespaces.
The primary change of this patchset is the ability to do everything
with file descriptors, and with the mount namespace. That moves
everything from a bizarre hard to understand and manipulate interface
to one where things can be done much more easily, and cheaply.
Resulting in a much more powerful and usable interface.
Eric
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Eric Dumazet @ 2010-09-24 16:58 UTC (permalink / raw)
To: Ulrich Weber; +Cc: Ulrich Weber, David Miller, netdev
In-Reply-To: <4C9CD466.4010909@astaro.com>
Le vendredi 24 septembre 2010 à 18:40 +0200, Ulrich Weber a écrit :
> On 09/24/2010 06:05 PM, Eric Dumazet wrote:
> > Le vendredi 24 septembre 2010 à 17:38 +0200, Ulrich Weber a écrit :
> >> steps to reproduce:
> >> server:
> >> ip route add 1.0.0.0/8 dev dummy0
> >>
> >> client:
> >> ip route add 1.0.0.0/8 dev eth0
> >> nmap --min-rate 500 -sP 1.0.0.0/8
> >>
> >
> > Great, you use nmap and fill 'client' neighbour cache.
>
> Nope, I fills the 'server' neighbor cache too
> due cached routes in arp_process():
> if (arp->ar_op == htons(ARPOP_REQUEST) &&
> ip_route_input_noref(skb, tip, sip, 0, dev) == 0)
It fills the "server neighbor cache" because you specifically said it
has 2^24 ip addresses.
If using a normal route to gateway on eth0, it only fills route cache,
with a max of 65536 slots on your config, not 1024. When max is reached,
garbage collection takes place.
>
> > Now, back to the _real_ problem, please ?
> >
> > <quote>
> >
> > Background: At home I have two Internet connections, DSL and Cable.
> > DSL is the primary uplink while Cable is the secondary.
> > My Cable ISP is flooding me with ARP request from 10.0.0.0/8,
> > which creates routes via the primary uplink.
> > There are thousands of cached routes and after some time
> > I get "Neighbour table overflow" messages.
> >
> > </quote>
> >
> > You receive an ARP request on device eth1,
> > this creates a route on eth0 ?
> >
> > Could you send your routing/address setup ?
> >
> > ip addr
> > ip ro
> >
>
> ARP request flood comes in via eth2.
>
> Have to correct myself: With configuration below only route cache
> increases but no "Neighbour table overflow".
>
> By adding "ip route add 10.0.0.0/8 dev eth0" the Neighbor table overflow
> will occur.
>
Because you want instead "ip route add 10.0.0.0/8 via gateway"
Or else you are vulnerable to an attack, as you discovered.
Here it works perfectly.
rtstat -c20 -i1|cut -c1-60
rt_cache|rt_cache|rt_cache|rt_cache|rt_cache|rt_cache|rt_cac
entries| in_hit|in_slow_|in_slow_|in_no_ro| in_brd|in_mar
| | tot| mc| ute| | an_d
1984| 2| 1| 0| 0| 0|
1984| 2| 0| 0| 0| 0|
1984| 2| 0| 0| 0| 0|
1985| 4| 2| 0| 0| 0|
1988| 0| 4| 0| 0| 0|
2020| 1| 33| 0| 0| 0|
2042| 1| 23| 0| 0| 0|
2104| 0| 63| 0| 0| 0|
2117| 0| 14| 0| 0| 0|
2141| 0| 26| 0| 0| 0|
2159| 1| 19| 0| 0| 0|
2175| 0| 17| 0| 0| 0|
2221| 0| 48| 0| 0| 0|
2241| 0| 20| 0| 0| 0|
2256| 0| 17| 0| 0| 0|
2269| 3| 15| 0| 0| 0|
2286| 0| 17| 0| 0| 0|
2295| 1| 10| 0| 0| 0|
2326| 1| 33| 0| 0| 0|
>
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
> inet 127.0.0.1/8 scope host lo
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
> state UP qlen 1000
> inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0
> 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
> state UP qlen 1000
> inet 78.43.x.x/22 brd 78.43.35.255 scope global eth2
> 12: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc hfsc
> state UNKNOWN qlen 3
> inet 95.114.x.x peer 213.20.56.129/32 scope global ppp0
>
>
> default via 213.20.56.129 dev ppp0
> 78.43.32.0/22 dev eth2 proto kernel scope link src 78.43.x.x
> 127.0.0.0/8 dev lo scope link
> 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1
> 213.20.56.129 dev ppp0 proto kernel scope link src 95.114.x.x
>
>
Thanks
^ permalink raw reply
* Re: [PATCH net-next-2.6] rps: allocate rx queues in register_netdevice only
From: John Fastabend @ 2010-09-24 16:54 UTC (permalink / raw)
To: Eric Dumazet
Cc: Ben Hutchings, David Miller, netdev@vger.kernel.org,
linux-net-drivers@solarflare.com, Tom Herbert
In-Reply-To: <1285320110.2503.42.camel@edumazet-laptop>
On 9/24/2010 2:21 AM, Eric Dumazet wrote:
> Le vendredi 24 septembre 2010 à 01:15 -0700, John Fastabend a écrit :
>> On 9/23/2010 8:26 PM, Eric Dumazet wrote:
>>>
>>>> Also, I dont understand why we need to restrict
>>>> netif_set_real_num_rx_queues() to lower the count.
>>>> This wastes memory.
>>>>
>>>> Why dont we allocate dev->_rx once we know the real count, not in
>>>> alloc_netdev_mq() but in register_netdevice() ?
>>>>
>>
>> Eric,
>>
>> At least in the TX case we may not "know" until later how many
>> tx_queues we want to use. For example it could change based on
>> enabling/disabling features or available interrupts. So we use
>> num_tx_queues as the max we ever expect to use and then
>> netif_set_real_num_tx_queues() sets the number we want to use.
>>
>> I presume for rx queues there are similar cases where features and
>> available interrupts may determine how many rx queues are needed.
>>
>> Moving the allocation later could help drivers make better max number
>> of queue decisions. But, I think we still need the
>> netif_set_num_rx_queues() and netif_set_num_tx_queues(). Although this
>> does end up wasting memory as you pointed out.
>>
>
> Note I am not against having netif_set_num_rx_queues() and
> netif_set_num_tx_queues(). My patch was a cleanup, not an alternative.
>
>
> If I take a look at sysfs stuff, on a machine with a bnx2 adapter,
> single queue, I get :
>
> /sys/class/net/eth0/queues/rx-0/rps_cpus
> /sys/class/net/eth0/queues/rx-0/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-1/rps_cpus
> /sys/class/net/eth0/queues/rx-1/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-2/rps_cpus
> /sys/class/net/eth0/queues/rx-2/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-3/rps_cpus
> /sys/class/net/eth0/queues/rx-3/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-4/rps_cpus
> /sys/class/net/eth0/queues/rx-4/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-5/rps_cpus
> /sys/class/net/eth0/queues/rx-5/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-6/rps_cpus
> /sys/class/net/eth0/queues/rx-6/rps_flow_cnt
> /sys/class/net/eth0/queues/rx-7/rps_cpus
> /sys/class/net/eth0/queues/rx-7/rps_flow_cnt
>
> Thats a lot of extra memory and administrator confusion.
>
> We all agree :)
>
>
Thanks for the clarification Eric.
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Ulrich Weber @ 2010-09-24 16:40 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Ulrich Weber, David Miller, netdev
In-Reply-To: <1285344352.2503.321.camel@edumazet-laptop>
On 09/24/2010 06:05 PM, Eric Dumazet wrote:
> Le vendredi 24 septembre 2010 à 17:38 +0200, Ulrich Weber a écrit :
>> steps to reproduce:
>> server:
>> ip route add 1.0.0.0/8 dev dummy0
>>
>> client:
>> ip route add 1.0.0.0/8 dev eth0
>> nmap --min-rate 500 -sP 1.0.0.0/8
>>
>
> Great, you use nmap and fill 'client' neighbour cache.
Nope, I fills the 'server' neighbor cache too
due cached routes in arp_process():
if (arp->ar_op == htons(ARPOP_REQUEST) &&
ip_route_input_noref(skb, tip, sip, 0, dev) == 0)
> Now, back to the _real_ problem, please ?
>
> <quote>
>
> Background: At home I have two Internet connections, DSL and Cable.
> DSL is the primary uplink while Cable is the secondary.
> My Cable ISP is flooding me with ARP request from 10.0.0.0/8,
> which creates routes via the primary uplink.
> There are thousands of cached routes and after some time
> I get "Neighbour table overflow" messages.
>
> </quote>
>
> You receive an ARP request on device eth1,
> this creates a route on eth0 ?
>
> Could you send your routing/address setup ?
>
> ip addr
> ip ro
>
ARP request flood comes in via eth2.
Have to correct myself: With configuration below only route cache
increases but no "Neighbour table overflow".
By adding "ip route add 10.0.0.0/8 dev eth0" the Neighbor table overflow
will occur.
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
state UP qlen 1000
inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
state UP qlen 1000
inet 78.43.x.x/22 brd 78.43.35.255 scope global eth2
12: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc hfsc
state UNKNOWN qlen 3
inet 95.114.x.x peer 213.20.56.129/32 scope global ppp0
default via 213.20.56.129 dev ppp0
78.43.32.0/22 dev eth2 proto kernel scope link src 78.43.x.x
127.0.0.0/8 dev lo scope link
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1
213.20.56.129 dev ppp0 proto kernel scope link src 95.114.x.x
--
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany
^ permalink raw reply
* [PATCH] iwl3945: queue the right work if the scan needs to be aborted
From: Florian Mickler @ 2010-09-24 16:22 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
Cc: Florian Mickler, Reinette Chatre, Wey-Yi Guy,
Intel Linux Wireless, John W. Linville, Johannes Berg, Zhu Yi,
Ben Cahill, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
iwl3945's scan_completed calls into the mac80211 stack which triggers a
warn on if there is no scan outstanding.
This can be avoided by not calling scan_completed but abort_scan in
iwl3945_request_scan in the done: branch of the function which is used
as an error out.
The done: branch seems to be an error-out branch, as, for example, if
iwl_is_ready(priv) returns false the done: branch is executed.
NOTE:
I'm not familiar with the driver at all.
I just quickly scanned as a reaction to
https://bugzilla.kernel.org/show_bug.cgi?id=17722
the users of scan_completed in the iwl3945 driver and noted the odd
discrepancy between the comment above this instance and the comment in
mac80211 scan_completed function.
Signed-off-by: Florian Mickler <florian-sVu6HhrpSfRAfugRpC6u6w@public.gmane.org>
---
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 9dd9e64..8fd00a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
clear_bit(STATUS_SCAN_HW, &priv->status);
clear_bit(STATUS_SCANNING, &priv->status);
/* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ queue_work(priv->workqueue, &priv->abort_scan);
}
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 59a308b..d31661c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
clear_bit(STATUS_SCANNING, &priv->status);
/* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
+ queue_work(priv->workqueue, &priv->abort_scan);
}
static void iwl3945_bg_restart(struct work_struct *data)
--
1.7.3
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH net-next-2.6] net: update SOCK_MIN_RCVBUF
From: Eric Dumazet @ 2010-09-24 16:19 UTC (permalink / raw)
To: David Miller; +Cc: netdev
SOCK_MIN_RCVBUF current value is 256 bytes
It doesnt permit to receive the smallest possible frame, considering
socket sk_rmem_alloc/sk_rcvbuf account skb truesizes. On 64bit arches,
sizeof(struct sk_buff) is 240 bytes. Add the typical 64 bytes of
headroom, and we go over the limit.
With old kernels and 32bit arches, we were under the limit, if netdriver
was doing copybreak.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/sock.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 8ae97c4..c33e62c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1558,7 +1558,11 @@ static inline void sk_wake_async(struct sock *sk, int how, int band)
}
#define SOCK_MIN_SNDBUF 2048
-#define SOCK_MIN_RCVBUF 256
+/*
+ * Since sk_rmem_alloc sums skb->truesize, even a small frame might need
+ * sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak
+ */
+#define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff))
static inline void sk_stream_moderate_sndbuf(struct sock *sk)
{
^ permalink raw reply related
* Re: [PATCH] net: reset skb queue mapping when rx'ing over tunnel
From: Tom Herbert @ 2010-09-24 16:18 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, davem, chavey
In-Reply-To: <1285293960.2380.23.camel@edumazet-laptop>
> Hmm...
>
> This would need to be reverted later when tunnels are updated to be
> multiqueue aware ? I made an attempt with GRE some days ago.
>
> I dont understand why this patch is needed, since get_rps_cpu() has a
> check anyway
>
I think the skb queue_mapping should correspond to a queue in the
skb's device as an invariant. In the case that an skb's device is
change from a multiqueue device to single queue device (like GRE), the
inconsistency in the queue_mapping is fairly innocuous, we get one
warning but will pretty much take the unlikely branch for GRE packets
then on. But imagine a case where skb's device was change from one
multiqueue device to another, but the queue mapping was not also
updated. This would cause poor weighting in get_rps_cpus. For
example, if the new device had fewer queues than the old one,
get_rps_cpu will bias toward using queue 0's rps mask.
> if (skb_rx_queue_recorded(skb)) {
> u16 index = skb_get_rx_queue(skb);
> if (unlikely(index >= dev->num_rx_queues)) {
> WARN_ONCE(dev->num_rx_queues > 1, "%s received packet "
> "on queue %u, but number of RX queues is %u\n",
> dev->name, index, dev->num_rx_queues);
> goto done;
> }
> rxqueue = dev->_rx + index;
> } else
> rxqueue = dev->_rx;
>
>
>
>
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Eric Dumazet @ 2010-09-24 16:05 UTC (permalink / raw)
To: Ulrich Weber; +Cc: Ulrich Weber, David Miller, netdev
In-Reply-To: <4C9CC608.7010401@astaro.com>
Le vendredi 24 septembre 2010 à 17:38 +0200, Ulrich Weber a écrit :
> Yes, as I wrote before my Cable ISP is flooding me with
> ARP requests from 10.0.0.0/8, which get a route
> via the primary PPP link.
>
> I know thats not a common setup but why do that
> kind of routes have to be cached ? :)
>
>
> steps to reproduce:
> server:
> ip route add 1.0.0.0/8 dev dummy0
>
> client:
> ip route add 1.0.0.0/8 dev eth0
> nmap --min-rate 500 -sP 1.0.0.0/8
>
Great, you use nmap and fill 'client' neighbour cache.
Now, back to the _real_ problem, please ?
<quote>
Background: At home I have two Internet connections, DSL and Cable.
DSL is the primary uplink while Cable is the secondary.
My Cable ISP is flooding me with ARP request from 10.0.0.0/8,
which creates routes via the primary uplink.
There are thousands of cached routes and after some time
I get "Neighbour table overflow" messages.
</quote>
You receive an ARP request on device eth1,
this creates a route on eth0 ?
Could you send your routing/address setup ?
ip addr
ip ro
^ permalink raw reply
* Re: [PATCH net-next-2.6] rps: allocate rx queues in register_netdevice only
From: Tom Herbert @ 2010-09-24 15:58 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Ben Hutchings, David Miller, netdev, linux-net-drivers
In-Reply-To: <1285312049.2380.66.camel@edumazet-laptop>
On Fri, Sep 24, 2010 at 12:07 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 24 septembre 2010 à 05:26 +0200, Eric Dumazet a écrit :
>> > Also, I dont understand why we need to restrict
>> > netif_set_real_num_rx_queues() to lower the count.
>> > This wastes memory.
>> >
>> > Why dont we allocate dev->_rx once we know the real count, not in
>> > alloc_netdev_mq() but in register_netdevice() ?
>> >
>> >
>>
>> Here is a patch to make this possible
>>
>> I guess a similar thing could be done for tx queues.
>>
>> boot tested, but please double check.
>>
>> Thanks
>>
>> [PATCH net-next-2.6] rps: allocate rx queues in register_netdevice()
>>
>> Instead of having two places were we allocate dev->_rx, introduce
>> netif_alloc_rx_queues() helper and call it only from
>> register_netdevice(), not from alloc_netdev_mq()
>>
>> Goal is to let drivers change dev->num_rx_queues after allocating netdev
>> and before registering it.
>>
>> This also removes a lot of ifdefs in net/core/dev.c
>>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> ---
>> net/core/dev.c | 76 +++++++++++++++++++----------------------------
>> 1 file changed, 32 insertions(+), 44 deletions(-)
>>
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 2c7934f..9110b8d 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -4964,6 +4964,34 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev,
>> }
>> EXPORT_SYMBOL(netif_stacked_transfer_operstate);
>>
>> +static int netif_alloc_rx_queues(struct net_device *dev)
>> +{
>> +#ifdef CONFIG_RPS
>> + unsigned int i, count = dev->num_rx_queues;
>> +
>
> Tom
>
> I tried to find a caller with dev->num_rx_queues = 0, but failed
>
> If it's valid, we might add a
>
> if (!dev->num_rx_queues)
> dev->num_rx_queues = 1;
>
Or maybe just enforce that in register_net_device and make it an error
to call alloc_netdev_mq with zero queue count. You've uncovered a bug
since get_rps_cpus assumes at least one queue, but alloc_netdev_mq
allows zeros queues to be allocated!
> I wonder if you remember why you added the section :
> /*
> * Allocate a single RX queue if driver never called
> * alloc_netdev_mq
> */
RPS is configured per queue, so every device will need at least one RX
queue for the structures.
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Ulrich Weber @ 2010-09-24 15:43 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Ulrich Weber, David Miller, netdev
In-Reply-To: <1285342497.2503.260.camel@edumazet-laptop>
/proc/sys/net/ipv4/conf/all/arp_accept:0
/proc/sys/net/ipv4/conf/default/arp_accept:0
/proc/sys/net/ipv4/conf/lo/arp_accept:0
/proc/sys/net/ipv4/conf/eth0/arp_accept:0
/proc/sys/net/ipv4/conf/dummy0/arp_accept:0
On 09/24/2010 05:34 PM, Eric Dumazet wrote:
> Le vendredi 24 septembre 2010 à 17:28 +0200, Eric Dumazet a écrit :
>
>> What are the packets you receive ? A flood of ARP answers ?
>>
>> a "tcpdump -X" of a few packets would help to understand.
>>
>>
>
>
> Also please report
>
> grep . `find /proc/sys -name arp_accept`
>
>
>
--
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany
^ permalink raw reply
* Re: [RFC PATCH] dont create cached routes from ARP requests
From: Ulrich Weber @ 2010-09-24 15:38 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Ulrich Weber, David Miller, netdev
In-Reply-To: <1285342083.2503.252.camel@edumazet-laptop>
Yes, as I wrote before my Cable ISP is flooding me with
ARP requests from 10.0.0.0/8, which get a route
via the primary PPP link.
I know thats not a common setup but why do that
kind of routes have to be cached ? :)
steps to reproduce:
server:
ip route add 1.0.0.0/8 dev dummy0
client:
ip route add 1.0.0.0/8 dev eth0
nmap --min-rate 500 -sP 1.0.0.0/8
On 09/24/2010 05:28 PM, Eric Dumazet wrote:
> Le vendredi 24 septembre 2010 à 17:00 +0200, Ulrich Weber a écrit :
>> Hi Eric,
>>
>> please find the output in the attached text file.
>>
>> Neighbor garbage collection wont't work because all
>> neighbor records are bound to cached routes.
>>
>> Forced route garbaged collections returns without freeing
>> any routes, probably because the route threshold is quite high
>> with 65536 compared to the small neighbor threshold of 1024,
>> resulting in a fixed amount of 1024 cached routes...
>>
>> Instead of running the garbage collection we could flush the route
>> cache completely if the neighbor cache overflows.
>> But why do we have to cache that routes in first place ?
>> See the previous patch which skips caching for that kind of routes.
>
> What are the packets you receive ? A flood of ARP answers ?
>
> a "tcpdump -X" of a few packets would help to understand.
>
>
>
--
Ulrich Weber | uweber@astaro.com | Software Engineer
Astaro GmbH & Co. KG | www.astaro.com | Phone +49-721-25516-0 | Fax –200
An der RaumFabrik 33a | 76227 Karlsruhe | Germany
^ permalink raw reply
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