Re: [PKT_SCHED]: Add stateless NAT

2007-09-30 Thread Patrick McHardy
Herbert Xu wrote:
 On Sun, Sep 30, 2007 at 08:26:01AM +0800, Herbert Xu wrote:
 
Indeed.  The only other case I can think of is defragmentation.
But even there we should be able to squeeze it into the original
skb :)
 
 
 OK it won't be pretty but it's definitely doable.  We simply
 swap the contents of that skb with the head skb that would've
 otherwise been returned.
 
 If this is the only place in netfilter where we need to modify
 *pskb then I think it's worthwhile.
 
 So the question is are there any other places that we haven't
 covered which also needs to change *pskb?


From a quick look it seems at least IPv4 and IPv6 don't need to
change the skb anywhere else. It seems to be necessary for
bridging though to unshare the skb. OTOH br_netfilter.c already
unshares the skb for IPv4 and IPv6, so we could simply do this
unconditionally before calling the hooks.

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-29 Thread Patrick McHardy
Herbert Xu wrote:
 Herbert Xu [EMAIL PROTECTED] wrote:
 
On Fri, Sep 28, 2007 at 06:55:32PM +0200, Patrick McHardy wrote:

Looking at ip_input.o as example (everything without forced inlining):

   textdata bss dec hex filename
   2076   8   02084 824 net/ipv4/ip_input.o
   3483   8   03491 da3 net/ipv4/ip_input.o

If it's so big perhaps it should be inlined? It'll be a tail
call anyway.
 
 
 s/should be/shouldn't be/


Unfortunately gcc doesn't perform tail call optimization when the
address of a parameter or local variable is passed to an extern
function before the tail call, which NF_HOOK does for the skb.

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-29 Thread Herbert Xu
On Sat, Sep 29, 2007 at 05:21:23PM +0200, Patrick McHardy wrote:

 Unfortunately gcc doesn't perform tail call optimization when the
 address of a parameter or local variable is passed to an extern
 function before the tail call, which NF_HOOK does for the skb.

You mean the struct sk_buff **pskb bit? I've always wondered
why netfilter had to modify the skb.  Could we perhaps make it
so that it doesn't need to do so?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-29 Thread Herbert Xu
On Sun, Sep 30, 2007 at 08:26:01AM +0800, Herbert Xu wrote:

 Indeed.  The only other case I can think of is defragmentation.
 But even there we should be able to squeeze it into the original
 skb :)

OK it won't be pretty but it's definitely doable.  We simply
swap the contents of that skb with the head skb that would've
otherwise been returned.

If this is the only place in netfilter where we need to modify
*pskb then I think it's worthwhile.

So the question is are there any other places that we haven't
covered which also needs to change *pskb?

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-29 Thread David Miller
From: Patrick McHardy [EMAIL PROTECTED]
Date: Sat, 29 Sep 2007 17:21:23 +0200

 Unfortunately gcc doesn't perform tail call optimization when the
 address of a parameter or local variable is passed to an extern
 function before the tail call, which NF_HOOK does for the skb.

To which Herbert later asked why we need the **pskb thing.

The reason is that if we have to COW or resize the SKB it
could result in a realloc of the sk_buff struct which is
why we need the **pskb thing.

But strangely I can't find any skbuff.h interfaces that
require that any longer :-)))  So this might be some artifact
that we can in fact kill off.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-29 Thread Herbert Xu
On Sat, Sep 29, 2007 at 05:13:39PM -0700, David Miller wrote:
 
 The reason is that if we have to COW or resize the SKB it
 could result in a realloc of the sk_buff struct which is
 why we need the **pskb thing.
 
 But strangely I can't find any skbuff.h interfaces that
 require that any longer :-)))  So this might be some artifact
 that we can in fact kill off.

Indeed.  The only other case I can think of is defragmentation.
But even there we should be able to squeeze it into the original
skb :)

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Patrick McHardy
David Miller wrote:
 From: jamal [EMAIL PROTECTED]
 Date: Thu, 27 Sep 2007 08:39:45 -0400
 
+config NET_ACT_NAT
+tristate Stateless NAT
+depends on NET_CLS_ACT
+select NETFILTER

I am gonna have to agree with Evgeniy on this Herbert;-
The rewards are it will improve performance for people who dont need
netfilter.
 
 
 I agree that we should move the functions out.   However...
 
 You have to realize that this logic is a complete crock
 of shit for %99. of Linux users out there
 who get and only use distribution compiled kernels which are
 going to enable everything anyways.
 
 So we better make sure there are zero performance implications at some
 point just for compiling netfilter into the tree.  I know that isn't
 the case currently, but that means that we aren't helping out the
 majority of Linux users and are thus only adding these optimizations
 for such a small sliver of users and that is totally pointless and
 sucks.


The hooks themselves actually shouldn't be that much of a problem
since without any registered users they come down to a simple
list_empty check. The bigger problem is probably the fact that
the okfn is usually declared inline, but we also take its address
for nf_hook_slow, so at least with forced inlining, we end up
with one inlined and one out-of-line version.

Looking at ip_input.o as example (everything without forced inlining):

   textdata bss dec hex filename
   2076   8   02084 824 net/ipv4/ip_input.o
   3483   8   03491 da3 net/ipv4/ip_input.o


So we have roughly 1.75 more code for the two hooks. For reference,
without using the function pointer it increases a lot less:

   textdata bss dec hex filename
   2319   8   02327 917 net/ipv4/ip_input.o

similar with not inlining ip_rcv_finish() and ip_local_deliver_finish():

   textdata bss dec hex filename
   2282   8   02290 8f2 net/ipv4/ip_input.o

Any ideas how to do this better? Unforunately we need the function
pointers for reinjecting queued packets ..
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Patrick McHardy
David Miller wrote:
 I still think the nf_*() prefixes should all go and the extern
 prototypes should go into an independant header file.
 
 These are not netfilter routines, they are INET helpers.


Agreed. Evgeniy, can you send a new patch for this?

 And we should make similar treatment for all of the ipv6
 packet parser helper functions that ipv6 netfilter needs.


