Skip to content

Commit

Permalink
tcp: resets are misrouted
Browse files Browse the repository at this point in the history
After commit e2446ea ("tcp_v4_send_reset: binding oif to iif in no
sock case").. tcp resets are always lost, when routing is asymmetric.
Yes, backing out that patch will result in misrouting of resets for
dead connections which used interface binding when were alive, but we
actually cannot do anything here.  What's died that's died and correct
handling normal unbound connections is obviously a priority.

Comment to comment:
> This has few benefits:
>   1. tcp_v6_send_reset already did that.

It was done to route resets for IPv6 link local addresses. It was a
mistake to do so for global addresses. The patch fixes this as well.

Actually, the problem appears to be even more serious than guaranteed
loss of resets.  As reported by Sergey Soloviev <sol@eqv.ru>, those
misrouted resets create a lot of arp traffic and huge amount of
unresolved arp entires putting down to knees NAT firewalls which use
asymmetric routing.

Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
  • Loading branch information
Alexey Kuznetsov authored and davem330 committed Oct 12, 2012
1 parent 5d9d01a commit 4c67525
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 4 deletions.
7 changes: 4 additions & 3 deletions net/ipv4/tcp_ipv4.c
Expand Up @@ -708,10 +708,11 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
arg.csumoffset = offsetof(struct tcphdr, check) / 2;
arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
/* When socket is gone, all binding information is lost.
* routing might fail in this case. using iif for oif to
* make sure we can deliver it
* routing might fail in this case. No choice here, if we choose to force
* input interface, we will misroute in case of asymmetric route.
*/
arg.bound_dev_if = sk ? sk->sk_bound_dev_if : inet_iif(skb);
if (sk)
arg.bound_dev_if = sk->sk_bound_dev_if;

net = dev_net(skb_dst(skb)->dev);
arg.tos = ip_hdr(skb)->tos;
Expand Down
3 changes: 2 additions & 1 deletion net/ipv6/tcp_ipv6.c
Expand Up @@ -877,7 +877,8 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
__tcp_v6_send_check(buff, &fl6.saddr, &fl6.daddr);

fl6.flowi6_proto = IPPROTO_TCP;
fl6.flowi6_oif = inet6_iif(skb);
if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
fl6.flowi6_oif = inet6_iif(skb);
fl6.fl6_dport = t1->dest;
fl6.fl6_sport = t1->source;
security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
Expand Down

0 comments on commit 4c67525

Please sign in to comment.