[netfilter-cvslog] r4246 - trunk/patch-o-matic-ng/patchlets/raw

laforge at netfilter.org laforge at netfilter.org
Sun Aug 28 13:58:01 CEST 2005


Author: laforge at netfilter.org
Date: 2005-08-28 13:58:00 +0200 (Sun, 28 Aug 2005)
New Revision: 4246

Added:
   trunk/patch-o-matic-ng/patchlets/raw/linux-2.4.31.patch
Log:
Fix raw patch for linux-2.4.31:
- fixed crash because of wrong refcnt [Pablo Neira]
- rediffed against 2.4.31 vanilla
- translated some comments into english ;)
(Roberto Nibali)


Added: trunk/patch-o-matic-ng/patchlets/raw/linux-2.4.31.patch
===================================================================
--- trunk/patch-o-matic-ng/patchlets/raw/linux-2.4.31.patch	2005-08-28 08:09:44 UTC (rev 4245)
+++ trunk/patch-o-matic-ng/patchlets/raw/linux-2.4.31.patch	2005-08-28 11:58:00 UTC (rev 4246)
@@ -0,0 +1,260 @@
+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);




More information about the netfilter-cvslog mailing list