I'll look into that.

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 12:52:39PM -0700, David Miller ([EMAIL PROTECTED]) 
wrote:
 From: Patrick McHardy [EMAIL PROTECTED]
 Date: Thu, 27 Sep 2007 15:39:34 +0200
 
  Evgeniy Polyakov wrote:
   On Thu, Sep 27, 2007 at 09:20:37PM +0800, Herbert Xu ([EMAIL PROTECTED]) 
   wrote:
   
  How about putting it in net/core/utils.c?
   
   
   I knew, that was a bad idea to try to fix netfilter dependency :)
   
   diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
  
  
  This looks good to me.
 
 I still think the nf_*() prefixes should all go and the extern
 prototypes should go into an independant header file.
 
 These are not netfilter routines, they are INET helpers.
 
 And we should make similar treatment for all of the ipv6
 packet parser helper functions that ipv6 netfilter needs.

Should netfilter still have own nf_ prefixed functions which will just
call the same ones without prefix from inet header?

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Evgeniy Polyakov
On Fri, Sep 28, 2007 at 12:19:19PM +0400, Evgeniy Polyakov ([EMAIL PROTECTED]) 
wrote:
  I still think the nf_*() prefixes should all go and the extern
  prototypes should go into an independant header file.
  
  These are not netfilter routines, they are INET helpers.
  
  And we should make similar treatment for all of the ipv6
  packet parser helper functions that ipv6 netfilter needs.
 
 Should netfilter still have own nf_ prefixed functions which will just
 call the same ones without prefix from inet header?

Kind of.

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dd075e..befdb82 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -291,9 +291,7 @@ extern int skb_make_writable(struct sk_buff **pskb, 
unsigned int writable_len);
 
 static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
 {
-   __be32 diff[] = { ~from, to };
-
-   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
+   csum_replace(sum, from, to);
 }
 
 static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
@@ -301,13 +299,17 @@ static inline void nf_csum_replace2(__sum16 *sum, __be16 
from, __be16 to)
nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
 }
 
-extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
- __be32 from, __be32 to, int pseudohdr);
+static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   proto_csum_replace(sum, skb, (__force __be32)from,
+   (__force __be32)to, pseudohdr);
+}
 
 static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
  __be16 from, __be16 to, int pseudohdr)
 {
-   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
+   proto_csum_replace(sum, skb, (__force __be32)from,
(__force __be32)to, pseudohdr);
 }
 
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index 66ca8e3..e0561ea 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -72,8 +72,11 @@ enum nf_ip6_hook_priorities {
 
 #ifdef CONFIG_NETFILTER
 extern int ip6_route_me_harder(struct sk_buff *skb);
-extern __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
-   unsigned int dataoff, u_int8_t protocol);
+static inline __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
+   unsigned int dataoff, u_int8_t protocol)
+{
+   return ip6_checksum(skb, hook, dataoff, protocol);
+}
 
 extern int ipv6_netfilter_init(void);
 extern void ipv6_netfilter_fini(void);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a656cec..95ad5af 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1788,5 +1788,11 @@ static inline void skb_forward_csum(struct sk_buff *skb)
skb-ip_summed = CHECKSUM_NONE;
 }
 
+extern void proto_csum_replace(__sum16 *sum, struct sk_buff *skb,
+ __be32 from, __be32 to, int pseudohdr);
+
+extern __sum16 ip6_checksum(struct sk_buff *skb, unsigned int hook,
+unsigned int dataoff, u_int8_t protocol);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 1242461..8602189 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -93,4 +93,12 @@ static inline __wsum csum_unfold(__sum16 n)
 }
 
 #define CSUM_MANGLED_0 ((__force __sum16)0x)
+
+static inline void csum_replace(__sum16 *sum, __be32 from, __be32 to)
+{
+   __be32 diff[] = { ~from, to };
+
+   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
+}
+
 #endif
diff --git a/net/core/utils.c b/net/core/utils.c
index 0bf17da..17576c8 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -293,3 +293,54 @@ out:
 }
 
 EXPORT_SYMBOL(in6_pton);
+
+void proto_csum_replace(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   __be32 diff[] = { ~from, to };
+   if (skb-ip_summed != CHECKSUM_PARTIAL) {
+   *sum = csum_fold(csum_partial(diff, sizeof(diff),
+   ~csum_unfold(*sum)));
+   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
+   skb-csum = ~csum_partial(diff, sizeof(diff),
+   ~skb-csum);
+   } else if (pseudohdr)
+   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+   csum_unfold(*sum)));
+}
+EXPORT_SYMBOL(proto_csum_replace);
+
+__sum16 ip6_checksum(struct sk_buff *skb, unsigned int hook,
+unsigned int dataoff, u_int8_t protocol)
+{
+   

Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Herbert Xu
On Fri, Sep 28, 2007 at 06:55:32PM +0200, Patrick McHardy wrote:

 Looking at ip_input.o as example (everything without forced inlining):
 
textdata bss dec hex filename
2076   8   02084 824 net/ipv4/ip_input.o
3483   8   03491 da3 net/ipv4/ip_input.o

If it's so big perhaps it should be inlined? It'll be a tail
call anyway.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-28 Thread Herbert Xu
Herbert Xu [EMAIL PROTECTED] wrote:
 On Fri, Sep 28, 2007 at 06:55:32PM +0200, Patrick McHardy wrote:

 Looking at ip_input.o as example (everything without forced inlining):
 
textdata bss dec hex filename
2076   8   02084 824 net/ipv4/ip_input.o
3483   8   03491 da3 net/ipv4/ip_input.o
 
 If it's so big perhaps it should be inlined? It'll be a tail
 call anyway.

s/should be/shouldn't be/
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
Hi:

[PKT_SCHED]: Add stateless NAT

Stateless NAT is useful in controlled environments where restrictions are
placed on through traffic such that we don't need connection tracking to
correctly NAT protocol-specific data.

In particular, this is of interest when the number of flows or the number
of addresses being NATed is large, or if connection tracking information
has to be replicated and where it is not practical to do so.

Previously we had stateless NAT functionality which was integrated into
the IPv4 routing subsystem.  This was a great solution as long as the NAT
worked on a subnet to subnet basis such that the number of NAT rules was
relatively small.  The reason is that for SNAT the routing based system
had to perform a linear scan through the rules.

If the number of rules is large then major renovations would have take
place in the routing subsystem to make this practical.

For the time being, the least intrusive way of achieving this is to use
the u32 classifier written by Alexey Kuznetsov along with the actions
infrastructure implemented by Jamal Hadi Salim.

The following patch is an attempt at this problem by creating a new nat
action that can be invoked from u32 hash tables which would allow large
number of stateless NAT rules that can be used/updated in constant time.

The actual NAT code is mostly based on the previous stateless NAT code
written by Alexey.  In future we might be able to utilise the protocol
NAT code from netfilter to improve support for other protocols.

Signed-off-by: Herbert Xu [EMAIL PROTECTED]

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/linux/tc_act/tc_nat.h b/include/linux/tc_act/tc_nat.h
new file mode 100644
index 000..9280c6f
--- /dev/null
+++ b/include/linux/tc_act/tc_nat.h
@@ -0,0 +1,29 @@
+#ifndef __LINUX_TC_NAT_H
+#define __LINUX_TC_NAT_H
+
+#include linux/pkt_cls.h
+#include linux/types.h
+
+#define TCA_ACT_NAT 9
+
+enum
+{
+   TCA_NAT_UNSPEC,
+   TCA_NAT_PARMS,
+   TCA_NAT_TM,
+   __TCA_NAT_MAX
+};
+#define TCA_NAT_MAX (__TCA_NAT_MAX - 1)
+
+#define TCA_NAT_FLAG_EGRESS 1
+   
+struct tc_nat
+{
+   tc_gen;
+   __be32 old_addr;
+   __be32 new_addr;
+   __be32 mask;
+   __u32 flags;
+};
+
+#endif
diff --git a/include/net/tc_act/tc_nat.h b/include/net/tc_act/tc_nat.h
new file mode 100644
index 000..4a691f3
--- /dev/null
+++ b/include/net/tc_act/tc_nat.h
@@ -0,0 +1,21 @@
+#ifndef __NET_TC_NAT_H
+#define __NET_TC_NAT_H
+
+#include linux/types.h
+#include net/act_api.h
+
+struct tcf_nat {
+   struct tcf_common common;
+
+   __be32 old_addr;
+   __be32 new_addr;
+   __be32 mask;
+   u32 flags;
+};
+
+static inline struct tcf_nat *to_tcf_nat(struct tcf_common *pc)
+{
+   return container_of(pc, struct tcf_nat, common);
+}
+
+#endif /* __NET_TC_NAT_H */
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 8a74cac..22b34f2 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -447,6 +447,17 @@ config NET_ACT_IPT
  To compile this code as a module, choose M here: the
  module will be called ipt.
 
+config NET_ACT_NAT
+tristate Stateless NAT
+depends on NET_CLS_ACT
+select NETFILTER
+---help---
+ Say Y here to do stateless NAT on IPv4 packets.  You should use
+ netfilter for NAT unless you know what you are doing.
+
+ To compile this code as a module, choose M here: the
+ module will be called ipt.
+
 config NET_ACT_PEDIT
 tristate Packet Editing
 depends on NET_CLS_ACT
diff --git a/net/sched/Makefile b/net/sched/Makefile
index b67c36f..81ecbe8 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_NET_ACT_POLICE)  += act_police.o
 obj-$(CONFIG_NET_ACT_GACT) += act_gact.o
 obj-$(CONFIG_NET_ACT_MIRRED)   += act_mirred.o
 obj-$(CONFIG_NET_ACT_IPT)  += act_ipt.o
