not generating icmp's

Rusty Russell rusty@linuxcare.com.au
Sun, 04 Jun 2000 19:34:30 +1000


In message <Pine.LNX.4.21.0006031627430.1060-100000@tux.rsn.hk-r.se> you write:
> Hi

Hi Martin (and Trever).

	See latest CVS patch (ICMP generation bug), or just apply this
excerpt:

diff -urN -X /tmp/file0hDgaG --minimal linux-2.4.0-test1-official/include/linux/netfilter_ipv4/ip_conntrack_core.h working-2.4.0-test1/include/linux/netfilter_ipv4/ip_conntrack_core.h
--- linux-2.4.0-test1-official/include/linux/netfilter_ipv4/ip_conntrack_core.h	Fri Jun  2 15:09:24 2000
+++ working-2.4.0-test1/include/linux/netfilter_ipv4/ip_conntrack_core.h	Sat Jun  3 05:57:05 2000
@@ -22,7 +22,8 @@
 
 /* Returns conntrack if it dealt with ICMP, and filled in skb->nfct */
 extern struct ip_conntrack *icmp_error_track(struct sk_buff *skb,
-					     enum ip_conntrack_info *ctinfo);
+					     enum ip_conntrack_info *ctinfo,
+					     unsigned int hooknum);
 extern int get_tuple(const struct iphdr *iph, size_t len,
 		     struct ip_conntrack_tuple *tuple,
 		     struct ip_conntrack_protocol *protocol);
diff -urN -X /tmp/file0hDgaG --minimal linux-2.4.0-test1-official/net/ipv4/netfilter/ip_conntrack_core.c working-2.4.0-test1/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.0-test1-official/net/ipv4/netfilter/ip_conntrack_core.c	Fri May 12 12:51:52 2000
+++ working-2.4.0-test1/net/ipv4/netfilter/ip_conntrack_core.c	Sat Jun  3 04:28:21 2000
@@ -297,7 +289,9 @@
 
 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */
 struct ip_conntrack *
-icmp_error_track(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
+icmp_error_track(struct sk_buff *skb,
+		 enum ip_conntrack_info *ctinfo,
+		 unsigned int hooknum)
 {
 	const struct iphdr *iph;
 	struct icmphdr *hdr;
@@ -353,7 +354,11 @@
 		DEBUGP("icmp_error_track: no match\n");
 		return NULL;
 	}
-	if (!(h->ctrack->status & IPS_CONFIRMED)) {
+
+	/* REJECT target does this commonly, so allow locally
+           generated ICMP errors --RR */
+	if (!(h->ctrack->status & IPS_CONFIRMED)
+	    && hooknum != NF_IP_LOCAL_OUT) {
 		DEBUGP("icmp_error_track: unconfirmed\n");
 		ip_conntrack_put(h->ctrack);
 		return NULL;
@@ -623,7 +647,7 @@
 
 	/* It may be an icmp error... */
 	if ((*pskb)->nh.iph->protocol != IPPROTO_ICMP 
-	    || !(ct = icmp_error_track(*pskb, &ctinfo))) {
+	    || !(ct = icmp_error_track(*pskb, &ctinfo, hooknum))) {
 		if (!(ct = resolve_normal_ct(*pskb, proto, &ctinfo))) {
 			/* Not valid part of a connection */
 			return NF_ACCEPT;
diff -urN -X /tmp/file0hDgaG --minimal linux-2.4.0-test1-official/net/ipv4/netfilter/ip_fw_compat_masq.c working-2.4.0-test1/net/ipv4/netfilter/ip_fw_compat_masq.c
--- linux-2.4.0-test1-official/net/ipv4/netfilter/ip_fw_compat_masq.c	Fri May 12 12:51:52 2000
+++ working-2.4.0-test1/net/ipv4/netfilter/ip_fw_compat_masq.c	Sat Jun  3 06:08:38 2000
@@ -114,15 +114,21 @@
 	switch (iph->protocol) {
 	case IPPROTO_ICMP:
 		/* ICMP errors. */
-		if ((ct = icmp_error_track(*pskb, &ctinfo))) {
+		ct = icmp_error_track(*pskb, &ctinfo, NF_IP_PRE_ROUTING);
+		if (ct) {
 			icmp_reply_translation(*pskb, ct,
 					       NF_IP_PRE_ROUTING,
 					       CTINFO2DIR(ctinfo));
+			icmp_reply_translation(*pskb, ct,
+					       NF_IP_POST_ROUTING,
+					       CTINFO2DIR(ctinfo));
 			return NF_ACCEPT;
 		}
 		/* Fall thru... */
 	case IPPROTO_TCP:
 	case IPPROTO_UDP:
+		IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
+
 		if (!get_tuple(iph, (*pskb)->len, &tuple, protocol)) {
 			if (net_ratelimit())
 				printk("ip_fw_compat_masq: Can't get tuple\n");

Rusty.
--
Hacking time.