ipvlan: properly track tx_errors
authorEric Dumazet <edumazet@google.com>
Thu, 26 Oct 2023 13:14:46 +0000 (13:14 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 27 Oct 2023 21:49:09 +0000 (14:49 -0700)
Both ipvlan_process_v4_outbound() and ipvlan_process_v6_outbound()
increment dev->stats.tx_errors in case of errors.

Unfortunately there are two issues :

1) ipvlan_get_stats64() does not propagate dev->stats.tx_errors to user.

2) Increments are not atomic. KCSAN would complain eventually.

Use DEV_STATS_INC() to not miss an update, and change ipvlan_get_stats64()
to copy the value back to user.

Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Mahesh Bandewar <maheshb@google.com>
Link: https://lore.kernel.org/r/20231026131446.3933175-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ipvlan/ipvlan_core.c
drivers/net/ipvlan/ipvlan_main.c

index c0c49f1813673acebdae2f3f52259fb6b9678c36..21e9cac7312186380fa60de11f0a9178080b74b0 100644 (file)
@@ -441,12 +441,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
 
        err = ip_local_out(net, skb->sk, skb);
        if (unlikely(net_xmit_eval(err)))
-               dev->stats.tx_errors++;
+               DEV_STATS_INC(dev, tx_errors);
        else
                ret = NET_XMIT_SUCCESS;
        goto out;
 err:
-       dev->stats.tx_errors++;
+       DEV_STATS_INC(dev, tx_errors);
        kfree_skb(skb);
 out:
        return ret;
@@ -482,12 +482,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
 
        err = ip6_local_out(net, skb->sk, skb);
        if (unlikely(net_xmit_eval(err)))
-               dev->stats.tx_errors++;
+               DEV_STATS_INC(dev, tx_errors);
        else
                ret = NET_XMIT_SUCCESS;
        goto out;
 err:
-       dev->stats.tx_errors++;
+       DEV_STATS_INC(dev, tx_errors);
        kfree_skb(skb);
 out:
        return ret;
index 1b55928e89b8a10706cc8c7911d6055d17987be6..57c79f5f29916b66154da2c8ff10238ef2c02584 100644 (file)
@@ -324,6 +324,7 @@ static void ipvlan_get_stats64(struct net_device *dev,
                s->rx_dropped = rx_errs;
                s->tx_dropped = tx_drps;
        }
+       s->tx_errors = DEV_STATS_READ(dev, tx_errors);
 }
 
 static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)