Commit 14ee70ca authored by Vasily Averin's avatar Vasily Averin Committed by David S. Miller
Browse files

vrf: use skb_expand_head in vrf_finish_output



Unlike skb_realloc_headroom, new helper skb_expand_head
does not allocate a new skb if possible.

Signed-off-by: default avatarVasily Averin <vvs@virtuozzo.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5678a595
Loading
Loading
Loading
Loading
+7 −14
Original line number Diff line number Diff line
@@ -857,30 +857,24 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
	unsigned int hh_len = LL_RESERVED_SPACE(dev);
	struct neighbour *neigh;
	bool is_v6gw = false;
	int ret = -EINVAL;

	nf_reset_ct(skb);

	/* Be paranoid, rather than too clever. */
	if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
		struct sk_buff *skb2;

		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
		if (!skb2) {
			ret = -ENOMEM;
			goto err;
		skb = skb_expand_head(skb, hh_len);
		if (!skb) {
			skb->dev->stats.tx_errors++;
			return -ENOMEM;
		}
		if (skb->sk)
			skb_set_owner_w(skb2, skb->sk);

		consume_skb(skb);
		skb = skb2;
	}

	rcu_read_lock_bh();

	neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
	if (!IS_ERR(neigh)) {
		int ret;

		sock_confirm_neigh(skb, neigh);
		/* if crossing protocols, can not use the cached header */
		ret = neigh_output(neigh, skb, is_v6gw);
@@ -889,9 +883,8 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
	}

	rcu_read_unlock_bh();
err:
	vrf_tx_error(skb->dev, skb);
	return ret;
	return -EINVAL;
}

static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb)