* Re: [Patch] 2.4.32 - Neighbour Cache (ARP) State machine bug Fixed
From: Bill Davidsen @ 2006-02-10 20:35 UTC (permalink / raw)
To: gcoady; +Cc: netdev, linux-kernel
In-Reply-To: <4skiu150r13a2a78i68bg28cvdb67a8qjb@4ax.com>
Grant Coady wrote:
> On Tue, 7 Feb 2006 17:50:03 -0800, Pradeep Vincent <pradeep.vincent@gmail.com> wrote:
>
>
>>One more attempt. Attaching the diff file as well.
>>
>>Signed off by: Pradeep Vincent <pradeep.vincent@gmail.com>
>>
>>--- old/net/core/neighbour.c Wed Nov 9 16:48:10 2005
>>+++ new/net/core/neighbour.c Tue Feb 7 17:38:26 2006
>>@@ -14,6 +14,7 @@
>> * Vitaly E. Lavrov releasing NULL neighbor in neigh_add.
>> * Harald Welte Add neighbour cache statistics like rtstat
>> * Harald Welte port neighbour cache rework from 2.6.9-rcX
>>+ * Pradeep Vincent fix neighbour cache state machine
>> */
>>
>>#include <linux/config.h>
>>@@ -705,6 +706,13 @@
>> neigh_release(n);
>> continue;
>> }
>>+ /* Move to NUD_STALE state */
>>+ if (n->nud_state&NUD_REACHABLE &&
>>+ now - n->confirmed > n->parms->reachable_time) {
>
>
> Hmm, you're suffering tab -> space conversion syndrome :(
>
> Grant.
The attachment has tabs here, don't know what you're seeing.
--
bill davidsen <davidsen@tmr.com>
CTO TMR Associates, Inc
Doing interesting things with small computers since 1979
^ permalink raw reply
* [PATCH] ACX: Delete .owner field in usb.c
From: Carlos Martín @ 2006-02-10 21:46 UTC (permalink / raw)
To: acx100-devel; +Cc: netdev
diff-tree e0f5be38b5dea8bbfc486edbf9d88d5ee94941d9 (from
29292af943e12ace0115497616569f0629ed1cd7)
Author: Carlos <carlos@pepe.(none)>
Date: Fri Feb 10 21:02:39 2006 +0000
Delete .owner field in usb.c
It's no longer there. We already deleted it. Andi, I'm looking at you...
diff --git a/usb.c b/usb.c
index 45a95dd..1e64b15 100644
--- a/usb.c
+++ b/usb.c
@@ -155,7 +155,6 @@ MODULE_DEVICE_TABLE(usb, acxusb_ids);
/* USB driver data structure as required by the kernel's USB core */
static struct usb_driver
acxusb_driver = {
- .owner = THIS_MODULE,
.name = "acx_usb",
.probe = acxusb_e_probe,
.disconnect = acxusb_e_disconnect,
--
Carlos Martín Nieto | http://www.cmartin.tk
Hobbyist programmer |
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid\x103432&bid#0486&dat\x121642
^ permalink raw reply related
* [PATCH] IPv6: Cleanups for net/ipv6/addrconf.c (kzalloc, early exit) v2
From: Ingo Oeser @ 2006-02-11 16:37 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明; +Cc: linux-kernel, netdev
In-Reply-To: <20060210.014853.13643277.yoshfuji@linux-ipv6.org>
From: Ingo Oeser <ioe-lkml@rameria.de>
Here are some possible (and trivial) cleanups.
- use kzalloc() where possible
- remove unused label
- invert allocation failure test like
if (object) {
/* Rest of function here */
}
to
if (object == NULL)
return NULL;
/* Rest of function here */
The last one moves quite some code, because it changes indention.
I can split that up, if needed.
Signed-off-by: Ingo Oeser <ioe-lkml@rameria.de>
---
Hello,
On Thursday 09 February 2006 17:48, YOSHIFUJI Hideaki wrote:
> Please keep nlmsg_failure, which is used by NLMSG_NEW().
This issue has been adressed now.
Patch is against latest git from Linus. It has been compile tested with
allyesconfig on ix86.
Many thanks for your patience!
Regards
Ingo Oeer
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b7d8822..984a9bc 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -327,86 +327,85 @@ static struct inet6_dev * ipv6_add_dev(s
if (dev->mtu < IPV6_MIN_MTU)
return NULL;
- ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL);
+ ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
- if (ndev) {
- memset(ndev, 0, sizeof(struct inet6_dev));
+ if (ndev == NULL)
+ return NULL;
- rwlock_init(&ndev->lock);
- ndev->dev = dev;
- memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
- ndev->cnf.mtu6 = dev->mtu;
- ndev->cnf.sysctl = NULL;
- ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
- if (ndev->nd_parms == NULL) {
- kfree(ndev);
- return NULL;
- }
- /* We refer to the device */
- dev_hold(dev);
+ rwlock_init(&ndev->lock);
+ ndev->dev = dev;
+ memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
+ ndev->cnf.mtu6 = dev->mtu;
+ ndev->cnf.sysctl = NULL;
+ ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
+ if (ndev->nd_parms == NULL) {
+ kfree(ndev);
+ return NULL;
+ }
+ /* We refer to the device */
+ dev_hold(dev);
- if (snmp6_alloc_dev(ndev) < 0) {
- ADBG((KERN_WARNING
- "%s(): cannot allocate memory for statistics; dev=%s.\n",
- __FUNCTION__, dev->name));
- neigh_parms_release(&nd_tbl, ndev->nd_parms);
- ndev->dead = 1;
- in6_dev_finish_destroy(ndev);
- return NULL;
- }
+ if (snmp6_alloc_dev(ndev) < 0) {
+ ADBG((KERN_WARNING
+ "%s(): cannot allocate memory for statistics; dev=%s.\n",
+ __FUNCTION__, dev->name));
+ neigh_parms_release(&nd_tbl, ndev->nd_parms);
+ ndev->dead = 1;
+ in6_dev_finish_destroy(ndev);
+ return NULL;
+ }
- if (snmp6_register_dev(ndev) < 0) {
- ADBG((KERN_WARNING
- "%s(): cannot create /proc/net/dev_snmp6/%s\n",
- __FUNCTION__, dev->name));
- neigh_parms_release(&nd_tbl, ndev->nd_parms);
- ndev->dead = 1;
- in6_dev_finish_destroy(ndev);
- return NULL;
- }
+ if (snmp6_register_dev(ndev) < 0) {
+ ADBG((KERN_WARNING
+ "%s(): cannot create /proc/net/dev_snmp6/%s\n",
+ __FUNCTION__, dev->name));
+ neigh_parms_release(&nd_tbl, ndev->nd_parms);
+ ndev->dead = 1;
+ in6_dev_finish_destroy(ndev);
+ return NULL;
+ }
- /* One reference from device. We must do this before
- * we invoke __ipv6_regen_rndid().
- */
- in6_dev_hold(ndev);
+ /* One reference from device. We must do this before
+ * we invoke __ipv6_regen_rndid().
+ */
+ in6_dev_hold(ndev);
#ifdef CONFIG_IPV6_PRIVACY
- get_random_bytes(ndev->rndid, sizeof(ndev->rndid));
- get_random_bytes(ndev->entropy, sizeof(ndev->entropy));
- init_timer(&ndev->regen_timer);
- ndev->regen_timer.function = ipv6_regen_rndid;
- ndev->regen_timer.data = (unsigned long) ndev;
- if ((dev->flags&IFF_LOOPBACK) ||
- dev->type == ARPHRD_TUNNEL ||
- dev->type == ARPHRD_NONE ||
- dev->type == ARPHRD_SIT) {
- printk(KERN_INFO
- "%s: Disabled Privacy Extensions\n",
- dev->name);
- ndev->cnf.use_tempaddr = -1;
- } else {
- in6_dev_hold(ndev);
- ipv6_regen_rndid((unsigned long) ndev);
- }
+ get_random_bytes(ndev->rndid, sizeof(ndev->rndid));
+ get_random_bytes(ndev->entropy, sizeof(ndev->entropy));
+ init_timer(&ndev->regen_timer);
+ ndev->regen_timer.function = ipv6_regen_rndid;
+ ndev->regen_timer.data = (unsigned long) ndev;
+ if ((dev->flags&IFF_LOOPBACK) ||
+ dev->type == ARPHRD_TUNNEL ||
+ dev->type == ARPHRD_NONE ||
+ dev->type == ARPHRD_SIT) {
+ printk(KERN_INFO
+ "%s: Disabled Privacy Extensions\n",
+ dev->name);
+ ndev->cnf.use_tempaddr = -1;
+ } else {
+ in6_dev_hold(ndev);
+ ipv6_regen_rndid((unsigned long) ndev);
+ }
#endif
- if (netif_carrier_ok(dev))
- ndev->if_flags |= IF_READY;
+ if (netif_carrier_ok(dev))
+ ndev->if_flags |= IF_READY;
- write_lock_bh(&addrconf_lock);
- dev->ip6_ptr = ndev;
- write_unlock_bh(&addrconf_lock);
+ write_lock_bh(&addrconf_lock);
+ dev->ip6_ptr = ndev;
+ write_unlock_bh(&addrconf_lock);
- ipv6_mc_init_dev(ndev);
- ndev->tstamp = jiffies;
+ ipv6_mc_init_dev(ndev);
+ ndev->tstamp = jiffies;
#ifdef CONFIG_SYSCTL
- neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6,
- NET_IPV6_NEIGH, "ipv6",
- &ndisc_ifinfo_sysctl_change,
- NULL);
- addrconf_sysctl_register(ndev, &ndev->cnf);
+ neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6,
+ NET_IPV6_NEIGH, "ipv6",
+ &ndisc_ifinfo_sysctl_change,
+ NULL);
+ addrconf_sysctl_register(ndev, &ndev->cnf);
#endif
- }
return ndev;
}
@@ -524,7 +523,7 @@ ipv6_add_addr(struct inet6_dev *idev, co
goto out;
}
- ifa = kmalloc(sizeof(struct inet6_ifaddr), GFP_ATOMIC);
+ ifa = kzalloc(sizeof(struct inet6_ifaddr), GFP_ATOMIC);
if (ifa == NULL) {
ADBG(("ipv6_add_addr: malloc failed\n"));
@@ -538,7 +537,6 @@ ipv6_add_addr(struct inet6_dev *idev, co
goto out;
}
- memset(ifa, 0, sizeof(struct inet6_ifaddr));
ipv6_addr_copy(&ifa->addr, addr);
spin_lock_init(&ifa->lock);
@@ -2668,11 +2666,10 @@ static int if6_seq_open(struct inode *in
{
struct seq_file *seq;
int rc = -ENOMEM;
- struct if6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ struct if6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
goto out;
- memset(s, 0, sizeof(*s));
rc = seq_open(file, &if6_seq_ops);
if (rc)
^ permalink raw reply related
* Re: [PATCH] IPv6: Cleanups for net/ipv6/addrconf.c (kzalloc, early exit) v2
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-02-11 17:11 UTC (permalink / raw)
To: davem; +Cc: ioe-lkml, linux-kernel, netdev, yoshfuji
In-Reply-To: <200602111737.20010.ioe-lkml@rameria.de>
Hello.
In article <200602111737.20010.ioe-lkml@rameria.de> (at Sat, 11 Feb 2006 17:37:18 +0100), Ingo Oeser <ioe-lkml@rameria.de> says:
> From: Ingo Oeser <ioe-lkml@rameria.de>
>
> Here are some possible (and trivial) cleanups.
> - use kzalloc() where possible
> - remove unused label
> - invert allocation failure test like
:
> Signed-off-by: Ingo Oeser <ioe-lkml@rameria.de>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
--yoshfuji
^ permalink raw reply
* [RFC: 2.6 patch] CONFIG_FORCEDETH updates
From: Adrian Bunk @ 2006-02-12 17:52 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linux-kernel
This patch contains the following possible updates:
- let FORCEDETH no longer depend on EXPERIMENTAL
- remove the "Reverse Engineered" from the option text:
for the user it's important which hardware the driver supports, not
how it was developed
Signed-off-by: Adrian Bunk <bunk@stusta.de>
--- linux-2.6.16-rc2-mm1-full/drivers/net/Kconfig.old 2006-02-12 02:23:31.000000000 +0100
+++ linux-2.6.16-rc2-mm1-full/drivers/net/Kconfig 2006-02-12 02:24:04.000000000 +0100
@@ -1370,10 +1370,10 @@
<file:Documentation/networking/net-modules.txt>. The module will be
called b44.
config FORCEDETH
- tristate "Reverse Engineered nForce Ethernet support (EXPERIMENTAL)"
- depends on NET_PCI && PCI && EXPERIMENTAL
+ tristate "nForce Ethernet support"
+ depends on NET_PCI && PCI
help
If you have a network (Ethernet) controller of this type, say Y and
read the Ethernet-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
^ permalink raw reply
* [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: Harald Welte @ 2006-02-12 17:56 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 25127 bytes --]
Hi Dave!
This is net-2.6.17 stuff, please apply.
Thanks!
[NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
This patch moves all helper related data fields of 'struct nf_conn' into a
separate structure 'struct nf_conn_help'. This new structure is only
present in conntrack entries for which we actually have a helper loaded.
Also, this patch cleans up the nf_conntrack 'features' mechanism to
resemble what the original idea was: Just glue the feature-specific
data structures at the end of 'struct nf_conn', and explicitly re-calculate
the pointer to it when needed rather than keeping pointers around.
Saves 20 bytes per conntrack on my x86_64 box. A non-helped conntrack is
276 bytes. We still need to save another 20 bytes in order to fit into to
target of 256bytes.
Signed-off-by: Harald Welte <laforge@netfilter.org>
---
commit aba8cf3ac5b60e10eb1ce9f30b6bb4c007ab9868
tree 758aedbe80b8306c1991a05c47eab8905d33a13b
parent 94d3d40c84672b74e59ea5252f61602610e1513e
author Harald Welte <laforge@netfilter.org> Sun, 29 Jan 2006 19:19:06 +0100
committer Harald Welte <laforge@netfilter.org> Sun, 29 Jan 2006 19:19:06 +0100
include/net/netfilter/nf_conntrack.h | 56 +++++++----
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 22 ++---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 39 +++++---
net/netfilter/nf_conntrack_core.c | 117 ++++++++++--------------
net/netfilter/nf_conntrack_ftp.c | 2
net/netfilter/nf_conntrack_netlink.c | 39 +++++---
net/netfilter/nf_conntrack_standalone.c | 1
net/netfilter/xt_helper.c | 8 +-
8 files changed, 147 insertions(+), 137 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 6d075ca..9d1f0e6 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -67,6 +67,18 @@ do { \
struct nf_conntrack_helper;
+/* nf_conn feature for connections that have a helper */
+struct nf_conn_help {
+ /* Helper. if any */
+ struct nf_conntrack_helper *helper;
+
+ union nf_conntrack_help help;
+
+ /* Current number of expected connections */
+ unsigned int expecting;
+};
+
+
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
struct nf_conn
{
@@ -81,6 +93,9 @@ struct nf_conn
/* Have we seen traffic both ways yet? (bitset) */
unsigned long status;
+ /* If we were expected by an expectation, this will be it */
+ struct nf_conn *master;
+
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
@@ -88,38 +103,22 @@ struct nf_conn
/* Accounting Information (same cache line as other written members) */
struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
#endif
- /* If we were expected by an expectation, this will be it */
- struct nf_conn *master;
-
- /* Current number of expected connections */
- unsigned int expecting;
/* Unique ID that identifies this conntrack*/
unsigned int id;
- /* Helper. if any */
- struct nf_conntrack_helper *helper;
-
/* features - nat, helper, ... used by allocating system */
u_int32_t features;
- /* Storage reserved for other modules: */
-
- union nf_conntrack_proto proto;
-
#if defined(CONFIG_NF_CONNTRACK_MARK)
u_int32_t mark;
#endif
- /* These members are dynamically allocated. */
-
- union nf_conntrack_help *help;
+ /* Storage reserved for other modules: */
+ union nf_conntrack_proto proto;
- /* Layer 3 dependent members. (ex: NAT) */
- union {
- struct nf_conntrack_ipv4 *ipv4;
- } l3proto;
- void *data[0];
+ /* features dynamically at the end: helper, nat (both optional) */
+ char data[0];
};
struct nf_conntrack_expect
@@ -373,10 +372,23 @@ nf_conntrack_expect_event(enum ip_conntr
#define NF_CT_F_NUM 4
extern int
-nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
- int (*init_conntrack)(struct nf_conn *, u_int32_t));
+nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
extern void
nf_conntrack_unregister_cache(u_int32_t features);
+/* valid combinations:
+ * basic: nf_conn, nf_conn .. nf_conn_help
+ * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help
+ */
+static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+{
+ unsigned int offset = sizeof(struct nf_conn);
+
+ if (!(ct->features & NF_CT_F_HELP))
+ return NULL;
+
+ return (struct nf_conn_help *) ((void *)ct + offset);
+}
+
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_H */
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 167619f..e52b50b 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -141,19 +141,21 @@ static unsigned int ipv4_conntrack_help(
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
+ struct nf_conn_help *help;
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
- if (ct && ct->helper) {
- unsigned int ret;
- ret = ct->helper->help(pskb,
- (*pskb)->nh.raw - (*pskb)->data
- + (*pskb)->nh.iph->ihl*4,
- ct, ctinfo);
- if (ret != NF_ACCEPT)
- return ret;
- }
- return NF_ACCEPT;
+ if (!ct)
+ return NF_ACCEPT;
+
+ help = nfct_help(ct);
+ if (!help || !help->helper)
+ return NF_ACCEPT;
+
+ return help->helper->help(pskb,
+ (*pskb)->nh.raw - (*pskb)->data
+ + (*pskb)->nh.iph->ihl*4,
+ ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ac702a2..ac35f95 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -179,31 +179,36 @@ static unsigned int ipv6_confirm(unsigne
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
+ struct nf_conn_help *help;
enum ip_conntrack_info ctinfo;
+ unsigned int ret, protoff;
+ unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
+ - (*pskb)->data;
+ unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
+
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
- if (ct && ct->helper) {
- unsigned int ret, protoff;
- unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
- - (*pskb)->data;
- unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
-
- protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
- (*pskb)->len - extoff);
- if (protoff < 0 || protoff > (*pskb)->len ||
- pnum == NEXTHDR_FRAGMENT) {
- DEBUGP("proto header not found\n");
- return NF_ACCEPT;
- }
+ if (!ct)
+ goto out;
- ret = ct->helper->help(pskb, protoff, ct, ctinfo);
- if (ret != NF_ACCEPT)
- return ret;
+ help = nfct_help(ct);
+ if (!help || !help->helper)
+ goto out;
+
+ protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
+ (*pskb)->len - extoff);
+ if (protoff < 0 || protoff > (*pskb)->len ||
+ pnum == NEXTHDR_FRAGMENT) {
+ DEBUGP("proto header not found\n");
+ return NF_ACCEPT;
}
+ ret = help->helper->help(pskb, protoff, ct, ctinfo);
+ if (ret != NF_ACCEPT)
+ return ret;
+out:
/* We've seen it coming out the other side: confirm it */
-
return nf_conntrack_confirm(pskb);
}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 62bb509..873afa6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -3,7 +3,7 @@
extension. */
/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
* (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,9 @@
* - generalize L3 protocol denendent part.
* 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
* - add support various size of conntrack structures.
+ * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
+ * - restructure nf_conn (introduce nf_conn_help)
+ * - redesign 'features' how they were originally intended
*
* Derived from net/ipv4/netfilter/ip_conntrack_core.c
*/
@@ -55,7 +58,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
-#define NF_CONNTRACK_VERSION "0.4.1"
+#define NF_CONNTRACK_VERSION "0.5.0"
#if 0
#define DEBUGP printk
@@ -259,21 +262,8 @@ static inline u_int32_t hash_conntrack(c
nf_conntrack_hash_rnd);
}
-/* Initialize "struct nf_conn" which has spaces for helper */
-static int
-init_conntrack_for_helper(struct nf_conn *conntrack, u_int32_t features)
-{
-
- conntrack->help = (union nf_conntrack_help *)
- (((unsigned long)conntrack->data
- + (__alignof__(union nf_conntrack_help) - 1))
- & (~((unsigned long)(__alignof__(union nf_conntrack_help) -1))));
- return 0;
-}
-
int nf_conntrack_register_cache(u_int32_t features, const char *name,
- size_t size,
- int (*init)(struct nf_conn *, u_int32_t))
+ size_t size)
{
int ret = 0;
char *cache_name;
@@ -296,8 +286,7 @@ int nf_conntrack_register_cache(u_int32_
DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
if ((!strncmp(nf_ct_cache[features].name, name,
NF_CT_FEATURES_NAMELEN))
- && nf_ct_cache[features].size == size
- && nf_ct_cache[features].init_conntrack == init) {
+ && nf_ct_cache[features].size == size) {
DEBUGP("nf_conntrack_register_cache: reusing.\n");
nf_ct_cache[features].use++;
ret = 0;
@@ -340,7 +329,6 @@ int nf_conntrack_register_cache(u_int32_
write_lock_bh(&nf_ct_cache_lock);
nf_ct_cache[features].use = 1;
nf_ct_cache[features].size = size;
- nf_ct_cache[features].init_conntrack = init;
nf_ct_cache[features].cachep = cachep;
nf_ct_cache[features].name = cache_name;
write_unlock_bh(&nf_ct_cache_lock);
@@ -377,7 +365,6 @@ void nf_conntrack_unregister_cache(u_int
name = nf_ct_cache[features].name;
nf_ct_cache[features].cachep = NULL;
nf_ct_cache[features].name = NULL;
- nf_ct_cache[features].init_conntrack = NULL;
nf_ct_cache[features].size = 0;
write_unlock_bh(&nf_ct_cache_lock);
@@ -432,11 +419,15 @@ nf_ct_invert_tuple(struct nf_conntrack_t
/* nf_conntrack_expect helper functions */
void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
{
+ struct nf_conn_help *master_help = nfct_help(exp->master);
+
+ NF_CT_ASSERT(master_help);
ASSERT_WRITE_LOCK(&nf_conntrack_lock);
NF_CT_ASSERT(!timer_pending(&exp->timeout));
+
list_del(&exp->list);
NF_CT_STAT_INC(expect_delete);
- exp->master->expecting--;
+ master_help->expecting--;
nf_conntrack_expect_put(exp);
}
@@ -508,9 +499,10 @@ find_expectation(const struct nf_conntra
void nf_ct_remove_expectations(struct nf_conn *ct)
{
struct nf_conntrack_expect *i, *tmp;
+ struct nf_conn_help *help = nfct_help(ct);
/* Optimization: most connection never expect any others. */
- if (ct->expecting == 0)
+ if (!help || help->expecting == 0)
return;
list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
@@ -713,6 +705,7 @@ __nf_conntrack_confirm(struct sk_buff **
conntrack_tuple_cmp,
struct nf_conntrack_tuple_hash *,
&ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
+ struct nf_conn_help *help;
/* Remove from unconfirmed list */
list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
@@ -726,7 +719,8 @@ __nf_conntrack_confirm(struct sk_buff **
set_bit(IPS_CONFIRMED_BIT, &ct->status);
NF_CT_STAT_INC(insert);
write_unlock_bh(&nf_conntrack_lock);
- if (ct->helper)
+ help = nfct_help(ct);
+ if (help && help->helper)
nf_conntrack_event_cache(IPCT_HELPER, *pskb);
#ifdef CONFIG_NF_NAT_NEEDED
if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
@@ -842,8 +836,9 @@ __nf_conntrack_alloc(const struct nf_con
{
struct nf_conn *conntrack = NULL;
u_int32_t features = 0;
+ void *helper;
- if (!nf_conntrack_hash_rnd_initted) {
+ if (unlikely(!nf_conntrack_hash_rnd_initted)) {
get_random_bytes(&nf_conntrack_hash_rnd, 4);
nf_conntrack_hash_rnd_initted = 1;
}
@@ -863,8 +858,11 @@ __nf_conntrack_alloc(const struct nf_con
/* find features needed by this conntrack. */
features = l3proto->get_features(orig);
+
+ /* FIXME: protect helper list per RCU */
read_lock_bh(&nf_conntrack_lock);
- if (__nf_ct_helper_find(repl) != NULL)
+ helper = __nf_ct_helper_find(repl);
+ if (helper)
features |= NF_CT_F_HELP;
read_unlock_bh(&nf_conntrack_lock);
@@ -872,7 +870,7 @@ __nf_conntrack_alloc(const struct nf_con
read_lock_bh(&nf_ct_cache_lock);
- if (!nf_ct_cache[features].use) {
+ if (unlikely(!nf_ct_cache[features].use)) {
DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
features);
goto out;
@@ -886,12 +884,10 @@ __nf_conntrack_alloc(const struct nf_con
memset(conntrack, 0, nf_ct_cache[features].size);
conntrack->features = features;
- if (nf_ct_cache[features].init_conntrack &&
- nf_ct_cache[features].init_conntrack(conntrack, features) < 0) {
- DEBUGP("nf_conntrack_alloc: failed to init\n");
- kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
- conntrack = NULL;
- goto out;
+ if (helper) {
+ struct nf_conn_help *help = nfct_help(conntrack);
+ NF_CT_ASSERT(help);
+ help->helper = helper;
}
atomic_set(&conntrack->ct_general.use, 1);
@@ -972,11 +968,8 @@ init_conntrack(const struct nf_conntrack
#endif
nf_conntrack_get(&conntrack->master->ct_general);
NF_CT_STAT_INC(expect_new);
- } else {
- conntrack->helper = __nf_ct_helper_find(&repl_tuple);
-
+ } else
NF_CT_STAT_INC(new);
- }
/* Overload tuple linked list to put us in unconfirmed list. */
list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
@@ -1206,14 +1199,16 @@ void nf_conntrack_expect_put(struct nf_c
static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
{
+ struct nf_conn_help *master_help = nfct_help(exp->master);
+
atomic_inc(&exp->use);
- exp->master->expecting++;
+ master_help->expecting++;
list_add(&exp->list, &nf_conntrack_expect_list);
init_timer(&exp->timeout);
exp->timeout.data = (unsigned long)exp;
exp->timeout.function = expectation_timed_out;
- exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
+ exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
add_timer(&exp->timeout);
exp->id = ++nf_conntrack_expect_next_id;
@@ -1239,10 +1234,12 @@ static void evict_oldest_expect(struct n
static inline int refresh_timer(struct nf_conntrack_expect *i)
{
+ struct nf_conn_help *master_help = nfct_help(i->master);
+
if (!del_timer(&i->timeout))
return 0;
- i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
+ i->timeout.expires = jiffies + master_help->helper->timeout*HZ;
add_timer(&i->timeout);
return 1;
}
@@ -1251,8 +1248,11 @@ int nf_conntrack_expect_related(struct n
{
struct nf_conntrack_expect *i;
struct nf_conn *master = expect->master;
+ struct nf_conn_help *master_help = nfct_help(master);
int ret;
+ NF_CT_ASSERT(master_help);
+
DEBUGP("nf_conntrack_expect_related %p\n", related_to);
DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
@@ -1271,8 +1271,8 @@ int nf_conntrack_expect_related(struct n
}
}
/* Will be over limit? */
- if (master->helper->max_expected &&
- master->expecting >= master->helper->max_expected)
+ if (master_help->helper->max_expected &&
+ master_help->expecting >= master_help->helper->max_expected)
evict_oldest_expect(master);
nf_conntrack_expect_insert(expect);
@@ -1283,24 +1283,6 @@ out:
return ret;
}
-/* Alter reply tuple (maybe alter helper). This is for NAT, and is
- implicitly racy: see __nf_conntrack_confirm */
-void nf_conntrack_alter_reply(struct nf_conn *conntrack,
- const struct nf_conntrack_tuple *newreply)
-{
- write_lock_bh(&nf_conntrack_lock);
- /* Should be unconfirmed, so not in hash table yet */
- NF_CT_ASSERT(!nf_ct_is_confirmed(conntrack));
-
- DEBUGP("Altering reply tuple of %p to ", conntrack);
- NF_CT_DUMP_TUPLE(newreply);
-
- conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
- if (!conntrack->master && conntrack->expecting == 0)
- conntrack->helper = __nf_ct_helper_find(newreply);
- write_unlock_bh(&nf_conntrack_lock);
-}
-
int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
{
int ret;
@@ -1309,8 +1291,7 @@ int nf_conntrack_helper_register(struct
ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
sizeof(struct nf_conn)
+ sizeof(union nf_conntrack_help)
- + __alignof__(union nf_conntrack_help),
- init_conntrack_for_helper);
+ + __alignof__(union nf_conntrack_help));
if (ret < 0) {
printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
return ret;
@@ -1338,9 +1319,12 @@ __nf_conntrack_helper_find_byname(const
static inline int unhelp(struct nf_conntrack_tuple_hash *i,
const struct nf_conntrack_helper *me)
{
- if (nf_ct_tuplehash_to_ctrack(i)->helper == me) {
- nf_conntrack_event(IPCT_HELPER, nf_ct_tuplehash_to_ctrack(i));
- nf_ct_tuplehash_to_ctrack(i)->helper = NULL;
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
+ struct nf_conn_help *help = nfct_help(ct);
+
+ if (help && help->helper == me) {
+ nf_conntrack_event(IPCT_HELPER, ct);
+ help->helper = NULL;
}
return 0;
}
@@ -1356,7 +1340,8 @@ void nf_conntrack_helper_unregister(stru
/* Get rid of expectations */
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
- if (exp->master->helper == me && del_timer(&exp->timeout)) {
+ struct nf_conn_help *help = nfct_help(exp->master);
+ if (help->helper == me && del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
}
@@ -1695,7 +1680,7 @@ int __init nf_conntrack_init(void)
}
ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
- sizeof(struct nf_conn), NULL);
+ sizeof(struct nf_conn));
if (ret < 0) {
printk(KERN_ERR "Unable to create nf_conn slab cache\n");
goto err_free_hash;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index ab0c920..280c5c2 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -440,7 +440,7 @@ static int help(struct sk_buff **pskb,
u32 seq;
int dir = CTINFO2DIR(ctinfo);
unsigned int matchlen, matchoff;
- struct ip_ct_ftp_master *ct_ftp_info = &ct->help->ct_ftp_info;
+ struct ip_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
struct nf_conntrack_expect *exp;
struct nf_conntrack_man cmd = {};
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 73ab16b..bd42186 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2,7 +2,7 @@
* protocol helpers and general trouble making from userspace.
*
* (C) 2001 by Jay Schulist <jschlst@samba.org>
- * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
* (C) 2003 by Patrick Mchardy <kaber@trash.net>
* (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
*
@@ -44,7 +44,7 @@
MODULE_LICENSE("GPL");
-static char __initdata version[] = "0.92";
+static char __initdata version[] = "0.93";
#if 0
#define DEBUGP printk
@@ -165,15 +165,16 @@ static inline int
ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
{
struct nfattr *nest_helper;
+ const struct nf_conn_help *help = nfct_help(ct);
- if (!ct->helper)
+ if (!help)
return 0;
nest_helper = NFA_NEST(skb, CTA_HELP);
- NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
+ NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
- if (ct->helper->to_nfattr)
- ct->helper->to_nfattr(skb, ct);
+ if (help->helper->to_nfattr)
+ help->helper->to_nfattr(skb, ct);
NFA_NEST_END(skb, nest_helper);
@@ -903,11 +904,17 @@ static inline int
ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
{
struct nf_conntrack_helper *helper;
+ struct nf_conn_help *help = nfct_help(ct);
char *helpname;
int err;
DEBUGP("entered %s\n", __FUNCTION__);
+ if (!help) {
+ /* FIXME: we need to reallocate and rehash */
+ return -EBUSY;
+ }
+
/* don't change helper of sibling connections */
if (ct->master)
return -EINVAL;
@@ -924,18 +931,18 @@ ctnetlink_change_helper(struct nf_conn *
return -EINVAL;
}
- if (ct->helper) {
+ if (help->helper) {
if (!helper) {
/* we had a helper before ... */
nf_ct_remove_expectations(ct);
- ct->helper = NULL;
+ help->helper = NULL;
} else {
/* need to zero data of old helper */
- memset(&ct->help, 0, sizeof(ct->help));
+ memset(&help->help, 0, sizeof(help->help));
}
}
- ct->helper = helper;
+ help->helper = helper;
return 0;
}
@@ -1050,14 +1057,9 @@ ctnetlink_create_conntrack(struct nfattr
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif
- ct->helper = nf_ct_helper_find_get(rtuple);
-
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
- if (ct->helper)
- nf_ct_helper_put(ct->helper);
-
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0;
@@ -1417,7 +1419,8 @@ ctnetlink_del_expect(struct sock *ctnl,
}
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
list) {
- if (exp->master->helper == h
+ struct nf_conn_help *m_help = nfct_help(exp->master);
+ if (m_help->helper == h
&& del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
@@ -1452,6 +1455,7 @@ ctnetlink_create_expect(struct nfattr *c
struct nf_conntrack_tuple_hash *h = NULL;
struct nf_conntrack_expect *exp;
struct nf_conn *ct;
+ struct nf_conn_help *help;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
@@ -1472,8 +1476,9 @@ ctnetlink_create_expect(struct nfattr *c
if (!h)
return -ENOENT;
ct = nf_ct_tuplehash_to_ctrack(h);
+ help = nfct_help(ct);
- if (!ct->helper) {
+ if (!help || !help->helper) {
/* such conntrack hasn't got any helper, abort */
err = -EINVAL;
goto out;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 617599a..290d5a0 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -839,7 +839,6 @@ EXPORT_SYMBOL(nf_conntrack_l3proto_unreg
EXPORT_SYMBOL(nf_conntrack_protocol_register);
EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
EXPORT_SYMBOL(nf_ct_invert_tuplepr);
-EXPORT_SYMBOL(nf_conntrack_alter_reply);
EXPORT_SYMBOL(nf_conntrack_destroyed);
EXPORT_SYMBOL(need_conntrack);
EXPORT_SYMBOL(nf_conntrack_helper_register);
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 38b6715..c451169 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -96,6 +96,7 @@ match(const struct sk_buff *skb,
{
const struct xt_helper_info *info = matchinfo;
struct nf_conn *ct;
+ struct nf_conn_help *master_help;
enum ip_conntrack_info ctinfo;
int ret = info->invert;
@@ -111,7 +112,8 @@ match(const struct sk_buff *skb,
}
read_lock_bh(&nf_conntrack_lock);
- if (!ct->master->helper) {
+ master_help = nfct_help(ct->master);
+ if (!master_help || !master_help->helper) {
DEBUGP("xt_helper: master ct %p has no helper\n",
exp->expectant);
goto out_unlock;
@@ -123,8 +125,8 @@ match(const struct sk_buff *skb,
if (info->name[0] == '\0')
ret ^= 1;
else
- ret ^= !strncmp(ct->master->helper->name, info->name,
- strlen(ct->master->helper->name));
+ ret ^= !strncmp(master_help->helper->name, info->name,
+ strlen(master_help->helper->name));
out_unlock:
read_unlock_bh(&nf_conntrack_lock);
return ret;
--
- Harald Welte <laforge@gnumonks.org> http://gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* [RFC: 2.6 patch] let NET_CLS_ACT no longer depend on EXPERIMENTAL
From: Adrian Bunk @ 2006-02-12 17:56 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
This option should IMHO no longer depend on EXPERIMENTAL.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
--- linux-2.6.16-rc2-mm1-full/net/sched/Kconfig.old 2006-02-12 02:21:30.000000000 +0100
+++ linux-2.6.16-rc2-mm1-full/net/sched/Kconfig 2006-02-12 02:21:58.000000000 +0100
@@ -434,7 +434,6 @@
config NET_CLS_ACT
bool "Actions"
- depends on EXPERIMENTAL
select NET_ESTIMATOR
---help---
Say Y here if you want to use traffic control actions. Actions
^ permalink raw reply
* Re: [RFC: 2.6 patch] CONFIG_FORCEDETH updates
From: Lee Revell @ 2006-02-12 22:03 UTC (permalink / raw)
To: Adrian Bunk; +Cc: jgarzik, netdev, linux-kernel
In-Reply-To: <20060212175202.GK30922@stusta.de>
On Sun, 2006-02-12 at 18:52 +0100, Adrian Bunk wrote:
> This patch contains the following possible updates:
> - let FORCEDETH no longer depend on EXPERIMENTAL
> - remove the "Reverse Engineered" from the option text:
> for the user it's important which hardware the driver supports, not
> how it was developed
Is this driver as stable as one that was developed with proper
documentation? I prefer to know that something as elementary as a fast
ethernet controller had to be reverse engineered so I can avoid
supporting a vendor so hostile to Linux.
Lee
^ permalink raw reply
* Re: [RFC: 2.6 patch] CONFIG_FORCEDETH updates
From: Alistair John Strachan @ 2006-02-12 22:47 UTC (permalink / raw)
To: Lee Revell; +Cc: Adrian Bunk, jgarzik, netdev, linux-kernel
In-Reply-To: <1139781817.19342.300.camel@mindpipe>
On Sunday 12 February 2006 22:03, Lee Revell wrote:
> On Sun, 2006-02-12 at 18:52 +0100, Adrian Bunk wrote:
> > This patch contains the following possible updates:
> > - let FORCEDETH no longer depend on EXPERIMENTAL
> > - remove the "Reverse Engineered" from the option text:
> > for the user it's important which hardware the driver supports, not
> > how it was developed
>
> Is this driver as stable as one that was developed with proper
> documentation? I prefer to know that something as elementary as a fast
> ethernet controller had to be reverse engineered so I can avoid
> supporting a vendor so hostile to Linux.
Although NVIDIA continue to maintain their own driver, I know forcedeth has
had contributions from at least a couple of NVIDIA employees. Also, I've
personally used the driver on nForce2, nForce3 and now nForce4 SLI boards and
it's rock solid.
Adrian's change is a good one, IMO.
--
Cheers,
Alistair.
'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.
^ permalink raw reply
* Re: [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: Yasuyuki KOZAKAI @ 2006-02-13 1:32 UTC (permalink / raw)
To: laforge; +Cc: netdev, netfilter-devel, davem
In-Reply-To: <20060212175622.GG4601@sunbeam.de.gnumonks.org>
Hi, Harald,
From: Harald Welte <laforge@gnumonks.org>
Date: Sun, 12 Feb 2006 18:56:22 +0100
> [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
>
> This patch moves all helper related data fields of 'struct nf_conn' into a
> separate structure 'struct nf_conn_help'. This new structure is only
> present in conntrack entries for which we actually have a helper loaded.
>
> Also, this patch cleans up the nf_conntrack 'features' mechanism to
> resemble what the original idea was: Just glue the feature-specific
> data structures at the end of 'struct nf_conn', and explicitly re-calculate
> the pointer to it when needed rather than keeping pointers around.
>
> Saves 20 bytes per conntrack on my x86_64 box. A non-helped conntrack is
> 276 bytes. We still need to save another 20 bytes in order to fit into to
> target of 256bytes.
>
> Signed-off-by: Harald Welte <laforge@netfilter.org>
This patch seems not to include fixes I pointed out and you said "fixed".
Please confirm if you really sent the intended one.
Regards,
-- Yasuyuki Kozakai
^ permalink raw reply
* Re: [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: Harald Welte @ 2006-02-13 8:17 UTC (permalink / raw)
To: Yasuyuki KOZAKAI; +Cc: netdev, netfilter-devel, davem
In-Reply-To: <200602130132.k1D1WoYA003717@toshiba.co.jp>
[-- Attachment #1: Type: text/plain, Size: 1661 bytes --]
On Mon, Feb 13, 2006 at 10:32:49AM +0900, Yasuyuki KOZAKAI wrote:
>
> Hi, Harald,
>
> From: Harald Welte <laforge@gnumonks.org>
> Date: Sun, 12 Feb 2006 18:56:22 +0100
>
> > [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
> >
> > This patch moves all helper related data fields of 'struct nf_conn' into a
> > separate structure 'struct nf_conn_help'. This new structure is only
> > present in conntrack entries for which we actually have a helper loaded.
> >
> > Also, this patch cleans up the nf_conntrack 'features' mechanism to
> > resemble what the original idea was: Just glue the feature-specific
> > data structures at the end of 'struct nf_conn', and explicitly re-calculate
> > the pointer to it when needed rather than keeping pointers around.
> >
> > Saves 20 bytes per conntrack on my x86_64 box. A non-helped conntrack is
> > 276 bytes. We still need to save another 20 bytes in order to fit into to
> > target of 256bytes.
> >
> > Signed-off-by: Harald Welte <laforge@netfilter.org>
>
> This patch seems not to include fixes I pointed out and you said "fixed".
> Please confirm if you really sent the intended one.
oops, thanks for checking. Dave: Please hold, I sent an old version.
You'll get a new one ASAP.
--
- Harald Welte <laforge@netfilter.org> http://netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [RFC: 2.6 patch] CONFIG_FORCEDETH updates
From: Arthur Othieno @ 2006-02-13 8:36 UTC (permalink / raw)
To: Lee Revell; +Cc: Adrian Bunk, jgarzik, netdev, linux-kernel
In-Reply-To: <1139781817.19342.300.camel@mindpipe>
On Sun, Feb 12, 2006 at 05:03:36PM -0500, Lee Revell wrote:
> On Sun, 2006-02-12 at 18:52 +0100, Adrian Bunk wrote:
> > This patch contains the following possible updates:
> > - let FORCEDETH no longer depend on EXPERIMENTAL
> > - remove the "Reverse Engineered" from the option text:
> > for the user it's important which hardware the driver supports, not
> > how it was developed
>
> Is this driver as stable as one that was developed with proper
> documentation?
Been using it on nForce since v0.19 (circa 2003) with no problems.
I doubt there are that many (significant) users of the binary driver
left..
And like Alistair pointed out:
drivers/net/forcedeth:17: * Copyright (c) 2004 NVIDIA Corporation
> I prefer to know that something as elementary as a fast ethernet
> controller had to be reverse engineered so I can avoid supporting
> a vendor so hostile to Linux.
Then how about moving the "Reverse Engineered" to the help text instead?
^ permalink raw reply
* Re: [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: Harald Welte @ 2006-02-13 10:04 UTC (permalink / raw)
To: David Miller, Netfilter Development Mailinglist,
Linux Netdev List
In-Reply-To: <20060212175622.GG4601@sunbeam.de.gnumonks.org>
[-- Attachment #1: Type: text/plain, Size: 25327 bytes --]
Hi Dave!
This is the correct (latest) version of this patch. Sorry for the
confusion. Please apply to net-2.6.17, thanks!
[NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
This patch moves all helper related data fields of 'struct nf_conn' into a
separate structure 'struct nf_conn_help'. This new structure is only
present in conntrack entries for which we actually have a helper loaded.
Also, this patch cleans up the nf_conntrack 'features' mechanism to
resemble what the original idea was: Just glue the feature-specific
data structures at the end of 'struct nf_conn', and explicitly re-calculate
the pointer to it when needed rather than keeping pointers around.
Saves 20 bytes per conntrack on my x86_64 box. A non-helped conntrack is
276 bytes. We still need to save another 20 bytes in order to fit into to
target of 256bytes.
Signed-off-by: Harald Welte <laforge@netfilter.org>
---
commit aba8cf3ac5b60e10eb1ce9f30b6bb4c007ab9868
tree 758aedbe80b8306c1991a05c47eab8905d33a13b
parent 94d3d40c84672b74e59ea5252f61602610e1513e
author Harald Welte <laforge@netfilter.org> Sun, 29 Jan 2006 19:19:06 +0100
committer Harald Welte <laforge@netfilter.org> Sun, 29 Jan 2006 19:19:06 +0100
include/net/netfilter/nf_conntrack.h | 56 +++++++----
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 22 ++---
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 39 +++++---
net/netfilter/nf_conntrack_core.c | 117 ++++++++++--------------
net/netfilter/nf_conntrack_ftp.c | 2
net/netfilter/nf_conntrack_netlink.c | 39 +++++---
net/netfilter/nf_conntrack_standalone.c | 1
net/netfilter/xt_helper.c | 8 +-
8 files changed, 147 insertions(+), 137 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 6d075ca..9d1f0e6 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -67,6 +67,18 @@ do { \
struct nf_conntrack_helper;
+/* nf_conn feature for connections that have a helper */
+struct nf_conn_help {
+ /* Helper. if any */
+ struct nf_conntrack_helper *helper;
+
+ union nf_conntrack_help help;
+
+ /* Current number of expected connections */
+ unsigned int expecting;
+};
+
+
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
struct nf_conn
{
@@ -81,6 +93,9 @@ struct nf_conn
/* Have we seen traffic both ways yet? (bitset) */
unsigned long status;
+ /* If we were expected by an expectation, this will be it */
+ struct nf_conn *master;
+
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
@@ -88,38 +103,22 @@ struct nf_conn
/* Accounting Information (same cache line as other written members) */
struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
#endif
- /* If we were expected by an expectation, this will be it */
- struct nf_conn *master;
-
- /* Current number of expected connections */
- unsigned int expecting;
/* Unique ID that identifies this conntrack*/
unsigned int id;
- /* Helper. if any */
- struct nf_conntrack_helper *helper;
-
/* features - nat, helper, ... used by allocating system */
u_int32_t features;
- /* Storage reserved for other modules: */
-
- union nf_conntrack_proto proto;
-
#if defined(CONFIG_NF_CONNTRACK_MARK)
u_int32_t mark;
#endif
- /* These members are dynamically allocated. */
-
- union nf_conntrack_help *help;
+ /* Storage reserved for other modules: */
+ union nf_conntrack_proto proto;
- /* Layer 3 dependent members. (ex: NAT) */
- union {
- struct nf_conntrack_ipv4 *ipv4;
- } l3proto;
- void *data[0];
+ /* features dynamically at the end: helper, nat (both optional) */
+ char data[0];
};
struct nf_conntrack_expect
@@ -373,10 +372,23 @@ nf_conntrack_expect_event(enum ip_conntr
#define NF_CT_F_NUM 4
extern int
-nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
- int (*init_conntrack)(struct nf_conn *, u_int32_t));
+nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
extern void
nf_conntrack_unregister_cache(u_int32_t features);
+/* valid combinations:
+ * basic: nf_conn, nf_conn .. nf_conn_help
+ * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help
+ */
+static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+{
+ unsigned int offset = sizeof(struct nf_conn);
+
+ if (!(ct->features & NF_CT_F_HELP))
+ return NULL;
+
+ return (struct nf_conn_help *) ((void *)ct + offset);
+}
+
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_H */
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 167619f..e52b50b 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -141,19 +141,21 @@ static unsigned int ipv4_conntrack_help(
{
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
+ struct nf_conn_help *help;
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
- if (ct && ct->helper) {
- unsigned int ret;
- ret = ct->helper->help(pskb,
- (*pskb)->nh.raw - (*pskb)->data
- + (*pskb)->nh.iph->ihl*4,
- ct, ctinfo);
- if (ret != NF_ACCEPT)
- return ret;
- }
- return NF_ACCEPT;
+ if (!ct)
+ return NF_ACCEPT;
+
+ help = nfct_help(ct);
+ if (!help || !help->helper)
+ return NF_ACCEPT;
+
+ return help->helper->help(pskb,
+ (*pskb)->nh.raw - (*pskb)->data
+ + (*pskb)->nh.iph->ihl*4,
+ ct, ctinfo);
}
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ac702a2..ac35f95 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -179,31 +179,36 @@ static unsigned int ipv6_confirm(unsigne
int (*okfn)(struct sk_buff *))
{
struct nf_conn *ct;
+ struct nf_conn_help *help;
enum ip_conntrack_info ctinfo;
+ unsigned int ret, protoff;
+ unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
+ - (*pskb)->data;
+ unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
+
/* This is where we call the helper: as the packet goes out. */
ct = nf_ct_get(*pskb, &ctinfo);
- if (ct && ct->helper) {
- unsigned int ret, protoff;
- unsigned int extoff = (u8*)((*pskb)->nh.ipv6h + 1)
- - (*pskb)->data;
- unsigned char pnum = (*pskb)->nh.ipv6h->nexthdr;
-
- protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
- (*pskb)->len - extoff);
- if (protoff < 0 || protoff > (*pskb)->len ||
- pnum == NEXTHDR_FRAGMENT) {
- DEBUGP("proto header not found\n");
- return NF_ACCEPT;
- }
+ if (!ct)
+ goto out;
- ret = ct->helper->help(pskb, protoff, ct, ctinfo);
- if (ret != NF_ACCEPT)
- return ret;
+ help = nfct_help(ct);
+ if (!help || !help->helper)
+ goto out;
+
+ protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
+ (*pskb)->len - extoff);
+ if (protoff < 0 || protoff > (*pskb)->len ||
+ pnum == NEXTHDR_FRAGMENT) {
+ DEBUGP("proto header not found\n");
+ return NF_ACCEPT;
}
+ ret = help->helper->help(pskb, protoff, ct, ctinfo);
+ if (ret != NF_ACCEPT)
+ return ret;
+out:
/* We've seen it coming out the other side: confirm it */
-
return nf_conntrack_confirm(pskb);
}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 0ce337a..ece4e83 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -3,7 +3,7 @@
extension. */
/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
* (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,9 @@
* - generalize L3 protocol denendent part.
* 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
* - add support various size of conntrack structures.
+ * 26 Jan 2006: Harald Welte <laforge@netfilter.org>
+ * - restructure nf_conn (introduce nf_conn_help)
+ * - redesign 'features' how they were originally intended
*
* Derived from net/ipv4/netfilter/ip_conntrack_core.c
*/
@@ -55,7 +58,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <linux/netfilter_ipv4/listhelp.h>
-#define NF_CONNTRACK_VERSION "0.4.1"
+#define NF_CONNTRACK_VERSION "0.5.0"
#if 0
#define DEBUGP printk
@@ -259,21 +262,8 @@ static inline u_int32_t hash_conntrack(c
nf_conntrack_hash_rnd);
}
-/* Initialize "struct nf_conn" which has spaces for helper */
-static int
-init_conntrack_for_helper(struct nf_conn *conntrack, u_int32_t features)
-{
-
- conntrack->help = (union nf_conntrack_help *)
- (((unsigned long)conntrack->data
- + (__alignof__(union nf_conntrack_help) - 1))
- & (~((unsigned long)(__alignof__(union nf_conntrack_help) -1))));
- return 0;
-}
-
int nf_conntrack_register_cache(u_int32_t features, const char *name,
- size_t size,
- int (*init)(struct nf_conn *, u_int32_t))
+ size_t size)
{
int ret = 0;
char *cache_name;
@@ -296,8 +286,7 @@ int nf_conntrack_register_cache(u_int32_
DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
if ((!strncmp(nf_ct_cache[features].name, name,
NF_CT_FEATURES_NAMELEN))
- && nf_ct_cache[features].size == size
- && nf_ct_cache[features].init_conntrack == init) {
+ && nf_ct_cache[features].size == size) {
DEBUGP("nf_conntrack_register_cache: reusing.\n");
nf_ct_cache[features].use++;
ret = 0;
@@ -340,7 +329,6 @@ int nf_conntrack_register_cache(u_int32_
write_lock_bh(&nf_ct_cache_lock);
nf_ct_cache[features].use = 1;
nf_ct_cache[features].size = size;
- nf_ct_cache[features].init_conntrack = init;
nf_ct_cache[features].cachep = cachep;
nf_ct_cache[features].name = cache_name;
write_unlock_bh(&nf_ct_cache_lock);
@@ -377,7 +365,6 @@ void nf_conntrack_unregister_cache(u_int
name = nf_ct_cache[features].name;
nf_ct_cache[features].cachep = NULL;
nf_ct_cache[features].name = NULL;
- nf_ct_cache[features].init_conntrack = NULL;
nf_ct_cache[features].size = 0;
write_unlock_bh(&nf_ct_cache_lock);
@@ -432,11 +419,15 @@ nf_ct_invert_tuple(struct nf_conntrack_t
/* nf_conntrack_expect helper functions */
void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
{
+ struct nf_conn_help *master_help = nfct_help(exp->master);
+
+ NF_CT_ASSERT(master_help);
ASSERT_WRITE_LOCK(&nf_conntrack_lock);
NF_CT_ASSERT(!timer_pending(&exp->timeout));
+
list_del(&exp->list);
NF_CT_STAT_INC(expect_delete);
- exp->master->expecting--;
+ master_help->expecting--;
nf_conntrack_expect_put(exp);
}
@@ -508,9 +499,10 @@ find_expectation(const struct nf_conntra
void nf_ct_remove_expectations(struct nf_conn *ct)
{
struct nf_conntrack_expect *i, *tmp;
+ struct nf_conn_help *help = nfct_help(ct);
/* Optimization: most connection never expect any others. */
- if (ct->expecting == 0)
+ if (!help || help->expecting == 0)
return;
list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
@@ -713,6 +705,7 @@ __nf_conntrack_confirm(struct sk_buff **
conntrack_tuple_cmp,
struct nf_conntrack_tuple_hash *,
&ct->tuplehash[IP_CT_DIR_REPLY].tuple, NULL)) {
+ struct nf_conn_help *help;
/* Remove from unconfirmed list */
list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
@@ -726,7 +719,8 @@ __nf_conntrack_confirm(struct sk_buff **
set_bit(IPS_CONFIRMED_BIT, &ct->status);
NF_CT_STAT_INC(insert);
write_unlock_bh(&nf_conntrack_lock);
- if (ct->helper)
+ help = nfct_help(ct);
+ if (help && help->helper)
nf_conntrack_event_cache(IPCT_HELPER, *pskb);
#ifdef CONFIG_NF_NAT_NEEDED
if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
@@ -842,8 +836,9 @@ __nf_conntrack_alloc(const struct nf_con
{
struct nf_conn *conntrack = NULL;
u_int32_t features = 0;
+ struct nf_conntrack_helper *helper;
- if (!nf_conntrack_hash_rnd_initted) {
+ if (unlikely(!nf_conntrack_hash_rnd_initted)) {
get_random_bytes(&nf_conntrack_hash_rnd, 4);
nf_conntrack_hash_rnd_initted = 1;
}
@@ -863,8 +858,11 @@ __nf_conntrack_alloc(const struct nf_con
/* find features needed by this conntrack. */
features = l3proto->get_features(orig);
+
+ /* FIXME: protect helper list per RCU */
read_lock_bh(&nf_conntrack_lock);
- if (__nf_ct_helper_find(repl) != NULL)
+ helper = __nf_ct_helper_find(repl);
+ if (helper)
features |= NF_CT_F_HELP;
read_unlock_bh(&nf_conntrack_lock);
@@ -872,7 +870,7 @@ __nf_conntrack_alloc(const struct nf_con
read_lock_bh(&nf_ct_cache_lock);
- if (!nf_ct_cache[features].use) {
+ if (unlikely(!nf_ct_cache[features].use)) {
DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
features);
goto out;
@@ -886,12 +884,10 @@ __nf_conntrack_alloc(const struct nf_con
memset(conntrack, 0, nf_ct_cache[features].size);
conntrack->features = features;
- if (nf_ct_cache[features].init_conntrack &&
- nf_ct_cache[features].init_conntrack(conntrack, features) < 0) {
- DEBUGP("nf_conntrack_alloc: failed to init\n");
- kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
- conntrack = NULL;
- goto out;
+ if (helper) {
+ struct nf_conn_help *help = nfct_help(conntrack);
+ NF_CT_ASSERT(help);
+ help->helper = helper;
}
atomic_set(&conntrack->ct_general.use, 1);
@@ -972,11 +968,8 @@ init_conntrack(const struct nf_conntrack
#endif
nf_conntrack_get(&conntrack->master->ct_general);
NF_CT_STAT_INC(expect_new);
- } else {
- conntrack->helper = __nf_ct_helper_find(&repl_tuple);
-
+ } else
NF_CT_STAT_INC(new);
- }
/* Overload tuple linked list to put us in unconfirmed list. */
list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
@@ -1206,14 +1199,16 @@ void nf_conntrack_expect_put(struct nf_c
static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
{
+ struct nf_conn_help *master_help = nfct_help(exp->master);
+
atomic_inc(&exp->use);
- exp->master->expecting++;
+ master_help->expecting++;
list_add(&exp->list, &nf_conntrack_expect_list);
init_timer(&exp->timeout);
exp->timeout.data = (unsigned long)exp;
exp->timeout.function = expectation_timed_out;
- exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
+ exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
add_timer(&exp->timeout);
exp->id = ++nf_conntrack_expect_next_id;
@@ -1239,10 +1234,12 @@ static void evict_oldest_expect(struct n
static inline int refresh_timer(struct nf_conntrack_expect *i)
{
+ struct nf_conn_help *master_help = nfct_help(i->master);
+
if (!del_timer(&i->timeout))
return 0;
- i->timeout.expires = jiffies + i->master->helper->timeout*HZ;
+ i->timeout.expires = jiffies + master_help->helper->timeout*HZ;
add_timer(&i->timeout);
return 1;
}
@@ -1251,8 +1248,11 @@ int nf_conntrack_expect_related(struct n
{
struct nf_conntrack_expect *i;
struct nf_conn *master = expect->master;
+ struct nf_conn_help *master_help = nfct_help(master);
int ret;
+ NF_CT_ASSERT(master_help);
+
DEBUGP("nf_conntrack_expect_related %p\n", related_to);
DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
@@ -1271,8 +1271,8 @@ int nf_conntrack_expect_related(struct n
}
}
/* Will be over limit? */
- if (master->helper->max_expected &&
- master->expecting >= master->helper->max_expected)
+ if (master_help->helper->max_expected &&
+ master_help->expecting >= master_help->helper->max_expected)
evict_oldest_expect(master);
nf_conntrack_expect_insert(expect);
@@ -1283,24 +1283,6 @@ out:
return ret;
}
-/* Alter reply tuple (maybe alter helper). This is for NAT, and is
- implicitly racy: see __nf_conntrack_confirm */
-void nf_conntrack_alter_reply(struct nf_conn *conntrack,
- const struct nf_conntrack_tuple *newreply)
-{
- write_lock_bh(&nf_conntrack_lock);
- /* Should be unconfirmed, so not in hash table yet */
- NF_CT_ASSERT(!nf_ct_is_confirmed(conntrack));
-
- DEBUGP("Altering reply tuple of %p to ", conntrack);
- NF_CT_DUMP_TUPLE(newreply);
-
- conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
- if (!conntrack->master && conntrack->expecting == 0)
- conntrack->helper = __nf_ct_helper_find(newreply);
- write_unlock_bh(&nf_conntrack_lock);
-}
-
int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
{
int ret;
@@ -1308,9 +1290,8 @@ int nf_conntrack_helper_register(struct
ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
sizeof(struct nf_conn)
- + sizeof(union nf_conntrack_help)
- + __alignof__(union nf_conntrack_help),
- init_conntrack_for_helper);
+ + sizeof(struct nf_conn_help)
+ + __alignof__(struct nf_conn_help));
if (ret < 0) {
printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
return ret;
@@ -1338,9 +1319,12 @@ __nf_conntrack_helper_find_byname(const
static inline int unhelp(struct nf_conntrack_tuple_hash *i,
const struct nf_conntrack_helper *me)
{
- if (nf_ct_tuplehash_to_ctrack(i)->helper == me) {
- nf_conntrack_event(IPCT_HELPER, nf_ct_tuplehash_to_ctrack(i));
- nf_ct_tuplehash_to_ctrack(i)->helper = NULL;
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
+ struct nf_conn_help *help = nfct_help(ct);
+
+ if (help && help->helper == me) {
+ nf_conntrack_event(IPCT_HELPER, ct);
+ help->helper = NULL;
}
return 0;
}
@@ -1356,7 +1340,8 @@ void nf_conntrack_helper_unregister(stru
/* Get rid of expectations */
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
- if (exp->master->helper == me && del_timer(&exp->timeout)) {
+ struct nf_conn_help *help = nfct_help(exp->master);
+ if (help->helper == me && del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
}
@@ -1695,7 +1680,7 @@ int __init nf_conntrack_init(void)
}
ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic",
- sizeof(struct nf_conn), NULL);
+ sizeof(struct nf_conn));
if (ret < 0) {
printk(KERN_ERR "Unable to create nf_conn slab cache\n");
goto err_free_hash;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 6f210f3..cd191b0 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -440,7 +440,7 @@ static int help(struct sk_buff **pskb,
u32 seq;
int dir = CTINFO2DIR(ctinfo);
unsigned int matchlen, matchoff;
- struct ip_ct_ftp_master *ct_ftp_info = &ct->help->ct_ftp_info;
+ struct ip_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
struct nf_conntrack_expect *exp;
struct nf_conntrack_man cmd = {};
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9ff3463..f0d6fc9 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2,7 +2,7 @@
* protocol helpers and general trouble making from userspace.
*
* (C) 2001 by Jay Schulist <jschlst@samba.org>
- * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
* (C) 2003 by Patrick Mchardy <kaber@trash.net>
* (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
*
@@ -44,7 +44,7 @@
MODULE_LICENSE("GPL");
-static char __initdata version[] = "0.92";
+static char __initdata version[] = "0.93";
#if 0
#define DEBUGP printk
@@ -165,15 +165,16 @@ static inline int
ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
{
struct nfattr *nest_helper;
+ const struct nf_conn_help *help = nfct_help(ct);
- if (!ct->helper)
+ if (!help || !help->helper)
return 0;
nest_helper = NFA_NEST(skb, CTA_HELP);
- NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
+ NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name);
- if (ct->helper->to_nfattr)
- ct->helper->to_nfattr(skb, ct);
+ if (help->helper->to_nfattr)
+ help->helper->to_nfattr(skb, ct);
NFA_NEST_END(skb, nest_helper);
@@ -903,11 +904,17 @@ static inline int
ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
{
struct nf_conntrack_helper *helper;
+ struct nf_conn_help *help = nfct_help(ct);
char *helpname;
int err;
DEBUGP("entered %s\n", __FUNCTION__);
+ if (!help) {
+ /* FIXME: we need to reallocate and rehash */
+ return -EBUSY;
+ }
+
/* don't change helper of sibling connections */
if (ct->master)
return -EINVAL;
@@ -924,18 +931,18 @@ ctnetlink_change_helper(struct nf_conn *
return -EINVAL;
}
- if (ct->helper) {
+ if (help->helper) {
if (!helper) {
/* we had a helper before ... */
nf_ct_remove_expectations(ct);
- ct->helper = NULL;
+ help->helper = NULL;
} else {
/* need to zero data of old helper */
- memset(&ct->help, 0, sizeof(ct->help));
+ memset(&help->help, 0, sizeof(help->help));
}
}
- ct->helper = helper;
+ help->helper = helper;
return 0;
}
@@ -1050,14 +1057,9 @@ ctnetlink_create_conntrack(struct nfattr
ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
#endif
- ct->helper = nf_ct_helper_find_get(rtuple);
-
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
- if (ct->helper)
- nf_ct_helper_put(ct->helper);
-
DEBUGP("conntrack with id %u inserted\n", ct->id);
return 0;
@@ -1417,7 +1419,8 @@ ctnetlink_del_expect(struct sock *ctnl,
}
list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
list) {
- if (exp->master->helper == h
+ struct nf_conn_help *m_help = nfct_help(exp->master);
+ if (m_help->helper == h
&& del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_conntrack_expect_put(exp);
@@ -1452,6 +1455,7 @@ ctnetlink_create_expect(struct nfattr *c
struct nf_conntrack_tuple_hash *h = NULL;
struct nf_conntrack_expect *exp;
struct nf_conn *ct;
+ struct nf_conn_help *help;
int err = 0;
DEBUGP("entered %s\n", __FUNCTION__);
@@ -1472,8 +1476,9 @@ ctnetlink_create_expect(struct nfattr *c
if (!h)
return -ENOENT;
ct = nf_ct_tuplehash_to_ctrack(h);
+ help = nfct_help(ct);
- if (!ct->helper) {
+ if (!help || !help->helper) {
/* such conntrack hasn't got any helper, abort */
err = -EINVAL;
goto out;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 617599a..290d5a0 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -839,7 +839,6 @@ EXPORT_SYMBOL(nf_conntrack_l3proto_unreg
EXPORT_SYMBOL(nf_conntrack_protocol_register);
EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
EXPORT_SYMBOL(nf_ct_invert_tuplepr);
-EXPORT_SYMBOL(nf_conntrack_alter_reply);
EXPORT_SYMBOL(nf_conntrack_destroyed);
EXPORT_SYMBOL(need_conntrack);
EXPORT_SYMBOL(nf_conntrack_helper_register);
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 38b6715..c451169 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -96,6 +96,7 @@ match(const struct sk_buff *skb,
{
const struct xt_helper_info *info = matchinfo;
struct nf_conn *ct;
+ struct nf_conn_help *master_help;
enum ip_conntrack_info ctinfo;
int ret = info->invert;
@@ -111,7 +112,8 @@ match(const struct sk_buff *skb,
}
read_lock_bh(&nf_conntrack_lock);
- if (!ct->master->helper) {
+ master_help = nfct_help(ct->master);
+ if (!master_help || !master_help->helper) {
DEBUGP("xt_helper: master ct %p has no helper\n",
exp->expectant);
goto out_unlock;
@@ -123,8 +125,8 @@ match(const struct sk_buff *skb,
if (info->name[0] == '\0')
ret ^= 1;
else
- ret ^= !strncmp(ct->master->helper->name, info->name,
- strlen(ct->master->helper->name));
+ ret ^= !strncmp(master_help->helper->name, info->name,
+ strlen(master_help->helper->name));
out_unlock:
read_unlock_bh(&nf_conntrack_lock);
return ret;
--
- Harald Welte <laforge@netfilter.org> http://netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* Re: [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: David S. Miller @ 2006-02-13 10:29 UTC (permalink / raw)
To: laforge; +Cc: netdev, netfilter-devel, yasuyuki.kozakai
In-Reply-To: <20060213081758.GL4601@sunbeam.de.gnumonks.org>
From: Harald Welte <laforge@netfilter.org>
Date: Mon, 13 Feb 2006 09:17:58 +0100
> Dave: Please hold, I sent an old version.
> You'll get a new one ASAP.
OK.
^ permalink raw reply
* Re: [PATCH] [NETFILTER] nf_conntrack: clean up to reduce size of 'struct nf_conn'
From: David S. Miller @ 2006-02-13 10:36 UTC (permalink / raw)
To: laforge; +Cc: netdev, netfilter-devel
In-Reply-To: <20060213100436.GP4601@sunbeam.de.gnumonks.org>
From: Harald Welte <laforge@netfilter.org>
Date: Mon, 13 Feb 2006 11:04:36 +0100
> This is the correct (latest) version of this patch. Sorry for the
> confusion. Please apply to net-2.6.17, thanks!
Applied, thanks.
^ permalink raw reply
* 2.6.16, sk98lin out of date
From: Alistair John Strachan @ 2006-02-13 10:58 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
Hi,
As I'm sure the drivers/net maintainers are well aware, SysKonnect constantly
update their sk98lin/sky2 driver without bothering to sync their changes with
the official linux kernel.
I quickly downloaded driver version 8.31 from http://www.skd.de/ today and
used the install script to generate a diff against 2.6.16-rc3. Even after
fixing up some DOS EOLs in the package, the diff was still well over 1.5MBs.
This is an enormous number of changes.
The reason I'm posting is that my DFI LanParty-UT SLI-D works with this
version of the driver, but not the version 2.6.16-rc3.
[alistair] 10:55 [~] dmesg | grep sk98lin
sk98lin: Could not read VPD data.
sk98lin: probe of 0000:01:0a.0 failed with error -5
I wonder if it's worth just identifying the "quick fix" (I've seen workarounds
for corrupt VPDs like mine) or whether a general merge up would be
beneficial..
If nobody's maintaining this driver I wouldn't mind helping out.
--
Cheers,
Alistair.
'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.
^ permalink raw reply
* Re: 2.6.16, sk98lin out of date
From: Matti Aarnio @ 2006-02-13 11:05 UTC (permalink / raw)
To: Alistair John Strachan; +Cc: netdev, linux-kernel
In-Reply-To: <200602131058.03419.s0348365@sms.ed.ac.uk>
On Mon, Feb 13, 2006 at 10:58:03AM +0000, Alistair John Strachan wrote:
> From: Alistair John Strachan <s0348365@sms.ed.ac.uk>
> To: netdev@vger.kernel.org
> Subject: 2.6.16, sk98lin out of date
> Date: Mon, 13 Feb 2006 10:58:03 +0000
> Cc: linux-kernel@vger.kernel.org
>
> Hi,
>
> As I'm sure the drivers/net maintainers are well aware, SysKonnect constantly
> update their sk98lin/sky2 driver without bothering to sync their changes with
> the official linux kernel.
My understanding is, that skge driver has superceded the sk98lin in
most uses.
There could, of course, be a change to insert vendor driver _as_is_ into
baseline kernel with its own name.
> I quickly downloaded driver version 8.31 from http://www.skd.de/ today and
> used the install script to generate a diff against 2.6.16-rc3. Even after
> fixing up some DOS EOLs in the package, the diff was still well over 1.5MBs.
> This is an enormous number of changes.
>
> The reason I'm posting is that my DFI LanParty-UT SLI-D works with this
> version of the driver, but not the version 2.6.16-rc3.
>
> [alistair] 10:55 [~] dmesg | grep sk98lin
> sk98lin: Could not read VPD data.
> sk98lin: probe of 0000:01:0a.0 failed with error -5
>
> I wonder if it's worth just identifying the "quick fix" (I've seen
> workarounds for corrupt VPDs like mine) or whether a general merge
> up would be beneficial..
See if 'skge' driver would work instead of 'sk98lin' ?
> If nobody's maintaining this driver I wouldn't mind helping out.
>
> --
> Cheers,
> Alistair.
/Matti Aarnio
^ permalink raw reply
* [PATCH] 2.6.16: [NETFILTER] Fix Kconfig menu level for x_tables
From: Harald Welte @ 2006-02-13 11:06 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 1580 bytes --]
Hi Dave, please apply this to the 2.6.16 tree and push it to Linus.
Thanks!
[NETFILTER] Fix Kconfig menu level for x_tables
The new x_tables related Kconfig options appear at the wrong menu level
without this patch.
Signed-off-by: Harald Welte <laforge@netfilter.org>
---
commit 2d3e1788278398e3d9f33409066f3232730336a6
tree d23977bfeafb91fdbc5e5400d516ef623cde5a1d
parent 0b2d6ca5297c6343d9ae4c2259f85046e487ed01
author Harald Welte <laforge@netfilter.org> Mon, 13 Feb 2006 12:04:25 +0100
committer Harald Welte <laforge@netfilter.org> Mon, 13 Feb 2006 12:04:25 +0100
net/netfilter/Kconfig | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 99c0a0f..0e55012 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -102,8 +102,6 @@ config NF_CT_NETLINK
help
This option enables support for a netlink-based userspace interface
-endmenu
-
config NETFILTER_XTABLES
tristate "Netfilter Xtables support (required for ip_tables)"
help
@@ -361,3 +359,5 @@ config NETFILTER_XT_MATCH_TCPMSS
To compile it as a module, choose M here. If unsure, say N.
+endmenu
+
--
- Harald Welte <laforge@netfilter.org> http://netfilter.org/
============================================================================
"Fragmentation is like classful addressing -- an interesting early
architectural error that shows how much experimentation was going
on while IP was being designed." -- Paul Vixie
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* Re: 2.6.16, sk98lin out of date
From: Mws @ 2006-02-13 11:06 UTC (permalink / raw)
To: Alistair John Strachan; +Cc: linux-kernel, netdev
In-Reply-To: <200602131058.03419.s0348365@sms.ed.ac.uk>
[-- Attachment #1.1: Type: text/plain, Size: 1631 bytes --]
On Monday 13 February 2006 11:58, you wrote:
> Hi,
>
> As I'm sure the drivers/net maintainers are well aware, SysKonnect constantly
> update their sk98lin/sky2 driver without bothering to sync their changes with
> the official linux kernel.
>
> I quickly downloaded driver version 8.31 from http://www.skd.de/ today and
> used the install script to generate a diff against 2.6.16-rc3. Even after
> fixing up some DOS EOLs in the package, the diff was still well over 1.5MBs.
> This is an enormous number of changes.
>
> The reason I'm posting is that my DFI LanParty-UT SLI-D works with this
> version of the driver, but not the version 2.6.16-rc3.
>
> [alistair] 10:55 [~] dmesg | grep sk98lin
> sk98lin: Could not read VPD data.
> sk98lin: probe of 0000:01:0a.0 failed with error -5
>
> I wonder if it's worth just identifying the "quick fix" (I've seen workarounds
> for corrupt VPDs like mine) or whether a general merge up would be
> beneficial..
>
> If nobody's maintaining this driver I wouldn't mind helping out.
>
hi,
as i do have the same problem i may help you out.
at first, syskonnect did send their kernel diffs/patches but they we're rejected caused
by coding style, indention and some people thinking that things can be done better.
i personally do apply these drivers with the generate patch function of the install.sh.
there were small modifications within kernel 2.6.16 with i also sended as a diff to syskonnect,
but got not reply.
i attached the diff, maybe it helps ya out. it works with my 2 onboard marvell yukon gbit adapters.
regards
marcel
[-- Attachment #1.2: sk98lin_v8.28.1.3_adjustments_for_2.6.16.patch --]
[-- Type: text/x-diff, Size: 3376 bytes --]
diff -ruN linux/drivers/net/sk98lin/h/skdrv2nd.h linux-new/drivers/net/sk98lin/h/skdrv2nd.h
--- linux/drivers/net/sk98lin/h/skdrv2nd.h 2006-01-18 10:11:04.000000000 +0100
+++ linux-new/drivers/net/sk98lin/h/skdrv2nd.h 2005-09-29 10:26:12.000000000 +0200
@@ -61,7 +61,7 @@
#ifdef HAVE_POLL_CONTROLLER
#define SK_POLL_CONTROLLER
#define CONFIG_SK98LIN_NAPI
+#elif defined CONFIG_NET_POLL_CONTROLLER
-#elif CONFIG_NET_POLL_CONTROLLER
#define SK_POLL_CONTROLLER
#define CONFIG_SK98LIN_NAPI
#endif
diff -ruN linux/drivers/net/sk98lin/skge.c linux-new/drivers/net/sk98lin/skge.c
--- linux/drivers/net/sk98lin/skge.c 2006-01-18 10:22:44.000000000 +0100
+++ linux-new/drivers/net/sk98lin/skge.c 2005-09-29 10:26:12.000000000 +0200
@@ -107,7 +107,7 @@
static int __devinit sk98lin_init_device(struct pci_dev *pdev, const struct pci_device_id *ent);
static void sk98lin_remove_device(struct pci_dev *pdev);
#ifdef CONFIG_PM
+static int sk98lin_suspend(struct pci_dev *pdev, pm_message_t state);
-static int sk98lin_suspend(struct pci_dev *pdev, u32 state);
static int sk98lin_resume(struct pci_dev *pdev);
static void SkEnableWOMagicPacket(SK_AC *pAC, SK_IOC IoC, SK_MAC_ADDR MacAddr);
#endif
@@ -971,7 +971,7 @@
*/
static int sk98lin_suspend(
struct pci_dev *pdev, /* pointer to the device that is to suspend */
+pm_message_t state) /* what power state is desired by Linux? */
-u32 state) /* what power state is desired by Linux? */
{
struct net_device *dev = pci_get_drvdata(pdev);
DEV_NET *pNet = (DEV_NET*) dev->priv;
@@ -1024,7 +1024,7 @@
#else
pci_save_state(pdev, pAC->PciState);
#endif
+ pci_set_power_state(pdev, pci_choose_state(pdev, state)); /* set the state */
- pci_set_power_state(pdev, state); /* set the state */
return 0;
}
diff -ruN linux/drivers/net/sk98lin/sky2.c linux-new/drivers/net/sk98lin/sky2.c
--- linux/drivers/net/sk98lin/sky2.c 2006-01-18 10:51:36.000000000 +0100
+++ linux-new/drivers/net/sk98lin/sky2.c 2005-09-29 10:26:12.000000000 +0200
@@ -33,7 +33,7 @@
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
#include <linux/tcp.h>
+#include <linux/ip.h>
-
/******************************************************************************
*
* Local Function Prototypes
@@ -337,7 +337,7 @@
PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket);
POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket);
}
+#ifdef USE_SYNC_TX_QUEUE
-#if USE_SYNC_TX_QUEUE
POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket);
while (pSkPacket != NULL) {
if ((pSkFrag = pSkPacket->pFrag) != NULL) {
@@ -902,7 +902,7 @@
pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pTail = NULL;
spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.QueueLock);
+#ifdef USE_SYNC_TX_QUEUE
-#if USE_SYNC_TX_QUEUE
pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pHead = NULL;
pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pTail = NULL;
spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.QueueLock);
@@ -2311,7 +2311,7 @@
SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
("No changes for TxA%d\n", Port + 1));
}
+#ifdef USE_SYNC_TX_QUEUE
-#if USE_SYNC_TX_QUEUE
if (HW_SYNC_TX_SUPPORTED(pAC)) {
/*
** Do we have a new Done idx ?
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: 2.6.16, sk98lin out of date
From: Alistair John Strachan @ 2006-02-13 11:10 UTC (permalink / raw)
To: Matti Aarnio; +Cc: netdev, linux-kernel
In-Reply-To: <20060213110542.GZ3927@mea-ext.zmailer.org>
On Monday 13 February 2006 11:05, Matti Aarnio wrote:
> On Mon, Feb 13, 2006 at 10:58:03AM +0000, Alistair John Strachan wrote:
> > Hi,
> >
> > As I'm sure the drivers/net maintainers are well aware, SysKonnect
> > constantly update their sk98lin/sky2 driver without bothering to sync
> > their changes with the official linux kernel.
>
> My understanding is, that skge driver has superceded the sk98lin in
> most uses.
>
> There could, of course, be a change to insert vendor driver _as_is_ into
> baseline kernel with its own name.
Thanks Matti, I wasn't even aware of this driver. Might I suggest the "old"
driver be marked as such in Linux 2.6.16. I guess I must've skipped over it
because it begins with "New", and does not contain the word "Marvell", which
is indicated exclusively by lspci.
--
Cheers,
Alistair.
'No sense being pessimistic, it probably wouldn't work anyway.'
Third year Computer Science undergraduate.
1F2 55 South Clerk Street, Edinburgh, UK.
^ permalink raw reply
* [RFC,NETFILTER]: Fix xfrm lookup after SNAT
From: Patrick McHardy @ 2006-02-13 17:25 UTC (permalink / raw)
To: Herbert Xu; +Cc: Linux Netdev List, Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 358 bytes --]
I finally got around to fixing the "ip_finish_output2: No header cache
and no neighbour!" problem reported by Andi Kleen. Instead of rerouting
the packet in POST_ROUTING, we reuse the original route for the
xfrm_lookup. This introduces a small restriction (see changelog entry),
but I think it should work.
Herbert, do you see any problems with this patch?
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 3940 bytes --]
[NETFILTER]: Fix xfrm lookup after SNAT
To find out if a packet needs to be handled by IPsec after SNAT, packets
are currently rerouted in POST_ROUTING and a new xfrm lookup is done. This
breaks SNAT of non-unicast packets to non-local addresses because the
packet is routed as incoming packet and no neighbour entry is bound to the
dst_entry. In general, it seems to be a bad idea to replace the dst_entry
after the packet was already sent to the output routine because its state
might not match what's expected.
This patch changes the xfrm lookup in POST_ROUTING to re-use the original
dst_entry without routing the packet again. This means no policy routing
can be used for transport mode transforms (which keep the original route)
when packets are SNATed to match the policy, but it looks like the best
we can do for now.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit 0ebf0a6fc360cf177712ed0f21f160e0ffea9f99
tree 5bef78d70573091e5055bf4e236d7d8a443d20df
parent b6d521bde1a8bcf7e3fcad139319a427c18d8012
author Patrick McHardy <kaber@trash.net> Mon, 13 Feb 2006 18:20:04 +0100
committer Patrick McHardy <kaber@trash.net> Mon, 13 Feb 2006 18:20:04 +0100
include/linux/netfilter_ipv4.h | 2 +-
net/ipv4/netfilter.c | 41 ++++++++++++++++++++++++++++++++
net/ipv4/netfilter/ip_nat_standalone.c | 6 ++---
3 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index fdc4a95..43c09d7 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -79,7 +79,7 @@ enum nf_ip_hook_priorities {
#ifdef __KERNEL__
extern int ip_route_me_harder(struct sk_buff **pskb);
-
+extern int ip_xfrm_me_harder(struct sk_buff **pskb);
#endif /*__KERNEL__*/
#endif /*__LINUX_IP_NETFILTER_H*/
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 52a3d7c..ed42cdc 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -78,6 +78,47 @@ int ip_route_me_harder(struct sk_buff **
}
EXPORT_SYMBOL(ip_route_me_harder);
+#ifdef CONFIG_XFRM
+int ip_xfrm_me_harder(struct sk_buff **pskb)
+{
+ struct flowi fl;
+ unsigned int hh_len;
+ struct dst_entry *dst;
+
+ if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED)
+ return 0;
+ if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0)
+ return -1;
+
+ dst = (*pskb)->dst;
+ if (dst->xfrm)
+ dst = ((struct xfrm_dst *)dst)->route;
+ dst_hold(dst);
+
+ if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0)
+ return -1;
+
+ dst_release((*pskb)->dst);
+ (*pskb)->dst = dst;
+
+ /* Change in oif may mean change in hh_len. */
+ hh_len = (*pskb)->dst->dev->hard_header_len;
+ if (skb_headroom(*pskb) < hh_len) {
+ struct sk_buff *nskb;
+
+ nskb = skb_realloc_headroom(*pskb, hh_len);
+ if (!nskb)
+ return -1;
+ if ((*pskb)->sk)
+ skb_set_owner_w(nskb, (*pskb)->sk);
+ kfree_skb(*pskb);
+ *pskb = nskb;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(ip_xfrm_me_harder);
+#endif
+
void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
EXPORT_SYMBOL(ip_nat_decode_session);
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 92c5499..7c3f7d3 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -235,19 +235,19 @@ ip_nat_out(unsigned int hooknum,
return NF_ACCEPT;
ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+#ifdef CONFIG_XFRM
if (ret != NF_DROP && ret != NF_STOLEN
&& (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.src.ip !=
ct->tuplehash[!dir].tuple.dst.ip
-#ifdef CONFIG_XFRM
|| ct->tuplehash[dir].tuple.src.u.all !=
ct->tuplehash[!dir].tuple.dst.u.all
-#endif
)
- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
}
+#endif
return ret;
}
^ permalink raw reply related
* Re: 2.6.16, sk98lin out of date
From: Lee Revell @ 2006-02-13 19:03 UTC (permalink / raw)
To: Mws; +Cc: Alistair John Strachan, linux-kernel, netdev
In-Reply-To: <200602131206.26285.mws@twisted-brains.org>
On Mon, 2006-02-13 at 12:06 +0100, Mws wrote:
> hi,
> as i do have the same problem i may help you out.
>
> at first, syskonnect did send their kernel diffs/patches but they
> we're rejected caused
> by coding style, indention and some people thinking that things can be
> done better.
Haha, they didn't like the LKML code review so they just stopped sending
patches? Classic. Remind me not to buy their gear.
Lee
^ permalink raw reply
* Re: 2.6.16, sk98lin out of date
From: Daniel Drake @ 2006-02-13 19:48 UTC (permalink / raw)
To: Alistair John Strachan; +Cc: Matti Aarnio, netdev, linux-kernel
In-Reply-To: <200602131110.34212.s0348365@sms.ed.ac.uk>
Alistair John Strachan wrote:
> Thanks Matti, I wasn't even aware of this driver. Might I suggest the
> "old" driver be marked as such in Linux 2.6.16. I guess I must've
> skipped over it because it begins with "New", and does not contain
> the word "Marvell", which is indicated exclusively by lspci.
I changed the help text of all 3 drivers (sk98lin/skge/sky2) to
point out which ones are/aren't interchangable in 2.6.16. The situation
is a little confusing.
The reason that the sk98lin diff is so huge is because SysKonnect
effectively added support for a substantially different range of cards
(Yukon-2) into the existing driver. This is far from the driver quality
required for the kernel today, so Stephen Hemminger (skge author) wrote
a new driver (sky2) for the Yukon-2 range.
The long term plan is to obsolete and remove sk98lin, but we aren't
ready yet: skge issues pop up every month or two, and sky2 is young.
Stephen's own words:
> I applaud the initiative, but this it is too premature to obsolete
> the existing driver. There may be lots of chip versions and other
> variables that make the existing driver a better choice.
Daniel
^ permalink raw reply
* Re: 2.6.16, sk98lin out of date
From: Willy Tarreau @ 2006-02-13 20:34 UTC (permalink / raw)
To: Lee Revell; +Cc: Mws, Alistair John Strachan, linux-kernel, netdev
In-Reply-To: <1139857394.3202.38.camel@mindpipe>
On Mon, Feb 13, 2006 at 02:03:14PM -0500, Lee Revell wrote:
> On Mon, 2006-02-13 at 12:06 +0100, Mws wrote:
> > hi,
> > as i do have the same problem i may help you out.
> >
> > at first, syskonnect did send their kernel diffs/patches but they
> > we're rejected caused
> > by coding style, indention and some people thinking that things can be
> > done better.
>
> Haha, they didn't like the LKML code review so they just stopped sending
> patches? Classic. Remind me not to buy their gear.
Lee, it's not always that simple. When you submit one driver, sometimes
reviewers tell you that for whatever reason your driver's structure is
wrong and it has to be changed a lot (and sometimes they're right of
course). But when you don't have enough ressource to do the job twice,
the best you can do is to maintain it out of tree, which is already a
pain. I'm not saying that it is what happened with their driver, I don't
know the history. However, I found your reaction somewhat hasty. I
personally would prefer to offer time and help before deciding that
I don't want anyone's products on this basis. It's not as if they
did not release their driver's source !
Cheers,
Willy
^ permalink raw reply
* Re: 2.6.16, sk98lin out of date
From: Lee Revell @ 2006-02-13 20:40 UTC (permalink / raw)
To: Willy Tarreau; +Cc: Mws, Alistair John Strachan, linux-kernel, netdev
In-Reply-To: <20060213203434.GI11380@w.ods.org>
On Mon, 2006-02-13 at 21:34 +0100, Willy Tarreau wrote:
> On Mon, Feb 13, 2006 at 02:03:14PM -0500, Lee Revell wrote:
> > On Mon, 2006-02-13 at 12:06 +0100, Mws wrote:
> > > hi,
> > > as i do have the same problem i may help you out.
> > >
> > > at first, syskonnect did send their kernel diffs/patches but they
> > > we're rejected caused
> > > by coding style, indention and some people thinking that things can be
> > > done better.
> >
> > Haha, they didn't like the LKML code review so they just stopped sending
> > patches? Classic. Remind me not to buy their gear.
>
> Lee, it's not always that simple. When you submit one driver, sometimes
> reviewers tell you that for whatever reason your driver's structure is
> wrong and it has to be changed a lot (and sometimes they're right of
> course). But when you don't have enough ressource to do the job twice,
> the best you can do is to maintain it out of tree, which is already a
> pain. I'm not saying that it is what happened with their driver, I don't
> know the history. However, I found your reaction somewhat hasty. I
> personally would prefer to offer time and help before deciding that
> I don't want anyone's products on this basis. It's not as if they
> did not release their driver's source!
True, that was a little harsh. I just find it a little sad that all
these vendors insist on throwing away months of work rather than simply
researching what the linux kernel coding standards are ahead of time.
Lee
^ 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