+obj-$(CONFIG_NET_ACT_NAT)  += act_nat.o
 obj-$(CONFIG_NET_ACT_PEDIT)+= act_pedit.o
 obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
 obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
new file mode 100644
index 000..efd6d7d
--- /dev/null
+++ b/net/sched/act_nat.c
@@ -0,0 +1,313 @@
+/*
+ * Stateless NAT actions
+ *
+ * Copyright (c) 2007 Herbert Xu [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include linux/errno.h
+#include linux/init.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/netfilter.h
+#include linux/rtnetlink.h
+#include

Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
Hi Herbert.

On Thu, Sep 27, 2007 at 03:34:47PM +0800, Herbert Xu ([EMAIL PROTECTED]) wrote:
 Hi:
 
 [PKT_SCHED]: Add stateless NAT
 
 Stateless NAT is useful in controlled environments where restrictions are
 placed on through traffic such that we don't need connection tracking to
 correctly NAT protocol-specific data.

Couple of comments below.
 --- a/net/sched/Kconfig
 +++ b/net/sched/Kconfig
 @@ -447,6 +447,17 @@ config NET_ACT_IPT
 To compile this code as a module, choose M here: the
 module will be called ipt.

 +config NET_ACT_NAT
 +tristate Stateless NAT
 +depends on NET_CLS_ACT
 +select NETFILTER

Argh... People usually do not understand such jokes :)
What about not using netfilter helpers and just move them to the
accessible header so that no additional slow path would ever be enabled?

 +---help---
 +   Say Y here to do stateless NAT on IPv4 packets.  You should use
 +   netfilter for NAT unless you know what you are doing.
 +
 +   To compile this code as a module, choose M here: the
 +   module will be called ipt.
 +

Modile will be called 'nat' I believe.

 +++ b/net/sched/act_nat.c
...
 +#define NAT_TAB_MASK 15

This really wants to be configurable at least via module parameter.

 +static struct tcf_common *tcf_nat_ht[NAT_TAB_MASK + 1];
 +static u32 nat_idx_gen;
 +static DEFINE_RWLOCK(nat_lock);

 +static struct tcf_hashinfo nat_hash_info = {
 + .htab   =   tcf_nat_ht,
 + .hmask  =   NAT_TAB_MASK,
 + .lock   =   nat_lock,
 +};

When I read this I swear I heard 'I want to be RCU'.
But that is another task.

 +static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
 +struct tcf_result *res)
 +{
 + struct tcf_nat *p = a-priv;
 + struct iphdr *iph;
 + __be32 old_addr;
 + __be32 new_addr;
 + __be32 mask;
 + __be32 addr;
 + int egress;
 + int action;
 + int ihl;
 +
 + spin_lock(p-tcf_lock);
 +
 + p-tcf_tm.lastuse = jiffies;
 + old_addr = p-old_addr;
 + new_addr = p-new_addr;
 + mask = p-mask;
 + egress = p-flags  TCA_NAT_FLAG_EGRESS;
 + action = p-tcf_action;
 +
 + p-tcf_bstats.bytes += skb-len;
 + p-tcf_bstats.packets++;
 +
 + spin_unlock(p-tcf_lock);
 +
 + if (!pskb_may_pull(skb, sizeof(*iph)))
 + return TC_ACT_SHOT;
 +
 + iph = ip_hdr(skb);
 +
 + if (egress)
 + addr = iph-saddr;
 + else
 + addr = iph-daddr;
 +
 + if (!((old_addr ^ addr)  mask)) {
 + if (skb_cloned(skb) 
 + !skb_clone_writable(skb, sizeof(*iph)) 
 + pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 + return TC_ACT_SHOT;
 +
 + new_addr = mask;
 + new_addr |= addr  ~mask;
 +
 + /* Rewrite IP header */
 + iph = ip_hdr(skb);
 + if (egress)
 + iph-saddr = new_addr;
 + else
 + iph-daddr = new_addr;
 +
 + nf_csum_replace4(iph-check, addr, new_addr);
 + }
 +
 + ihl = iph-ihl * 4;
 +
 + /* It would be nice to share code with stateful NAT. */
 + switch (iph-frag_off  htons(IP_OFFSET) ? 0 : iph-protocol) {
 + case IPPROTO_TCP:
 + {
 + struct tcphdr *tcph;
 +
 + if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) ||
 + (skb_cloned(skb) 
 +  !skb_clone_writable(skb, ihl + sizeof(*tcph)) 
 +  pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
 + return TC_ACT_SHOT;
 +
 + tcph = (void *)(skb_network_header(skb) + ihl);

Were you too lazy to write struct tcphdr here and in other places? :)


-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
On Thu, Sep 27, 2007 at 01:25:12PM +0400, Evgeniy Polyakov wrote:

 Couple of comments below.

Thanks Evgeniey :)

  --- a/net/sched/Kconfig
  +++ b/net/sched/Kconfig
  @@ -447,6 +447,17 @@ config NET_ACT_IPT
