From: Roberto Nibali <ratz@tac.ch>
To: Netfilter Developers <netfilter-devel@lists.netfilter.org>
Subject: [PATCH 2.4] update raw patch in POM take 2
Date: Wed, 29 Jun 2005 17:07:57 +0200 [thread overview]
Message-ID: <42C2B94D.4070401@tac.ch> (raw)
[-- Attachment #1: Type: text/plain, Size: 760 bytes --]
Hello,
This is the cleaned up and fixed patch which should go into pom.
Changelog:
- fixed crash because of wrong refcnt [Pablo Neira]
- rediffed against 2.4.31 vanilla
- translated some comments into english ;)
This patch has been compile-tested and works together with the nf_reset patch.
Please consider applying to POM, thanks.
Best regards,
Roberto Nibali, ratz
--
-------------------------------------------------------------
addr://Rathausgasse 31, CH-5001 Aarau tel://++41 62 823 9355
http://www.terreactive.com fax://++41 62 823 9356
-------------------------------------------------------------
terreActive AG Wir sichern Ihren Erfolg
-------------------------------------------------------------
[-- Attachment #2: linux-2.4.31-raw-table-for-pom-1.diff --]
[-- Type: text/plain, Size: 9910 bytes --]
diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ip_conntrack.h
--- linux-2.4.31-orig/include/linux/netfilter_ipv4/ip_conntrack.h 2005-04-04 03:42:20 +0200
+++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ip_conntrack.h 2005-06-29 12:23:37 +0200
@@ -249,6 +249,9 @@
/* Call me when a conntrack is destroyed. */
extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack);
+/* Fake conntrack entry for untracked connections */
+extern struct ip_conntrack ip_conntrack_untracked;
+
/* Returns new sk_buff, or NULL */
struct sk_buff *
ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user);
diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_conntrack.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_conntrack.h
--- linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_conntrack.h 2002-11-29 00:53:15 +0100
+++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_conntrack.h 2005-06-29 12:23:37 +0200
@@ -10,6 +10,7 @@
#define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
#define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
+#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
#define IPT_CONNTRACK_STATE 0x01
diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_state.h linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_state.h
--- linux-2.4.31-orig/include/linux/netfilter_ipv4/ipt_state.h 2000-04-14 18:37:20 +0200
+++ linux-2.4.31-pab2/include/linux/netfilter_ipv4/ipt_state.h 2005-06-29 12:23:37 +0200
@@ -3,6 +3,7 @@
#define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define IPT_STATE_INVALID (1 << 0)
+#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
struct ipt_state_info
{
diff -Nur linux-2.4.31-orig/include/linux/netfilter_ipv4.h linux-2.4.31-pab2/include/linux/netfilter_ipv4.h
--- linux-2.4.31-orig/include/linux/netfilter_ipv4.h 2002-02-25 20:38:13 +0100
+++ linux-2.4.31-pab2/include/linux/netfilter_ipv4.h 2005-06-29 12:23:37 +0200
@@ -51,6 +51,8 @@
enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
+ NF_IP_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP_PRI_RAW = -300,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_core.c 2005-04-04 03:42:20 +0200
+++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_core.c 2005-06-29 12:42:09 +0200
@@ -65,6 +65,7 @@
struct list_head *ip_conntrack_hash;
static kmem_cache_t *ip_conntrack_cachep;
static LIST_HEAD(unconfirmed);
+struct ip_conntrack ip_conntrack_untracked;
extern struct ip_conntrack_protocol ip_conntrack_generic_protocol;
@@ -823,6 +824,19 @@
int set_reply;
int ret;
+ /* Previously seen (loopback or untracked)? Ignore. */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+
+ /* Never happen */
+ if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) {
+ if (net_ratelimit()) {
+ printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n",
+ (*pskb)->nh.iph->protocol, hooknum);
+ }
+ return NF_DROP;
+ }
+
/* FIXME: Do this right please. --RR */
(*pskb)->nfcache |= NFC_UNKNOWN;
@@ -841,21 +855,6 @@
}
#endif
- /* Previously seen (loopback)? Ignore. Do this before
- fragment check. */
- if ((*pskb)->nfct)
- return NF_ACCEPT;
-
- /* Gather fragments. */
- if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
- *pskb = ip_ct_gather_frags(*pskb,
- hooknum == NF_IP_PRE_ROUTING ?
- IP_DEFRAG_CONNTRACK_IN :
- IP_DEFRAG_CONNTRACK_OUT);
- if (!*pskb)
- return NF_STOLEN;
- }
-
proto = ip_ct_find_proto((*pskb)->nh.iph->protocol);
/* It may be an icmp error... */
@@ -1392,6 +1391,8 @@
schedule();
goto i_see_dead_people;
}
+ while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1)
+ schedule();
kmem_cache_destroy(ip_conntrack_cachep);
vfree(ip_conntrack_hash);
@@ -1459,6 +1460,18 @@
/* For use by ipt_REJECT */
ip_ct_attach = ip_conntrack_attach;
+
+ /* Set up fake conntrack:
+ - never to be deleted, not in any hashes */
+ atomic_set(&ip_conntrack_untracked.ct_general.use, 1);
+ /* - and let it look as if it's a confirmed connection */
+ set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status);
+ /* - and prepare the ctinfo field for REJECT/NAT. */
+ ip_conntrack_untracked.infos[IP_CT_NEW].master =
+ ip_conntrack_untracked.infos[IP_CT_RELATED].master =
+ ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master =
+ &ip_conntrack_untracked.ct_general;
+
return ret;
err_free_hash:
diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.31-orig/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-04-04 03:42:20 +0200
+++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-06-29 12:23:37 +0200
@@ -189,6 +189,29 @@
return ip_conntrack_confirm(*pskb);
}
+static unsigned int ip_conntrack_defrag(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* Previously seen (loopback)? Ignore. Do this before
+ * fragment check. */
+ if ((*pskb)->nfct)
+ return NF_ACCEPT;
+
+ /* Gather fragments. */
+ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
+ *pskb = ip_ct_gather_frags(*pskb,
+ hooknum == NF_IP_PRE_ROUTING ?
+ IP_DEFRAG_CONNTRACK_IN :
+ IP_DEFRAG_CONNTRACK_OUT);
+ if (!*pskb)
+ return NF_STOLEN;
+ }
+ return NF_ACCEPT;
+}
+
static unsigned int ip_refrag(unsigned int hooknum,
struct sk_buff **pskb,
const struct net_device *in,
@@ -230,9 +253,15 @@
/* Connection tracking may drop packets, but never alters them, so
make it the first hook. */
+static struct nf_hook_ops ip_conntrack_defrag_ops
+= { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_PRE_ROUTING,
+ NF_IP_PRI_CONNTRACK_DEFRAG };
static struct nf_hook_ops ip_conntrack_in_ops
= { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
NF_IP_PRI_CONNTRACK };
+static struct nf_hook_ops ip_conntrack_defrag_local_out_ops
+= { { NULL, NULL }, ip_conntrack_defrag, PF_INET, NF_IP_LOCAL_OUT,
+ NF_IP_PRI_CONNTRACK_DEFRAG };
static struct nf_hook_ops ip_conntrack_local_out_ops
= { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
NF_IP_PRI_CONNTRACK };
@@ -353,10 +382,21 @@
if (!proc) goto cleanup_init;
proc->owner = THIS_MODULE;
+ ret = nf_register_hook(&ip_conntrack_defrag_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register pre-routing defrag hook.\n");
+ goto cleanup_proc;
+ }
+ ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register local_out defrag hook.\n");
+ goto cleanup_defragops;
+ }
+
ret = nf_register_hook(&ip_conntrack_in_ops);
if (ret < 0) {
printk("ip_conntrack: can't register pre-routing hook.\n");
- goto cleanup_proc;
+ goto cleanup_defraglocalops;
}
ret = nf_register_hook(&ip_conntrack_local_out_ops);
if (ret < 0) {
@@ -394,6 +434,10 @@
nf_unregister_hook(&ip_conntrack_local_out_ops);
cleanup_inops:
nf_unregister_hook(&ip_conntrack_in_ops);
+ cleanup_defraglocalops:
+ nf_unregister_hook(&ip_conntrack_defrag_local_out_ops);
+ cleanup_defragops:
+ nf_unregister_hook(&ip_conntrack_defrag_ops);
cleanup_proc:
proc_net_remove("ip_conntrack");
cleanup_init:
@@ -483,5 +527,6 @@
EXPORT_SYMBOL(ip_conntrack_expect_list);
EXPORT_SYMBOL(ip_conntrack_lock);
EXPORT_SYMBOL(ip_conntrack_hash);
+EXPORT_SYMBOL(ip_conntrack_untracked);
EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
EXPORT_SYMBOL_GPL(ip_conntrack_put);
diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c linux-2.4.31-pab2/net/ipv4/netfilter/ip_nat_core.c
--- linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c 2005-04-04 03:42:20 +0200
+++ linux-2.4.31-pab2/net/ipv4/netfilter/ip_nat_core.c 2005-06-29 12:23:37 +0200
@@ -1024,6 +1024,10 @@
IP_NF_ASSERT(ip_conntrack_destroyed == NULL);
ip_conntrack_destroyed = &ip_nat_cleanup_conntrack;
+ /* Initialize fake conntrack so that NAT will skip it */
+ ip_conntrack_untracked.nat.info.initialized |=
+ (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST);
+
return 0;
}
diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ipt_conntrack.c linux-2.4.31-pab2/net/ipv4/netfilter/ipt_conntrack.c
--- linux-2.4.31-orig/net/ipv4/netfilter/ipt_conntrack.c 2004-02-18 14:36:32 +0100
+++ linux-2.4.31-pab2/net/ipv4/netfilter/ipt_conntrack.c 2005-06-29 12:23:37 +0200
@@ -27,7 +27,9 @@
#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
- if (ct)
+ if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
+ statebit = IPT_CONNTRACK_STATE_UNTRACKED;
+ else if (ct)
statebit = IPT_CONNTRACK_STATE_BIT(ctinfo);
else
statebit = IPT_CONNTRACK_STATE_INVALID;
diff -Nur linux-2.4.31-orig/net/ipv4/netfilter/ipt_state.c linux-2.4.31-pab2/net/ipv4/netfilter/ipt_state.c
--- linux-2.4.31-orig/net/ipv4/netfilter/ipt_state.c 2004-02-18 14:36:32 +0100
+++ linux-2.4.31-pab2/net/ipv4/netfilter/ipt_state.c 2005-06-29 12:23:37 +0200
@@ -21,7 +21,9 @@
enum ip_conntrack_info ctinfo;
unsigned int statebit;
- if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
+ if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW])
+ statebit = IPT_STATE_UNTRACKED;
+ else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo))
statebit = IPT_STATE_INVALID;
else
statebit = IPT_STATE_BIT(ctinfo);
next reply other threads:[~2005-06-29 15:07 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-29 15:07 Roberto Nibali [this message]
2005-08-28 11:56 ` [PATCH 2.4] update raw patch in POM take 2 Harald Welte
2005-10-27 14:08 ` Roberto Nibali
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42C2B94D.4070401@tac.ch \
--to=ratz@tac.ch \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.