Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vasily Averin and committed by
David S. Miller
14ee70ca 5678a595

+7 -14
+7 -14
drivers/net/vrf.c
··· 857 857 unsigned int hh_len = LL_RESERVED_SPACE(dev); 858 858 struct neighbour *neigh; 859 859 bool is_v6gw = false; 860 - int ret = -EINVAL; 861 860 862 861 nf_reset_ct(skb); 863 862 864 863 /* Be paranoid, rather than too clever. */ 865 864 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { 866 - struct sk_buff *skb2; 867 - 868 - skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev)); 869 - if (!skb2) { 870 - ret = -ENOMEM; 871 - goto err; 865 + skb = skb_expand_head(skb, hh_len); 866 + if (!skb) { 867 + skb->dev->stats.tx_errors++; 868 + return -ENOMEM; 872 869 } 873 - if (skb->sk) 874 - skb_set_owner_w(skb2, skb->sk); 875 - 876 - consume_skb(skb); 877 - skb = skb2; 878 870 } 879 871 880 872 rcu_read_lock_bh(); 881 873 882 874 neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); 883 875 if (!IS_ERR(neigh)) { 876 + int ret; 877 + 884 878 sock_confirm_neigh(skb, neigh); 885 879 /* if crossing protocols, can not use the cached header */ 886 880 ret = neigh_output(neigh, skb, is_v6gw); ··· 883 889 } 884 890 885 891 rcu_read_unlock_bh(); 886 - err: 887 892 vrf_tx_error(skb->dev, skb); 888 - return ret; 893 + return -EINVAL; 889 894 } 890 895 891 896 static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb)