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

Reply via email to