--- linux-2.2.15pre16/include/net/ip_masq.h.orig Mon Mar 20 14:37:18 2000 +++ linux/include/net/ip_masq.h Sat Apr 1 11:50:53 2000 @@ -129,7 +129,7 @@ */ extern int ip_fw_masquerade(struct sk_buff **, __u32 maddr); extern int ip_fw_masq_icmp(struct sk_buff **, __u32 maddr); -extern int ip_fw_unmasq_icmp(struct sk_buff *); +extern int ip_fw_unmasq_icmp(struct sk_buff *, __u32 maddr); extern int ip_fw_demasquerade(struct sk_buff **); /* @@ -209,7 +209,7 @@ * service routine(s). */ -extern struct ip_masq * ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); +extern struct ip_masq * ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port, __u32 maddr); extern struct ip_masq * ip_masq_in_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); extern int ip_masq_listen(struct ip_masq *); @@ -222,12 +222,12 @@ iph->daddr, portp[1]); } -static __inline__ struct ip_masq * ip_masq_out_get_iph(const struct iphdr *iph) +static __inline__ struct ip_masq * ip_masq_out_get_iph(const struct iphdr *iph, __u32 maddr) { const __u16 *portp = (__u16 *)&(((char *)iph)[iph->ihl*4]); return ip_masq_out_get(iph->protocol, iph->saddr, portp[0], - iph->daddr, portp[1]); + iph->daddr, portp[1], maddr); } extern void ip_masq_put(struct ip_masq *ms); --- linux-2.2.15pre16/net/ipv4/icmp.c.orig Mon Mar 20 14:39:05 2000 +++ linux/net/ipv4/icmp.c Sat Apr 1 10:55:54 2000 @@ -592,7 +592,7 @@ #endif #ifdef CONFIG_IP_MASQUERADE if (type==ICMP_DEST_UNREACH && IPCB(skb_in)->flags&IPSKB_MASQUERADED) { - ip_fw_unmasq_icmp(skb_in); + ip_fw_unmasq_icmp(skb_in, rt->key.dst); } #endif --- linux-2.2.15pre16/net/ipv4/ip_masq.c.orig Mon Mar 20 14:39:06 2000 +++ linux/net/ipv4/ip_masq.c Sat Apr 1 12:17:46 2000 @@ -578,7 +578,8 @@ for (e=l->next; e!=l; e=e->next) { ms = list_entry(e, struct ip_masq, m_list); if (protocol==ms->protocol && - (d_addr==ms->maddr && d_port==ms->mport) && + (d_port==ms->mport) && + (d_addr==ms->maddr || ms->flags & MASQ_DADDR_PASS) && (s_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) && (s_port==ms->dport || ms->flags & MASQ_DPORT_PASS) ) { @@ -620,7 +621,7 @@ * Caller must lock tables */ -static struct ip_masq * __ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) +static struct ip_masq * __ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port, __u32 maddr) { unsigned hash; struct ip_masq *ms = NULL; @@ -661,7 +662,8 @@ if (protocol == ms->protocol && s_addr == ms->saddr && s_port == ms->sport && (d_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) && - (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS) + (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS) && + (maddr==ms->maddr || ms->flags & MASQ_DADDR_PASS) ) { IP_MASQ_DEBUG(2, "lk/out1 %d %08X:%04hX->%08X:%04hX OK\n", protocol, @@ -687,7 +689,8 @@ protocol == ms->protocol && s_addr == ms->saddr && (d_addr==ms->daddr || ms->flags & MASQ_DADDR_PASS) && - (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS) + (d_port==ms->dport || ms->flags & MASQ_DPORT_PASS) && + (maddr==ms->maddr || ms->flags & MASQ_DADDR_PASS) ) { IP_MASQ_DEBUG(2, "lk/out2 %d %08X:%04hX->%08X:%04hX OK\n", protocol, @@ -740,12 +743,12 @@ } #endif -struct ip_masq * ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) +struct ip_masq * ip_masq_out_get(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port, __u32 maddr) { struct ip_masq *ms; read_lock(&__ip_masq_lock); - ms = __ip_masq_out_get(protocol, s_addr, s_port, d_addr, d_port); + ms = __ip_masq_out_get(protocol, s_addr, s_port, d_addr, d_port, maddr); read_unlock(&__ip_masq_lock); if (ms) @@ -1220,7 +1223,7 @@ ntohl(iph->saddr), ntohs(h.portp[0]), ntohl(iph->daddr), ntohs(h.portp[1])); - ms = ip_masq_out_get_iph(iph); + ms = ip_masq_out_get_iph(iph, maddr); if (ms!=NULL) { /* @@ -1270,6 +1273,7 @@ */ ms->dport = h.portp[1]; ms->daddr = iph->daddr; + ms->maddr = iph->saddr; } } else { /* @@ -1408,7 +1412,7 @@ * ip_fw_masquerade(). * */ -int ip_fw_unmasq_icmp(struct sk_buff *skb) { +int ip_fw_unmasq_icmp(struct sk_buff *skb, __u32 maddr) { struct ip_masq *ms; struct iphdr *iph = skb->nh.iph; __u16 *portp = (__u16 *)&(((char *)iph)[iph->ihl*4]); @@ -1427,7 +1431,8 @@ read_lock(&__ip_masq_lock); ms = __ip_masq_out_get(iph->protocol, iph->daddr, portp[1], - iph->saddr, portp[0]); + iph->saddr, portp[0], + maddr); read_unlock(&__ip_masq_lock); if (ms) { IP_MASQ_DEBUG(1, "Incoming frag_need rewrited from %d.%d.%d.%d to %d.%d.%d.%d\n", @@ -1498,7 +1503,7 @@ iph->saddr, icmp_id(icmph), iph->daddr, - icmp_hv_req(icmph)); + icmp_hv_req(icmph), maddr); if (ms == NULL) { ms = ip_masq_new(iph->protocol, maddr, 0, @@ -1588,7 +1593,7 @@ ciph->daddr, icmp_id(cicmph), ciph->saddr, - icmp_hv_rep(cicmph)); + icmp_hv_rep(cicmph), maddr); read_unlock(&__ip_masq_lock); if (ms == NULL) @@ -1663,7 +1668,7 @@ ciph->daddr, pptr[1], ciph->saddr, - pptr[0]); + pptr[0], maddr); read_unlock(&__ip_masq_lock); if (ms == NULL) @@ -2103,6 +2108,7 @@ */ ms->dport = h.portp[0]; ms->daddr = iph->saddr; + ms->maddr = iph->daddr; } else { if ( ms->flags & IP_MASQ_F_NO_DPORT ) { /* && ms->protocol == IPPROTO_TCP ) { */ @@ -2126,6 +2132,7 @@ ip_masq_unhash(ms); ms->flags &= ~IP_MASQ_F_NO_DADDR; ms->daddr = iph->saddr; + ms->maddr = iph->daddr; ip_masq_hash(ms); /* hash on new daddr */ write_unlock(&__ip_masq_lock); --- linux-2.2.15pre16/net/ipv4/ip_masq_user.c.orig Wed Mar 29 13:15:44 2000 +++ linux/net/ipv4/ip_masq_user.c Sat Apr 1 11:59:47 2000 @@ -184,7 +184,7 @@ } else if (ums->sport && ums->saddr) { ms = ip_masq_out_get(ums->protocol, ums->saddr, ums->sport, - ums->daddr, ums->dport); + ums->daddr, ums->dport, ums->maddr); end_bh_atomic(); } else { end_bh_atomic(); @@ -224,7 +224,7 @@ } else if (ums->sport && ums->saddr) { ms = ip_masq_out_get(ums->protocol, ums->saddr, ums->sport, - ums->daddr, ums->dport); + ums->daddr, ums->dport, ums->maddr); end_bh_atomic(); } else { end_bh_atomic(); --- linux-2.2.15pre16/net/ipv4/ip_masq_ftp.c.orig Wed Mar 29 13:15:44 2000 +++ linux/net/ipv4/ip_masq_ftp.c Sat Apr 1 12:15:00 2000 @@ -187,7 +187,7 @@ n_ms = ip_masq_out_get(iph->protocol, htonl(from), htons(port), - iph->daddr, 0); + iph->daddr, 0, maddr); if (!n_ms) { n_ms = ip_masq_new(IPPROTO_TCP, maddr, 0, @@ -319,7 +319,7 @@ n_ms = ip_masq_out_get(iph->protocol, ms->saddr, 0, - htonl(to), htons(port)); + htonl(to), htons(port), maddr); if (!n_ms) { n_ms = ip_masq_new(IPPROTO_TCP, maddr, 0,