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+(*)