Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91c5f99d authored by Mike Manning's avatar Mike Manning Committed by Greg Kroah-Hartman
Browse files

vrf: mark skb for multicast or link-local as enslaved to VRF



[ Upstream commit 6f12fa775530195a501fb090d092c637f32d0cc5 ]

The skb for packets that are multicast or to a link-local address are
not marked as being enslaved to a VRF, if they are received on a socket
bound to the VRF. This is needed for ND and it is preferable for the
kernel not to have to deal with the additional use-cases if ll or mcast
packets are handled as enslaved. However, this does not allow service
instances listening on unbound and bound to VRF sockets to distinguish
the VRF used, if packets are sent as multicast or to a link-local
address. The fix is for the VRF driver to also mark these skb as being
enslaved to the VRF.

Signed-off-by: default avatarMike Manning <mmanning@vyatta.att-mail.com>
Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Tested-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 5c2a3997
Loading
Loading
Loading
Loading
+9 −10
Original line number Original line Diff line number Diff line
@@ -993,24 +993,23 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
				   struct sk_buff *skb)
				   struct sk_buff *skb)
{
{
	int orig_iif = skb->skb_iif;
	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.
	/* loopback, multicast & non-ND link-local traffic; do not push through
	 * Reset pkt_type for upper layers to process skb
	 * 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->dev = vrf_dev;
		skb->skb_iif = vrf_dev->ifindex;
		skb->skb_iif = vrf_dev->ifindex;
		IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
		IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
		if (skb->pkt_type == PACKET_LOOPBACK)
			skb->pkt_type = PACKET_HOST;
			skb->pkt_type = PACKET_HOST;
		goto out;
		goto out;
	}
	}


	/* if packet is NDISC or addressed to multicast or link-local
	/* if packet is NDISC then keep the ingress interface */
	 * then keep the ingress interface
	if (!is_ndisc) {
	 */
	need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
	if (!ipv6_ndisc_frame(skb) && !need_strict) {
		vrf_rx_stats(vrf_dev, skb->len);
		vrf_rx_stats(vrf_dev, skb->len);
		skb->dev = vrf_dev;
		skb->dev = vrf_dev;
		skb->skb_iif = vrf_dev->ifindex;
		skb->skb_iif = vrf_dev->ifindex;