This is the same bugfix as in my previous mail, this time for 2.5.x: Patch again by James Morris.
Please apply, Thanks diff -urN linux-2.5.8-pre3.orig/include/linux/skbuff.h linux-2.5.8-pre3-nf-01/include/linux/skbuff.h --- linux-2.5.8-pre3.orig/include/linux/skbuff.h Thu Apr 11 03:09:33 2002 +++ linux-2.5.8-pre3-nf-01/include/linux/skbuff.h Fri Apr 12 00:27:15 2002 @@ -1145,6 +1145,17 @@ if (nfct) atomic_inc(&nfct->master->use); } +static inline struct nf_ct_info * +skb_nf_ct(struct sk_buff *skb) +{ + return skb->nfct; +} +#else +static inline struct nf_ct_info * +skb_nf_ct(struct sk_buff *skb) +{ + return NULL; +} #endif #endif /* __KERNEL__ */ diff -urN linux-2.5.8-pre3.orig/include/net/ip.h linux-2.5.8-pre3-nf-01/include/net/ip.h --- linux-2.5.8-pre3.orig/include/net/ip.h Sun Mar 24 12:30:00 2002 +++ linux-2.5.8-pre3-nf-01/include/net/ip.h Fri Apr 12 00:27:15 2002 @@ -67,6 +67,7 @@ extern struct ip_ra_chain *ip_ra_chain; extern rwlock_t ip_ra_lock; +struct nf_ct_info; /* IP flags. */ #define IP_CE 0x8000 /* Flag: "Congestion" */ @@ -107,7 +108,8 @@ unsigned length, struct ipcm_cookie *ipc, struct rtable *rt, - int flags); + int flags, + struct nf_ct_info *nfct); /* * Map a multicast IP onto multicast MAC for type Token Ring. diff -urN linux-2.5.8-pre3.orig/net/ipv4/icmp.c linux-2.5.8-pre3-nf-01/net/ipv4/icmp.c --- linux-2.5.8-pre3.orig/net/ipv4/icmp.c Thu Apr 11 03:09:33 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/icmp.c Fri Apr 12 00:27:15 2002 @@ -370,7 +370,7 @@ icmp_param->data.icmph.code)) { ip_build_xmit(sk, icmp_glue_bits, icmp_param, icmp_param->data_len+icmp_param->head_len, - &ipc, rt, MSG_DONTWAIT); + &ipc, rt, MSG_DONTWAIT, NULL); } ip_rt_put(rt); out: @@ -528,7 +529,7 @@ ip_build_xmit(icmp_socket->sk, icmp_glue_bits, &icmp_param, icmp_param.data_len+sizeof(struct icmphdr), - &ipc, rt, MSG_DONTWAIT); + &ipc, rt, MSG_DONTWAIT, skb_nf_ct(skb_in)); ende: ip_rt_put(rt); diff -urN linux-2.5.8-pre3.orig/net/ipv4/ip_output.c linux-2.5.8-pre3-nf-01/net/ipv4/ip_output.c --- linux-2.5.8-pre3.orig/net/ipv4/ip_output.c Sun Mar 24 12:30:00 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/ip_output.c Fri Apr 12 00:27:15 2002 @@ -407,6 +407,22 @@ return -EHOSTUNREACH; } +#ifdef CONFIG_NETFILTER +/* If the original packet is part of a connection, but the connection + is not confirmed, our manufactured reply will not be associated + with it, so we need to do this manually. */ +static void nfct_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct) +{ + void (*attach)(struct sk_buff *, struct nf_ct_info *); + + /* Avoid module unload race with ip_ct_attach being NULLed out */ + if (nfct && (attach = ip_ct_attach) != NULL) + attach(new_skb, nfct); +} +#else +static void nfct_attach(struct sk_buff *new_skb, struct nf_ct_info *nfct) { } +#endif + /* * Build and send a packet, with as little as one copy * @@ -436,7 +452,8 @@ unsigned length, struct ipcm_cookie *ipc, struct rtable *rt, - int flags) + int flags, + struct nf_ct_info *nfct) { struct inet_opt *inet = inet_sk(sk); unsigned int fraglen, maxfraglen, fragheaderlen; @@ -602,6 +619,7 @@ nfrags++; + nfct_attach(skb, nfct); err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev, output_maybe_reroute); if (err) { @@ -636,7 +654,8 @@ unsigned length, struct ipcm_cookie *ipc, struct rtable *rt, - int flags) + int flags, + struct nf_ct_info *nfct) { struct inet_opt *inet = inet_sk(sk); int err; @@ -656,7 +675,7 @@ * Check for slow path. */ if (length > rt->u.dst.pmtu || ipc->opt != NULL) - return ip_build_xmit_slow(sk,getfrag,frag,length,ipc,rt,flags); + return +ip_build_xmit_slow(sk,getfrag,frag,length,ipc,rt,flags,nfct); } else { if (length > rt->u.dst.dev->mtu) { ip_local_error(sk, EMSGSIZE, rt->rt_dst, inet->dport, @@ -715,6 +734,7 @@ if (err) goto error_fault; + nfct_attach(skb, nfct); err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, output_maybe_reroute); if (err > 0) @@ -983,7 +1003,8 @@ inet->tos = skb->nh.iph->tos; sk->priority = skb->priority; sk->protocol = skb->nh.iph->protocol; - ip_build_xmit(sk, ip_reply_glue_bits, arg, len, &ipc, rt, MSG_DONTWAIT); + ip_build_xmit(sk, ip_reply_glue_bits, arg, len, &ipc, rt, MSG_DONTWAIT, + NULL); bh_unlock_sock(sk); ip_rt_put(rt); diff -urN linux-2.5.8-pre3.orig/net/ipv4/netfilter/ip_nat_core.c linux-2.5.8-pre3-nf-01/net/ipv4/netfilter/ip_nat_core.c --- linux-2.5.8-pre3.orig/net/ipv4/netfilter/ip_nat_core.c Thu Apr 11 03:09:33 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/netfilter/ip_nat_core.c Fri Apr 12 00:27:22 +2002 @@ -857,6 +857,18 @@ /* not reached */ } +/* + * Decide whether to map inner header of an ICMP reply, including when + * we generate the reply ourselves. + */ +static inline int +map_innards(unsigned int maniphook, unsigned int hooknum) +{ + return (maniphook == opposite_hook[hooknum] + || (hooknum == NF_IP_LOCAL_OUT + && HOOK2MANIP(maniphook) == IP_NAT_MANIP_SRC)); +} + unsigned int icmp_reply_translation(struct sk_buff *skb, struct ip_conntrack *conntrack, @@ -914,7 +926,7 @@ packet, except it was never src/dst reversed, so where we would normally apply a dst manip, we apply a src, and vice versa. */ - if (info->manips[i].hooknum == opposite_hook[hooknum]) { + if (map_innards(info->manips[i].hooknum, hooknum)) { DEBUGP("icmp_reply: inner %s -> %u.%u.%u.%u %u\n", info->manips[i].maniptype == IP_NAT_MANIP_SRC ? "DST" : "SRC", diff -urN linux-2.5.8-pre3.orig/net/ipv4/netfilter/ipt_REJECT.c linux-2.5.8-pre3-nf-01/net/ipv4/netfilter/ipt_REJECT.c --- linux-2.5.8-pre3.orig/net/ipv4/netfilter/ipt_REJECT.c Sun Mar 24 12:30:00 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/netfilter/ipt_REJECT.c Fri Apr 12 00:27:15 +2002 @@ -32,7 +32,8 @@ attach(new_skb, nfct); } -/* Send RST reply */ +/* Send RST reply: we want to use the dest as the RST src ip, so can't + use normal RST routine. --RR */ static void send_reset(struct sk_buff *oldskb, int local) { struct sk_buff *nskb; @@ -150,6 +151,7 @@ kfree_skb(nskb); } +#if 0 static void send_unreach(struct sk_buff *skb_in, int code) { struct iphdr *iph; @@ -267,6 +269,12 @@ NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev, ip_finish_output); } +#else +static void send_unreach(struct sk_buff *skb_in, int code) +{ + icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0); +} +#endif static unsigned int reject(struct sk_buff **pskb, unsigned int hooknum, diff -urN linux-2.5.8-pre3.orig/net/ipv4/raw.c linux-2.5.8-pre3-nf-01/net/ipv4/raw.c --- linux-2.5.8-pre3.orig/net/ipv4/raw.c Sun Mar 24 12:30:00 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/raw.c Fri Apr 12 00:27:15 2002 @@ -431,7 +431,8 @@ if (!ipc.addr) ipc.addr = rt->rt_dst; err = ip_build_xmit(sk, inet->hdrincl ? raw_getrawfrag : - raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags); + raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags, + NULL); done: if (free) diff -urN linux-2.5.8-pre3.orig/net/ipv4/udp.c linux-2.5.8-pre3-nf-01/net/ipv4/udp.c --- linux-2.5.8-pre3.orig/net/ipv4/udp.c Thu Apr 11 03:09:33 2002 +++ linux-2.5.8-pre3-nf-01/net/ipv4/udp.c Fri Apr 12 00:27:15 2002 @@ -559,7 +559,7 @@ (sk->no_check == UDP_CSUM_NOXMIT ? udp_getfrag_nosum : udp_getfrag), - &ufh, ulen, &ipc, rt, msg->msg_flags); + &ufh, ulen, &ipc, rt, msg->msg_flags, NULL); out: ip_rt_put(rt); -- Live long and prosper - Harald Welte / [EMAIL PROTECTED] http://www.gnumonks.org/ ============================================================================ GCS/E/IT d- s-: a-- C+++ UL++++$ P+++ L++++$ E--- W- N++ o? K- w--- O- M+ V-- PS++ PE-- Y++ PGP++ t+ 5-- !X !R tv-- b+++ !DI !D G+ e* h--- r++ y+(*)