diff options
author | Roland McGrath <roland@gnu.org> | 2000-02-05 12:21:17 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2000-02-05 12:21:17 +0000 |
commit | e5f75e8ece5d1a8d3c17bd0156082caf153d3779 (patch) | |
tree | 316ee48be396f95770ccd5511ea442b83cadca51 /pfinet/linux-src/net/ipv4/ip_masq.c | |
parent | b39cd08347c72483a4521a55301a0fa147a2a2b1 (diff) | |
download | hurd-e5f75e8ece5d1a8d3c17bd0156082caf153d3779.tar.gz hurd-e5f75e8ece5d1a8d3c17bd0156082caf153d3779.tar.bz2 hurd-e5f75e8ece5d1a8d3c17bd0156082caf153d3779.zip |
Import of Linux 2.2.14 subset (ipv4 stack and related)
Diffstat (limited to 'pfinet/linux-src/net/ipv4/ip_masq.c')
-rw-r--r-- | pfinet/linux-src/net/ipv4/ip_masq.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/pfinet/linux-src/net/ipv4/ip_masq.c b/pfinet/linux-src/net/ipv4/ip_masq.c index 6d0588c0..8f00409f 100644 --- a/pfinet/linux-src/net/ipv4/ip_masq.c +++ b/pfinet/linux-src/net/ipv4/ip_masq.c @@ -10,6 +10,9 @@ * See ip_fw.c for original log * * Fixes: + * Joseph Gooch : Modified ip_fw_masquerade() to do a ip_route_output() + * (help by Dan Drown) : to choose the proper local address. + * (and Alexey) : * Juan Jose Ciarlante : Modularized application masquerading (see ip_masq_app.c) * Juan Jose Ciarlante : New struct ip_masq_seq that holds output/input delta seq. * Juan Jose Ciarlante : Added hashed lookup by proto,maddr,mport and proto,saddr,sport @@ -787,6 +790,8 @@ void ip_masq_put(struct ip_masq *ms) } } +extern int sysctl_ip_always_defrag; + static void masq_expire(unsigned long data) { struct ip_masq *ms = (struct ip_masq *)data; @@ -839,6 +844,7 @@ static void masq_expire(unsigned long data) */ if (atomic_read(&ms->refcnt) == 1) { kfree_s(ms,sizeof(*ms)); + sysctl_ip_always_defrag--; MOD_DEC_USE_COUNT; goto masq_expire_out; } @@ -880,8 +886,6 @@ static __u16 get_next_mport(void) * Be careful, it can be called from u-space */ -extern int sysctl_ip_always_defrag; - struct ip_masq * ip_masq_new(int proto, __u32 maddr, __u16 mport, __u32 saddr, __u16 sport, __u32 daddr, __u16 dport, unsigned mflags) { struct ip_masq *ms, *mst; @@ -1141,6 +1145,23 @@ int ip_fw_masquerade(struct sk_buff **skb_p, __u32 maddr) return -1; } + /* Lets determine our maddr now, shall we? */ + if (maddr == 0) { + struct rtable *rt; + struct rtable *skb_rt = (struct rtable*)skb->dst; + struct device *skb_dev = skb_rt->u.dst.dev; + + if (ip_route_output(&rt, iph->daddr, 0, RT_TOS(iph->tos)|RTO_CONN, skb_dev?skb_dev->ifindex:0)) { + /* Fallback on old method */ + /* This really shouldn't happen... */ + maddr = inet_select_addr(skb_dev, skb_rt->rt_gateway, RT_SCOPE_UNIVERSE); + } else { + /* Route lookup succeeded */ + maddr = rt->rt_src; + ip_rt_put(rt); + } + } + switch (iph->protocol) { case IPPROTO_ICMP: return(ip_fw_masq_icmp(skb_p, maddr)); |