diff options
author | Eric Dumazet <edumazet@google.com> | 2023-10-26 16:14:46 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-10-28 00:49:09 +0300 |
commit | ff672b9ffeb3f82135488ac16c5c5eb4b992999b (patch) | |
tree | f22a14dc9e2bad8bf0e3ac177705fedc0a965b92 /drivers/net/ipvlan | |
parent | 6aff7cbfe7bfafbed86a6948e660e280848c4d97 (diff) | |
download | linux-ff672b9ffeb3f82135488ac16c5c5eb4b992999b.tar.xz |
ipvlan: properly track tx_errors
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>
Diffstat (limited to 'drivers/net/ipvlan')
-rw-r--r-- | drivers/net/ipvlan/ipvlan_core.c | 8 | ||||
-rw-r--r-- | drivers/net/ipvlan/ipvlan_main.c | 1 |
2 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index c0c49f181367..21e9cac73121 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -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; diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 1b55928e89b8..57c79f5f2991 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -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) |