diff options
author | Patrick McHardy <kaber@trash.net> | 2007-06-01 14:45:04 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-06-03 21:08:51 -0400 |
commit | 6e1d91039becc9d5bcd046d8c709dbaf471220e3 (patch) | |
tree | bd12a1493d5651aed36f7606c72e146bbf7c0c60 /net/ipv4/icmp.c | |
parent | 584bdf8cbdf6f277c2a00e083257ee75687cf6f4 (diff) |
[ICMP]: Fix icmp_errors_use_inbound_ifaddr sysctl
Currently when icmp_errors_use_inbound_ifaddr is set and an ICMP error is
sent after the packet passed through ip_output(), an address from the
outgoing interface is chosen as ICMP source address since skb->dev doesn't
point to the incoming interface anymore.
Fix this by doing an interface lookup on rt->dst.iif and using that device.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r-- | net/ipv4/icmp.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e238b17f554c..02a899bec196 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -514,12 +514,15 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
514 | 514 | ||
515 | saddr = iph->daddr; | 515 | saddr = iph->daddr; |
516 | if (!(rt->rt_flags & RTCF_LOCAL)) { | 516 | if (!(rt->rt_flags & RTCF_LOCAL)) { |
517 | /* This is broken, skb_in->dev points to the outgoing device | 517 | struct net_device *dev = NULL; |
518 | * after the packet passes through ip_output(). | 518 | |
519 | */ | 519 | if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) |
520 | if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr) | 520 | dev = dev_get_by_index(rt->fl.iif); |
521 | saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); | 521 | |
522 | else | 522 | if (dev) { |
523 | saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK); | ||
524 | dev_put(dev); | ||
525 | } else | ||
523 | saddr = 0; | 526 | saddr = 0; |
524 | } | 527 | } |
525 | 528 | ||