To compile this code as a module, choose M here: the
module will be called ipt.
 
  +config NET_ACT_NAT
  +tristate Stateless NAT
  +depends on NET_CLS_ACT
  +select NETFILTER
 
 Argh... People usually do not understand such jokes :)
 What about not using netfilter helpers and just move them to the
 accessible header so that no additional slow path would ever be enabled?

Sure.  However, as it is it's just including the netfilter core
which does not mean the inclusion of connection trakcing.  It's
only connection tracking that *may* (so don't flame me for this :)
pose a scalability problem.

  +---help---
  + Say Y here to do stateless NAT on IPv4 packets.  You should use
  + netfilter for NAT unless you know what you are doing.
  +
  + To compile this code as a module, choose M here: the
  + module will be called ipt.
  +
 
 Modile will be called 'nat' I believe.

Good catch, now you know where I copied it from :)

  +++ b/net/sched/act_nat.c
 ...
  +#define NAT_TAB_MASK   15
 
 This really wants to be configurable at least via module parameter.
 
  +static struct tcf_common *tcf_nat_ht[NAT_TAB_MASK + 1];
  +static u32 nat_idx_gen;
  +static DEFINE_RWLOCK(nat_lock);
 
  +static struct tcf_hashinfo nat_hash_info = {
  +   .htab   =   tcf_nat_ht,
  +   .hmask  =   NAT_TAB_MASK,
  +   .lock   =   nat_lock,
  +};
 
 When I read this I swear I heard 'I want to be RCU'.
 But that is another task.

Yes there are a lot of clean-up's that can be done for all
actions.  You're most welcome to send patches in this area.

  +   tcph = (void *)(skb_network_header(skb) + ihl);
 
 Were you too lazy to write struct tcphdr here and in other places? :)

Unfortunately it doesn't work.  For prerouting, we've not
entered the IP stack yet so the transport header isn't set.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 05:33:58PM +0800, Herbert Xu ([EMAIL PROTECTED]) wrote:
   +config NET_ACT_NAT
   +tristate Stateless NAT
   +depends on NET_CLS_ACT
   +select NETFILTER
  
  Argh... People usually do not understand such jokes :)
  What about not using netfilter helpers and just move them to the
  accessible header so that no additional slow path would ever be enabled?
 
 Sure.  However, as it is it's just including the netfilter core
 which does not mean the inclusion of connection trakcing.  It's
 only connection tracking that *may* (so don't flame me for this :)
 pose a scalability problem.

It forces all inpuit/pre/post/forward hooks to be enbled not as a direct
function call, but as additional lookups. And unability to remove
netfilter from config. And just because of couple of checksum helpers...

   +++ b/net/sched/act_nat.c
  ...
   +#define NAT_TAB_MASK 15
  
  This really wants to be configurable at least via module parameter.
  
   +static struct tcf_common *tcf_nat_ht[NAT_TAB_MASK + 1];
   +static u32 nat_idx_gen;
   +static DEFINE_RWLOCK(nat_lock);
  
   +static struct tcf_hashinfo nat_hash_info = {
   + .htab   =   tcf_nat_ht,
   + .hmask  =   NAT_TAB_MASK,
   + .lock   =   nat_lock,
   +};
  
  When I read this I swear I heard 'I want to be RCU'.
  But that is another task.
 
 Yes there are a lot of clean-up's that can be done for all
 actions.  You're most welcome to send patches in this area.
 
   + tcph = (void *)(skb_network_header(skb) + ihl);
  
  Were you too lazy to write struct tcphdr here and in other places? :)
 
 Unfortunately it doesn't work.  For prerouting, we've not
 entered the IP stack yet so the transport header isn't set.

I meant instead of dereferencing to void * it should be struct tcphdr *.

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
On Thu, Sep 27, 2007 at 02:07:53PM +0400, Evgeniy Polyakov wrote:

 It forces all inpuit/pre/post/forward hooks to be enbled not as a direct
 function call, but as additional lookups. And unability to remove
 netfilter from config. And just because of couple of checksum helpers...

I'm certainly not against patches moving that code out of
netfilter.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread jamal
On Thu, 2007-27-09 at 16:41 +0400, Evgeniy Polyakov wrote:

 I've attached simple patch which moves checksum helpers out of
 CONFIG_NETFILTER option but still in the same linux/netfilter.h header.
 This should be enough for removing 'select NETFILTER' in your patch.

Is there any point in keeping the code inside netfilter or keeping
the nf_ prefix? something in net/utilities/ or net/core maybe?
the nf_* can still exist in netfilter as aliases to wherever this is
moved to.

cheers,
jamal



-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 08:52:03AM -0400, jamal ([EMAIL PROTECTED]) wrote:
 On Thu, 2007-27-09 at 16:41 +0400, Evgeniy Polyakov wrote:
 
  I've attached simple patch which moves checksum helpers out of
  CONFIG_NETFILTER option but still in the same linux/netfilter.h header.
  This should be enough for removing 'select NETFILTER' in your patch.
 
 Is there any point in keeping the code inside netfilter or keeping
 the nf_ prefix? something in net/utilities/ or net/core maybe?
 the nf_* can still exist in netfilter as aliases to wherever this is
 moved to.

