From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Manning Subject: [PATCH net-next 2/5] ipv6: allow link-local and multicast packets inside vrf Date: Thu, 20 Sep 2018 09:58:45 +0100 Message-ID: <20180920085848.17721-3-mmanning@vyatta.att-mail.com> References: <20180920085848.17721-1-mmanning@vyatta.att-mail.com> To: netdev@vger.kernel.org Return-path: Received: from mx0a-00191d01.pphosted.com ([67.231.149.140]:45552 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727165AbeITOle (ORCPT ); Thu, 20 Sep 2018 10:41:34 -0400 Received: from pps.filterd (m0053301.ppops.net [127.0.0.1]) by mx0a-00191d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8K8skas045055 for ; Thu, 20 Sep 2018 04:59:08 -0400 Received: from alpi155.enaf.aldc.att.com (sbcsmtp7.sbc.com [144.160.229.24]) by mx0a-00191d01.pphosted.com with ESMTP id 2mm5yq3adw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 20 Sep 2018 04:59:08 -0400 Received: from enaf.aldc.att.com (localhost [127.0.0.1]) by alpi155.enaf.aldc.att.com (8.14.5/8.14.5) with ESMTP id w8K8x73b016052 for ; Thu, 20 Sep 2018 04:59:07 -0400 Received: from zlp27125.vci.att.com (zlp27125.vci.att.com [135.66.87.52]) by alpi155.enaf.aldc.att.com (8.14.5/8.14.5) with ESMTP id w8K8x3LS015989 for ; Thu, 20 Sep 2018 04:59:03 -0400 Received: from zlp27125.vci.att.com (zlp27125.vci.att.com [127.0.0.1]) by zlp27125.vci.att.com (Service) with ESMTP id 237B916A3EE for ; Thu, 20 Sep 2018 08:59:03 +0000 (GMT) Received: from mlpi432.sfdc.sbc.com (unknown [144.151.223.11]) by zlp27125.vci.att.com (Service) with ESMTP id 044EF16A3EC for ; Thu, 20 Sep 2018 08:59:03 +0000 (GMT) Received: from sfdc.sbc.com (localhost [127.0.0.1]) by mlpi432.sfdc.sbc.com (8.14.5/8.14.5) with ESMTP id w8K8x2eL005423 for ; Thu, 20 Sep 2018 04:59:02 -0400 Received: from mail.eng.vyatta.net (mail.eng.vyatta.net [10.156.50.82]) by mlpi432.sfdc.sbc.com (8.14.5/8.14.5) with ESMTP id w8K8wwWw005327 for ; Thu, 20 Sep 2018 04:58:58 -0400 Received: from MM-7520.vyatta.net (unknown [10.156.47.144]) by mail.eng.vyatta.net (Postfix) with ESMTPA id 97469360034 for ; Thu, 20 Sep 2018 01:58:57 -0700 (PDT) In-Reply-To: <20180920085848.17721-1-mmanning@vyatta.att-mail.com> Sender: netdev-owner@vger.kernel.org List-ID: Packets that are multicast or to link-local addresses are not enslaved to the vrf of the socket that they are received on. This is needed for NDISC, but breaks applications that rely on receiving such packets when in a VRF. Also to make IPv6 consistent with IPv4 which does handle multicast packets as being enslaved, modify the VRF driver to do the same for IPv6. As a result, the multicast address check needs to verify the address against the enslaved rather than the l3mdev device. Signed-off-by: Mike Manning --- drivers/net/vrf.c | 19 +++++++++---------- net/ipv6/ip6_input.c | 19 ++++++++++++++++++- net/ipv6/ipv6_sockglue.c | 2 +- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index f93547f257fb..9d817c19f3b4 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -981,24 +981,23 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev, struct sk_buff *skb) { int orig_iif = skb->skb_iif; - bool need_strict; + bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr); + bool is_ndisc = ipv6_ndisc_frame(skb); - /* loopback traffic; do not push through packet taps again. - * Reset pkt_type for upper layers to process skb + /* loopback, multicast & non-ND link-local traffic; do not push through + * packet taps again. Reset pkt_type for upper layers to process skb */ - if (skb->pkt_type == PACKET_LOOPBACK) { + if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) { skb->dev = vrf_dev; skb->skb_iif = vrf_dev->ifindex; IP6CB(skb)->flags |= IP6SKB_L3SLAVE; - skb->pkt_type = PACKET_HOST; + if (skb->pkt_type == PACKET_LOOPBACK) + skb->pkt_type = PACKET_HOST; goto out; } - /* if packet is NDISC or addressed to multicast or link-local - * then keep the ingress interface - */ - need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr); - if (!ipv6_ndisc_frame(skb) && !need_strict) { + /* if packet is NDISC then keep the ingress interface */ + if (!is_ndisc) { vrf_rx_stats(vrf_dev, skb->len); skb->dev = vrf_dev; skb->skb_iif = vrf_dev->ifindex; diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 96577e742afd..108f5f88ec98 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -432,15 +432,32 @@ EXPORT_SYMBOL_GPL(ip6_input); int ip6_mc_input(struct sk_buff *skb) { + int sdif = inet6_sdif(skb); const struct ipv6hdr *hdr; + struct net_device *dev; bool deliver; __IP6_UPD_PO_STATS(dev_net(skb_dst(skb)->dev), __in6_dev_get_safely(skb->dev), IPSTATS_MIB_INMCAST, skb->len); + /* skb->dev passed may be master dev for vrfs. */ + if (sdif) { + rcu_read_lock(); + dev = dev_get_by_index_rcu(dev_net(skb->dev), sdif); + if (!dev) { + rcu_read_unlock(); + kfree_skb(skb); + return -ENODEV; + } + } else { + dev = skb->dev; + } + hdr = ipv6_hdr(skb); - deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); + deliver = ipv6_chk_mcast_addr(dev, &hdr->daddr, NULL); + if (sdif) + rcu_read_unlock(); #ifdef CONFIG_IPV6_MROUTE /* diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 7dfbc797b130..4ebd395dd3df 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -486,7 +486,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = -EFAULT; break; } - if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if) + if (!sk_dev_equal_l3scope(sk, pkt.ipi6_ifindex)) goto e_inval; np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; -- 2.11.0