aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2018-12-12 18:27:38 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-15 14:36:14 -0500
commitc2027d1e17582903e368abf5d4838b22a98f2b7b (patch)
tree3578009723ccb7f2e954f648674c42888e7d604e /net/ipv6/tcp_ipv6.c
parente782410ed2378a2ddac58d944c3cf0c6f96b1ff3 (diff)
ipv6: Fix handling of LLA with VRF and sockets bound to VRF
A recent commit allows sockets bound to a VRF to receive ipv6 link local packets. However, it only works for UDP and worse TCP connection attempts to the LLA with the only listener bound to the VRF just hang where as before the client gets a reset and connection refused. Fix by adjusting ir_iif for LL addresses and packets received through a device enslaved to a VRF. Fixes: 6f12fa775530 ("vrf: mark skb for multicast or link-local as enslaved to VRF") Reported-by: Donald Sharp <sharpd@cumulusnetworks.com> Cc: Mike Manning <mmanning@vyatta.att-mail.com> Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index a3f559162521..b81eb7cb815e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -737,6 +737,7 @@ static void tcp_v6_init_req(struct request_sock *req,
737 const struct sock *sk_listener, 737 const struct sock *sk_listener,
738 struct sk_buff *skb) 738 struct sk_buff *skb)
739{ 739{
740 bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags);
740 struct inet_request_sock *ireq = inet_rsk(req); 741 struct inet_request_sock *ireq = inet_rsk(req);
741 const struct ipv6_pinfo *np = inet6_sk(sk_listener); 742 const struct ipv6_pinfo *np = inet6_sk(sk_listener);
742 743
@@ -744,7 +745,7 @@ static void tcp_v6_init_req(struct request_sock *req,
744 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; 745 ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
745 746
746 /* So that link locals have meaning */ 747 /* So that link locals have meaning */
747 if (!sk_listener->sk_bound_dev_if && 748 if ((!sk_listener->sk_bound_dev_if || l3_slave) &&
748 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL) 749 ipv6_addr_type(&ireq->ir_v6_rmt_addr) & IPV6_ADDR_LINKLOCAL)
749 ireq->ir_iif = tcp_v6_iif(skb); 750 ireq->ir_iif = tcp_v6_iif(skb);
750 751