No, there is no point in keeping that, I just wanted the smallest
possible change :)

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
On Thu, Sep 27, 2007 at 08:39:45AM -0400, jamal wrote:

 Do you have plans to do the iproute bits? If you do it will be nice to
 also update the doc/examples with some simple example(s).

Oh yes, I didn't test this by poking bits in the kernel
you know :)

Here are the iproute bits.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/utils.h b/include/utils.h
index a3fd335..b0dc03e 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -36,7 +36,7 @@ extern char * _SL_;
 
 extern void incomplete_command(void) __attribute__((noreturn));
 
-#define NEXT_ARG() do { argv++; if (--argc = 0) incomplete_command(); } 
while(0)
+#define NEXT_ARG() do { argv++; if (--argc  0) incomplete_command(); } 
while(0)
 #define NEXT_ARG_OK() (argc - 1  0)
 #define PREV_ARG() do { argv--; argc++; } while(0)
 
diff --git a/tc/Makefile b/tc/Makefile
index 22cd437..cd5a69e 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -26,6 +26,7 @@ TCMODULES += q_htb.o
 TCMODULES += m_gact.o
 TCMODULES += m_mirred.o
 TCMODULES += m_ipt.o
+TCMODULES += m_nat.o
 TCMODULES += m_pedit.o
 TCMODULES += p_ip.o
 TCMODULES += p_icmp.o
