From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Manning Subject: [PATCH net-next v1 2/5] ipv6: allow link-local and multicast packets inside vrf Date: Mon, 24 Sep 2018 17:13:23 +0100 Message-ID: <20180924161326.17167-3-mmanning@vyatta.att-mail.com> References: <20180924161326.17167-1-mmanning@vyatta.att-mail.com> To: netdev@vger.kernel.org Return-path: Received: from mx0b-00191d01.pphosted.com ([67.231.157.136]:39040 "EHLO mx0a-00191d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728544AbeIXWQh (ORCPT ); Mon, 24 Sep 2018 18:16:37 -0400 Received: from pps.filterd (m0049458.ppops.net [127.0.0.1]) by m0049458.ppops.net-00191d01. (8.16.0.22/8.16.0.22) with SMTP id w8OG8P2B006490 for ; Mon, 24 Sep 2018 12:13:43 -0400 Received: from alpi155.enaf.aldc.att.com (sbcsmtp7.sbc.com [144.160.229.24]) by m0049458.ppops.net-00191d01. with ESMTP id 2mq1juvk9y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 24 Sep 2018 12:13:42 -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 w8OGDfeR017577 for ; Mon, 24 Sep 2018 12:13:41 -0400 Received: from zlp27126.vci.att.com (zlp27126.vci.att.com [135.66.87.47]) by alpi155.enaf.aldc.att.com (8.14.5/8.14.5) with ESMTP id w8OGDdhS017525 for ; Mon, 24 Sep 2018 12:13:39 -0400 Received: from zlp27126.vci.att.com (zlp27126.vci.att.com [127.0.0.1]) by zlp27126.vci.att.com (Service) with ESMTP id 587AC40F6CEB for ; Mon, 24 Sep 2018 16:13:39 +0000 (GMT) Received: from mlpi432.sfdc.sbc.com (unknown [144.151.223.11]) by zlp27126.vci.att.com (Service) with ESMTP id 3A7CA40F6CEA for ; Mon, 24 Sep 2018 16:13:39 +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 w8OGDcdr002898 for ; Mon, 24 Sep 2018 12:13:39 -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 w8OGDaEe002840 for ; Mon, 24 Sep 2018 12:13:36 -0400 Received: from MM-7520.vyatta.net (unknown [10.156.47.164]) by mail.eng.vyatta.net (Postfix) with ESMTPA id 6DF6B3600D9 for ; Mon, 24 Sep 2018 09:13:35 -0700 (PDT) In-Reply-To: <20180924161326.17167-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