net: tcp response should set oif only if it is L3 master
authorDavid Ahern <dsa@cumulusnetworks.com>
Wed, 9 Nov 2016 17:07:26 +0000 (09:07 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 Nov 2016 03:32:10 +0000 (22:32 -0500)
Lorenzo noted an Android unit test failed due to e0d56fdd7342:
"The expectation in the test was that the RST replying to a SYN sent to a
closed port should be generated with oif=0. In other words it should not
prefer the interface where the SYN came in on, but instead should follow
whatever the routing table says it should do."

Revert the change to ip_send_unicast_reply and tcp_v6_send_response such
that the oif in the flow is set to the skb_iif only if skb_iif is an L3
master.

Fixes: e0d56fdd7342 ("net: l3mdev: remove redundant calls")
Reported-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Tested-by: Lorenzo Colitti <lorenzo@google.com>
Acked-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_output.c
net/ipv6/tcp_ipv6.c

index 49714010ac2ecf688663c298cf35bc925406a07a..9403fa3850be839bd8c25959dc4fcab8486b7f21 100644 (file)
@@ -1577,7 +1577,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
        }
 
        oif = arg->bound_dev_if;
-       oif = oif ? : skb->skb_iif;
+       if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+               oif = skb->skb_iif;
 
        flowi4_init_output(&fl4, oif,
                           IP4_REPLY_MARK(net, skb->mark),
index 5a27ab4eab3974280aad827241944b53daab569e..6ca23c2e76f7b79f9cf51867b8427e0e9e300bf8 100644 (file)
@@ -818,8 +818,12 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
        fl6.flowi6_proto = IPPROTO_TCP;
        if (rt6_need_strict(&fl6.daddr) && !oif)
                fl6.flowi6_oif = tcp_v6_iif(skb);
-       else
-               fl6.flowi6_oif = oif ? : skb->skb_iif;
+       else {
+               if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+                       oif = skb->skb_iif;
+
+               fl6.flowi6_oif = oif;
+       }
 
        fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
        fl6.fl6_dport = t1->dest;