diff --git a/tc/m_nat.c b/tc/m_nat.c
new file mode 100644
index 000..9a6c7da
--- /dev/null
+++ b/tc/m_nat.c
@@ -0,0 +1,208 @@
+/*
+ * m_nat.c NAT module
+ *
+ * This program is free software; you can distribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors:Herbert Xu [EMAIL PROTECTED]
+ *
+ */
+
+#include stdio.h
+#include stdlib.h
+#include unistd.h
+#include syslog.h
+#include fcntl.h
+#include sys/socket.h
+#include netinet/in.h
+#include arpa/inet.h
+#include string.h
+#include dlfcn.h
+#include utils.h
+#include tc_util.h
+#include linux/tc_act/tc_nat.h
+
+static void
+explain(void)
+{
+   fprintf(stderr, Usage: ... nat NAT\n
+   NAT := DIRECTION OLD NEW\n
+   DIRECTION := { ingress | egress }\n
+   OLD := PREFIX\n
+   NEW := ADDRESS\n);
+}
+
+static void
+usage(void)
+{
+   explain();
+   exit(-1);
+}
+
+static int
+parse_nat_args(int *argc_p, char ***argv_p,struct tc_nat *sel)
+{
+   int argc = *argc_p;
+   char **argv = *argv_p;
+   inet_prefix addr;
+
+   if (argc = 0)
+   return -1;
+
+   if (matches(*argv, egress) == 0)
+   sel-flags |= TCA_NAT_FLAG_EGRESS;
+   else if (matches(*argv, ingress) != 0)
+   goto bad_val;
+
+   NEXT_ARG();
+
+   if (get_prefix_1(addr, *argv, AF_INET))
+   goto bad_val;
+
+   sel-old_addr = addr.data[0];
+   sel-mask = htonl(~0u  (32 - addr.bitlen));
+
+   NEXT_ARG();
+
+   if (get_prefix_1(addr, *argv, AF_INET))
+   goto bad_val;
+
+   sel-new_addr = addr.data[0];
+
+   NEXT_ARG();
+
+   *argc_p = argc;
+   *argv_p = argv;
+   return 0;
+
+bad_val:
+   return -1;
+}
+
+static int
+parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, 
struct nlmsghdr *n)
+{
+   struct tc_nat sel;
+
+   int argc = *argc_p;
+   char **argv = *argv_p;
+   int ok = 0, iok = 0;
+   struct rtattr *tail;
+
+   memset(sel, 0, sizeof(sel));
+
+   while (argc  0) {
+   if (matches(*argv, nat) == 0) {
+   NEXT_ARG();
+   if (parse_nat_args(argc, argv, sel)) {
+   fprintf(stderr, Illegal nat construct (%s) \n,
+   *argv);
+   explain();
+   return -1;
+   }
+   ok++;
+   continue;
+   } else if (matches(*argv, help) == 0) {
+   usage();
+   } else {
+   break;
+   }
+
+   }
+
+   if (!ok) {
+   explain();
+   return -1;
+   }
+
+   if (argc) {
+   if (matches(*argv, reclassify) == 0) {
+   sel.action = TC_ACT_RECLASSIFY;
+   NEXT_ARG();
+   } else if (matches(*argv, pipe) == 0) {
+   sel.action = TC_ACT_PIPE;
+   NEXT_ARG();
+   } else if (matches(*argv, drop) == 0 ||
+   matches(*argv, shot) == 0) {
+   sel.action = TC_ACT_SHOT;
+   NEXT_ARG();
+   } else if (matches(*argv, continue) == 0) {
+   sel.action = TC_ACT_UNSPEC;
+   NEXT_ARG();
+   } else if 

Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
On Thu, Sep 27, 2007 at 08:39:45AM -0400, jamal wrote:

 You also need to p-tcf_qstats.drops++ for all packets that get shot.

I was rather hoping that my packets wouldn't get shot :)
But yeah let's increment the drops counter for consistency.

[PKT_SCHED]: Add stateless NAT

Stateless NAT is useful in controlled environments where restrictions are
placed on through traffic such that we don't need connection tracking to
correctly NAT protocol-specific data.

In particular, this is of interest when the number of flows or the number
of addresses being NATed is large, or if connection tracking information
has to be replicated and where it is not practical to do so.

Previously we had stateless NAT functionality which was integrated into
the IPv4 routing subsystem.  This was a great solution as long as the NAT
worked on a subnet to subnet basis such that the number of NAT rules was
relatively small.  The reason is that for SNAT the routing based system
had to perform a linear scan through the rules.

If the number of rules is large then major renovations would have take
place in the routing subsystem to make this practical.

For the time being, the least intrusive way of achieving this is to use
the u32 classifier written by Alexey Kuznetsov along with the actions
infrastructure implemented by Jamal Hadi Salim.

The following patch is an attempt at this problem by creating a new nat
action that can be invoked from u32 hash tables which would allow large
number of stateless NAT rules that can be used/updated in constant time.

The actual NAT code is mostly based on the previous stateless NAT code
written by Alexey.  In future we might be able to utilise the protocol
NAT code from netfilter to improve support for other protocols.

Signed-off-by: Herbert Xu [EMAIL PROTECTED]

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/linux/tc_act/tc_nat.h b/include/linux/tc_act/tc_nat.h
new file mode 100644
index 000..9280c6f
--- /dev/null
+++ b/include/linux/tc_act/tc_nat.h
@@ -0,0 +1,29 @@
+#ifndef __LINUX_TC_NAT_H
+#define __LINUX_TC_NAT_H
+
+#include linux/pkt_cls.h
+#include linux/types.h
+
+#define TCA_ACT_NAT 9
+
+enum
+{
+   TCA_NAT_UNSPEC,
+   TCA_NAT_PARMS,
+   TCA_NAT_TM,
+   __TCA_NAT_MAX
+};
+#define TCA_NAT_MAX (__TCA_NAT_MAX - 1)
+
+#define TCA_NAT_FLAG_EGRESS 1
+   
+struct tc_nat
+{
+   tc_gen;
+   __be32 old_addr;
+   __be32 new_addr;
+   __be32 mask;
+   __u32 flags;
+};
+
+#endif
diff --git a/include/net/tc_act/tc_nat.h b/include/net/tc_act/tc_nat.h
new file mode 100644
index 000..4a691f3
--- /dev/null
+++ b/include/net/tc_act/tc_nat.h
@@ -0,0 +1,21 @@
+#ifndef __NET_TC_NAT_H
+#define __NET_TC_NAT_H
+
+#include linux/types.h
+#include net/act_api.h
+
+struct tcf_nat {
+   struct tcf_common common;
+
+   __be32 old_addr;
+   __be32 new_addr;
+   __be32 mask;
+   u32 flags;
+};
+
+static inline struct tcf_nat *to_tcf_nat(struct tcf_common *pc)
+{
+   return container_of(pc, struct tcf_nat, common);
+}
+
+#endif /* __NET_TC_NAT_H */
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 8a74cac..92435a8 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -447,6 +447,17 @@ config NET_ACT_IPT
  To compile this code as a module, choose M here: the
  module will be called ipt.
 
+config NET_ACT_NAT
+tristate Stateless NAT
+depends on NET_CLS_ACT
+select NETFILTER
+---help---
+ Say Y here to do stateless NAT on IPv4 packets.  You should use
+ netfilter for NAT unless you know what you are doing.
+
+ To compile this code as a module, choose M here: the
+ module will be called nat.
+
 config NET_ACT_PEDIT
 tristate Packet Editing
 depends on NET_CLS_ACT
diff --git a/net/sched/Makefile b/net/sched/Makefile
index b67c36f..81ecbe8 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_NET_ACT_POLICE)  += act_police.o
 obj-$(CONFIG_NET_ACT_GACT) += act_gact.o
 obj-$(CONFIG_NET_ACT_MIRRED)   += act_mirred.o
 obj-$(CONFIG_NET_ACT_IPT)  += act_ipt.o
+obj-$(CONFIG_NET_ACT_NAT)  += act_nat.o
 obj-$(CONFIG_NET_ACT_PEDIT)+= act_pedit.o
 obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
 obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
new file mode 100644
index 000..1bce750
--- /dev/null
+++ b/net/sched/act_nat.c
@@ -0,0 +1,322 @@
+/*
+ * Stateless NAT actions
+ *
+ * Copyright (c) 2007 Herbert Xu [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either

Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 08:45:15PM +0800, Herbert Xu ([EMAIL PROTECTED]) wrote:
 On Thu, Sep 27, 2007 at 04:41:21PM +0400, Evgeniy Polyakov wrote:
 
  I've attached simple patch which moves checksum helpers out of
  CONFIG_NETFILTER option but still in the same linux/netfilter.h header.
  This should be enough for removing 'select NETFILTER' in your patch.
 
 Close but no cigar :)

:) take 2.

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dd075e..5313739 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -40,6 +40,41 @@
 #endif
 
 #ifdef __KERNEL__
+
+static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+{
+   __be32 diff[] = { ~from, to };
+
+   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
+}
+
+static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
+
+static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   __be32 diff[] = { ~from, to };
+   if (skb-ip_summed != CHECKSUM_PARTIAL) {
+   *sum = csum_fold(csum_partial(diff, sizeof(diff),
+   ~csum_unfold(*sum)));
+   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
+   skb-csum = ~csum_partial(diff, sizeof(diff),
+   ~skb-csum);
+   } else if (pseudohdr)
+   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+   csum_unfold(*sum)));
+}
+
+static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+ __be16 from, __be16 to, int pseudohdr)
+{
+   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
+   (__force __be32)to, pseudohdr);
+}
+
 #ifdef CONFIG_NETFILTER
 
 extern void netfilter_init(void);
@@ -289,28 +324,6 @@ extern void nf_invalidate_cache(int pf);
Returns true or false. */
 extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
 
-static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
-{
-   __be32 diff[] = { ~from, to };
-
-   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
-}
-
-static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
-{
-   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
-}
-
-extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
- __be32 from, __be32 to, int pseudohdr);
-
-static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
- __be16 from, __be16 to, int pseudohdr)
-{
-   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
-   (__force __be32)to, pseudohdr);
-}
-
 struct nf_afinfo {
unsigned short  family;
__sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 381a77c..9ffbbe2 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -226,22 +226,6 @@ copy_skb:
 }
 EXPORT_SYMBOL(skb_make_writable);
 
