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

Commit 7c852581 authored by Steffen Klassert's avatar Steffen Klassert
Browse files

vti6: Remove dst_entry caching



Unlike ip6_tunnel, vti6 can lookup multiple different dst entries,
dependent of the configured xfrm states. Therefore it does not make
sense to cache a dst_entry.

Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
parent 59b84351
Loading
Loading
Loading
Loading
+18 −24
Original line number Diff line number Diff line
@@ -278,7 +278,6 @@ static void vti6_dev_uninit(struct net_device *dev)
		RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
	else
		vti6_tnl_unlink(ip6n, t);
	ip6_tnl_dst_reset(t);
	dev_put(dev);
}

@@ -356,11 +355,10 @@ vti6_addr_conflict(const struct ip6_tnl *t, const struct ipv6hdr *hdr)
 **/
static int vti6_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net *net = dev_net(dev);
	struct ip6_tnl *t = netdev_priv(dev);
	struct net_device_stats *stats = &t->dev->stats;
	struct dst_entry *dst = NULL, *ndst = NULL;
	struct flowi6 fl6;
	struct dst_entry *dst = skb_dst(skb);
	struct flowi fl;
	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
	struct net_device *tdev;
	int err = -1;
@@ -369,22 +367,20 @@ static int vti6_xmit(struct sk_buff *skb, struct net_device *dev)
	    !ip6_tnl_xmit_ctl(t) || vti6_addr_conflict(t, ipv6h))
		return err;

	dst = ip6_tnl_dst_check(t);
	if (!dst) {
		memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
	memset(&fl, 0, sizeof(fl));
	skb->mark = be32_to_cpu(t->parms.o_key);
	xfrm_decode_session(skb, &fl, AF_INET6);

		ndst = ip6_route_output(net, NULL, &fl6);

		if (ndst->error)
	if (!dst)
		goto tx_err_link_failure;
		ndst = xfrm_lookup(net, ndst, flowi6_to_flowi(&fl6), NULL, 0);
		if (IS_ERR(ndst)) {
			err = PTR_ERR(ndst);
			ndst = NULL;

	dst_hold(dst);
	dst = xfrm_lookup(t->net, dst, &fl, NULL, 0);
	if (IS_ERR(dst)) {
		err = PTR_ERR(dst);
		dst = NULL;
		goto tx_err_link_failure;
	}
		dst = ndst;
	}

	if (!dst->xfrm || dst->xfrm->props.mode != XFRM_MODE_TUNNEL)
		goto tx_err_link_failure;
@@ -399,21 +395,19 @@ static int vti6_xmit(struct sk_buff *skb, struct net_device *dev)
	}


	skb_dst_drop(skb);
	skb_dst_set_noref(skb, dst);
	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
	skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
	skb_dst_set(skb, dst);
	skb->dev = skb_dst(skb)->dev;

	ip6tunnel_xmit(skb, dev);
	if (ndst) {
		dev->mtu = dst_mtu(ndst);
		ip6_tnl_dst_store(t, ndst);
	}

	return 0;
tx_err_link_failure:
	stats->tx_carrier_errors++;
	dst_link_failure(skb);
tx_err_dst_release:
	dst_release(ndst);
	dst_release(dst);
	return err;
}