-void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
-   __be32 from, __be32 to, int pseudohdr)
-{
-   __be32 diff[] = { ~from, to };
-   if (skb-ip_summed != CHECKSUM_PARTIAL) {
-   *sum = csum_fold(csum_partial(diff, sizeof(diff),
-   ~csum_unfold(*sum)));
-   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
-   skb-csum = ~csum_partial(diff, sizeof(diff),
-   ~skb-csum);
-   } else if (pseudohdr)
-   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
-   csum_unfold(*sum)));
-}
-EXPORT_SYMBOL(nf_proto_csum_replace4);
-
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 /* This does not belong here, but locally generated errors need it if 
connection
tracking in use: without this, connection may not be in hash table, and 
hence

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread jamal
On Thu, 2007-27-09 at 21:01 +0800, Herbert Xu wrote:
 On Thu, Sep 27, 2007 at 08:39:45AM -0400, jamal wrote:
 
  Do you have plans to do the iproute bits? If you do it will be nice to
  also update the doc/examples with some simple example(s).
 
 Oh yes, I didn't test this by poking bits in the kernel
 you know :)

Trust me - it has been done before ;-

Thanks Herbert, looks good to me. 

cheers,
jamal


-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Patrick McHardy
Evgeniy Polyakov wrote:
 +static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
 +{
 + __be32 diff[] = { ~from, to };
 +
 + *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
 ~csum_unfold(*sum)));
 +}
 +
 +static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
 +{
 + nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
 +}
 +
 +static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 + __be32 from, __be32 to, int pseudohdr)
 +{
 + __be32 diff[] = { ~from, to };
 + if (skb-ip_summed != CHECKSUM_PARTIAL) {
 + *sum = csum_fold(csum_partial(diff, sizeof(diff),
 + ~csum_unfold(*sum)));
 + if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
 + skb-csum = ~csum_partial(diff, sizeof(diff),
 + ~skb-csum);
 + } else if (pseudohdr)
 + *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
 + csum_unfold(*sum)));
 +}
 +
 +static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
 +   __be16 from, __be16 to, int pseudohdr)
 +{
 + nf_proto_csum_replace4(sum, skb, (__force __be32)from,
 + (__force __be32)to, pseudohdr);
 +}


These are way too large to get inlined, please move somewhere below
net/core.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Herbert Xu
On Thu, Sep 27, 2007 at 05:10:08PM +0400, Evgeniy Polyakov wrote:

 +static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
 + __be32 from, __be32 to, int pseudohdr)
 +{
 + __be32 diff[] = { ~from, to };
 + if (skb-ip_summed != CHECKSUM_PARTIAL) {
 + *sum = csum_fold(csum_partial(diff, sizeof(diff),
 + ~csum_unfold(*sum)));
 + if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
 + skb-csum = ~csum_partial(diff, sizeof(diff),
 + ~skb-csum);
 + } else if (pseudohdr)
 + *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
 + csum_unfold(*sum)));
 +}

The embedded people are going to hate you for this :)

How about putting it in net/core/utils.c?

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 03:16:48PM +0200, Patrick McHardy ([EMAIL PROTECTED]) 
wrote:
 Evgeniy Polyakov wrote:
  +static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff 
  *skb,
  +   __be32 from, __be32 to, int pseudohdr)
  +{
  +   __be32 diff[] = { ~from, to };
  +   if (skb-ip_summed != CHECKSUM_PARTIAL) {
  +   *sum = csum_fold(csum_partial(diff, sizeof(diff),
  +   ~csum_unfold(*sum)));
  +   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
  +   skb-csum = ~csum_partial(diff, sizeof(diff),
  +   ~skb-csum);
  +   } else if (pseudohdr)
  +   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
  +   csum_unfold(*sum)));
  +}
  +
  +static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff 
  *skb,
  + __be16 from, __be16 to, int pseudohdr)
  +{
  +   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
  +   (__force __be32)to, pseudohdr);
  +}
 
 
 These are way too large to get inlined, please move somewhere below
 net/core.

I knew that... :)
I'm pretty sure new files called net/core/helpers.c which will host that
helper is not a good solution too?

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dd075e..624d78b 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -40,6 +40,29 @@
 #endif
 
 #ifdef __KERNEL__
+
+static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+{
+   __be32 diff[] = { ~from, to };
+
+   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
+}
+
+static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
+
+extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr);
+
+static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+ __be16 from, __be16 to, int pseudohdr)
+{
+   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
+   (__force __be32)to, pseudohdr);
+}
+
 #ifdef CONFIG_NETFILTER
 
 extern void netfilter_init(void);
@@ -289,28 +312,6 @@ extern void nf_invalidate_cache(int pf);
Returns true or false. */
 extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
 
-static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
-{
-   __be32 diff[] = { ~from, to };
-
-   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
-}
-
-static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
-{
-   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
-}
-
-extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
- __be32 from, __be32 to, int pseudohdr);
-
-static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
- __be16 from, __be16 to, int pseudohdr)
-{
-   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
-   (__force __be32)to, pseudohdr);
-}
-
 struct nf_afinfo {
unsigned short  family;
__sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
diff --git a/net/core/Makefile b/net/core/Makefile
index 4751613..5757323 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
-gen_stats.o gen_estimator.o
+gen_stats.o gen_estimator.o helpers.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
diff --git a/net/core/helpers.c b/net/core/helpers.c
new file mode 100644
index 000..d3c8d97
--- /dev/null
+++ b/net/core/helpers.c
@@ -0,0 +1,23 @@
+/*
+ * Generic helper functions.
+ */
+
+#include linux/types.h
+#include linux/skbuff.h
+
+#include net/checksum.h
+
+void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   __be32 diff[] = { ~from, to };
+   if (skb-ip_summed != CHECKSUM_PARTIAL) {
+   *sum = csum_fold(csum_partial(diff, sizeof(diff),
+   ~csum_unfold(*sum)));
+   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
+   skb-csum = ~csum_partial(diff, sizeof(diff),
+   ~skb-csum);
+   } else if (pseudohdr)
+   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+   csum_unfold(*sum)));
+}
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 381a77c..9ffbbe2 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -226,22 +226,6 @@ copy_skb:
 }
 

Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 09:20:37PM +0800, Herbert Xu ([EMAIL PROTECTED]) wrote:
 How about putting it in net/core/utils.c?

I knew, that was a bad idea to try to fix netfilter dependency :)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 1dd075e..51b5a22 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -40,6 +40,35 @@
 #endif
 
 #ifdef __KERNEL__
+
+static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+{
+   __be32 diff[] = { ~from, to };
+
+   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
+}
+
+static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
+
+extern void proto_csum_replace(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr);
+
+static inline void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   proto_csum_replace(sum, skb, from, to, pseudohdr);
+}
+
+static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+ __be16 from, __be16 to, int pseudohdr)
+{
+   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
+   (__force __be32)to, pseudohdr);
+}
+
 #ifdef CONFIG_NETFILTER
 
 extern void netfilter_init(void);
@@ -289,28 +318,6 @@ extern void nf_invalidate_cache(int pf);
Returns true or false. */
 extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
 
-static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
-{
-   __be32 diff[] = { ~from, to };
-
-   *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 
~csum_unfold(*sum)));
-}
-
-static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
-{
-   nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
-}
-
-extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
- __be32 from, __be32 to, int pseudohdr);
-
-static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
- __be16 from, __be16 to, int pseudohdr)
-{
-   nf_proto_csum_replace4(sum, skb, (__force __be32)from,
-   (__force __be32)to, pseudohdr);
-}
-
 struct nf_afinfo {
unsigned short  family;
__sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
diff --git a/net/core/utils.c b/net/core/utils.c
index 0bf17da..2f6d4d2 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -293,3 +293,20 @@ out:
 }
 
 EXPORT_SYMBOL(in6_pton);
+
+void proto_csum_replace(__sum16 *sum, struct sk_buff *skb,
+   __be32 from, __be32 to, int pseudohdr)
+{
+   __be32 diff[] = { ~from, to };
+   if (skb-ip_summed != CHECKSUM_PARTIAL) {
+   *sum = csum_fold(csum_partial(diff, sizeof(diff),
+   ~csum_unfold(*sum)));
+   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
+   skb-csum = ~csum_partial(diff, sizeof(diff),
+   ~skb-csum);
+   } else if (pseudohdr)
+   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+   csum_unfold(*sum)));
+}
+
+EXPORT_SYMBOL(proto_csum_replace);
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 381a77c..9ffbbe2 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -226,22 +226,6 @@ copy_skb:
 }
 EXPORT_SYMBOL(skb_make_writable);
 
-void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
-   __be32 from, __be32 to, int pseudohdr)
-{
-   __be32 diff[] = { ~from, to };
-   if (skb-ip_summed != CHECKSUM_PARTIAL) {
-   *sum = csum_fold(csum_partial(diff, sizeof(diff),
-   ~csum_unfold(*sum)));
-   if (skb-ip_summed == CHECKSUM_COMPLETE  pseudohdr)
-   skb-csum = ~csum_partial(diff, sizeof(diff),
-   ~skb-csum);
-   } else if (pseudohdr)
-   *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
-   csum_unfold(*sum)));
-}
-EXPORT_SYMBOL(nf_proto_csum_replace4);
-
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 /* This does not belong here, but locally generated errors need it if 
connection
tracking in use: without this, connection may not be in hash table, and 
hence

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Patrick McHardy
Evgeniy Polyakov wrote:
 On Thu, Sep 27, 2007 at 03:16:48PM +0200, Patrick McHardy ([EMAIL PROTECTED]) 
 wrote:
 

These are way too large to get inlined, please move somewhere below
net/core.
 
 
 I knew that... :)
 I'm pretty sure new files called net/core/helpers.c which will host that
 helper is not a good solution too?


I like Herbert's suggestion of net/core/utils.c better (and without the
nf_ prefix please).
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Evgeniy Polyakov
On Thu, Sep 27, 2007 at 03:30:12PM +0200, Patrick McHardy ([EMAIL PROTECTED]) 
wrote:
 Evgeniy Polyakov wrote:
  On Thu, Sep 27, 2007 at 03:16:48PM +0200, Patrick McHardy ([EMAIL 
  PROTECTED]) wrote:
  
 
 These are way too large to get inlined, please move somewhere below
 net/core.
  
  
  I knew that... :)
  I'm pretty sure new files called net/core/helpers.c which will host that
  helper is not a good solution too?
 
 
 I like Herbert's suggestion of net/core/utils.c better (and without the
 nf_ prefix please).

I've put it there without nf_ prefix and updated netfilter header to
create new inlune function with that prefix for private netfilter usage.

-- 
Evgeniy Polyakov
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread jamal
On Thu, 2007-27-09 at 15:30 +0200, Patrick McHardy wrote:

 
 I like Herbert's suggestion of net/core/utils.c better (and without the
 nf_ prefix please).

me too. Evgeniy, you are the man if you finish the whole cow as some
wise Africans would say;-

cheers,
jamal 

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread Patrick McHardy
Evgeniy Polyakov wrote:
 On Thu, Sep 27, 2007 at 09:20:37PM +0800, Herbert Xu ([EMAIL PROTECTED]) 
 wrote:
 
How about putting it in net/core/utils.c?
 
 
 I knew, that was a bad idea to try to fix netfilter dependency :)
 
 diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h


This looks good to me.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread David Miller
From: jamal [EMAIL PROTECTED]
Date: Thu, 27 Sep 2007 08:39:45 -0400

 nice work. I like the egress flag idea;-
 and who would have thunk stateless nat could be written in such a few
 lines ;- I would have put the checksum as a separate action but it is
 fine the way you did it since it simplifies config.
 more comments below.
 
 On Thu, 2007-27-09 at 15:34 +0800, Herbert Xu wrote:
 
  +config NET_ACT_NAT
  +tristate Stateless NAT
  +depends on NET_CLS_ACT
  +select NETFILTER
 
 I am gonna have to agree with Evgeniy on this Herbert;-
 The rewards are it will improve performance for people who dont need
 netfilter.
 Ok, who is gonna move the csum utility functions out? /me looks at
 Evgeniy;-
 I could do it realsoonnow if noone raises their hands. 
 In any case, it would be real nice to have but i dont see it as a show
 stopper for inclusion.

I agree that we should move the functions out.   However...

You have to realize that this logic is a complete crock
of shit for %99. of Linux users out there
who get and only use distribution compiled kernels which are
going to enable everything anyways.

So we better make sure there are zero performance implications at some
point just for compiling netfilter into the tree.  I know that isn't
the case currently, but that means that we aren't helping out the
majority of Linux users and are thus only adding these optimizations
for such a small sliver of users and that is totally pointless and
sucks.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread David Miller
From: Herbert Xu [EMAIL PROTECTED]
Date: Thu, 27 Sep 2007 20:58:01 +0800

 On Thu, Sep 27, 2007 at 08:39:45AM -0400, jamal wrote:
 
  You also need to p-tcf_qstats.drops++ for all packets that get shot.
 
 I was rather hoping that my packets wouldn't get shot :)
 But yeah let's increment the drops counter for consistency.
 
 [PKT_SCHED]: Add stateless NAT

Applied to net-2.6.24, thanks Herbert!
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PKT_SCHED]: Add stateless NAT

2007-09-27 Thread David Miller
From: Patrick McHardy [EMAIL PROTECTED]
Date: Thu, 27 Sep 2007 15:39:34 +0200

 Evgeniy Polyakov wrote:
  On Thu, Sep 27, 2007 at 09:20:37PM +0800, Herbert Xu ([EMAIL PROTECTED]) 
  wrote:
  
 How about putting it in net/core/utils.c?
  
  
  I knew, that was a bad idea to try to fix netfilter dependency :)
  
  diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
 
 
 This looks good to me.

I still think the nf_*() prefixes should all go and the extern
prototypes should go into an independant header file.

These are not netfilter routines, they are INET helpers.

And we should make similar treatment for all of the ipv6
packet parser helper functions that ipv6 netfilter needs.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html