Merge tag 'perf-urgent-2023-11-26' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / drivers / net / netkit.c
index 5a0f86f38f093123c010beea5ac39c2cda031ec8..97bd6705c24117cff255ebbe34fc9efc4c0da2bd 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/filter.h>
 #include <linux/netfilter_netdev.h>
 #include <linux/bpf_mprog.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include <net/netkit.h>
 #include <net/dst.h>
@@ -68,6 +69,7 @@ static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
        netdev_tx_t ret_dev = NET_XMIT_SUCCESS;
        const struct bpf_mprog_entry *entry;
        struct net_device *peer;
+       int len = skb->len;
 
        rcu_read_lock();
        peer = rcu_dereference(nk->peer);
@@ -85,15 +87,22 @@ static netdev_tx_t netkit_xmit(struct sk_buff *skb, struct net_device *dev)
        case NETKIT_PASS:
                skb->protocol = eth_type_trans(skb, skb->dev);
                skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
-               __netif_rx(skb);
+               if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
+                       dev_sw_netstats_tx_add(dev, 1, len);
+                       dev_sw_netstats_rx_add(peer, len);
+               } else {
+                       goto drop_stats;
+               }
                break;
        case NETKIT_REDIRECT:
+               dev_sw_netstats_tx_add(dev, 1, len);
                skb_do_redirect(skb);
                break;
        case NETKIT_DROP:
        default:
 drop:
                kfree_skb(skb);
+drop_stats:
                dev_core_stats_tx_dropped_inc(dev);
                ret_dev = NET_XMIT_DROP;
                break;
@@ -169,11 +178,18 @@ out:
        rcu_read_unlock();
 }
 
-static struct net_device *netkit_peer_dev(struct net_device *dev)
+INDIRECT_CALLABLE_SCOPE struct net_device *netkit_peer_dev(struct net_device *dev)
 {
        return rcu_dereference(netkit_priv(dev)->peer);
 }
 
+static void netkit_get_stats(struct net_device *dev,
+                            struct rtnl_link_stats64 *stats)
+{
+       dev_fetch_sw_netstats(stats, dev->tstats);
+       stats->tx_dropped = DEV_STATS_READ(dev, tx_dropped);
+}
+
 static void netkit_uninit(struct net_device *dev);
 
 static const struct net_device_ops netkit_netdev_ops = {
@@ -184,6 +200,7 @@ static const struct net_device_ops netkit_netdev_ops = {
        .ndo_set_rx_headroom    = netkit_set_headroom,
        .ndo_get_iflink         = netkit_get_iflink,
        .ndo_get_peer_dev       = netkit_peer_dev,
+       .ndo_get_stats64        = netkit_get_stats,
        .ndo_uninit             = netkit_uninit,
        .ndo_features_check     = passthru_features_check,
 };
@@ -218,6 +235,7 @@ static void netkit_setup(struct net_device *dev)
 
        ether_setup(dev);
        dev->max_mtu = ETH_MAX_MTU;
+       dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
 
        dev->flags |= IFF_NOARP;
        dev->priv_flags &= ~IFF_TX_SKB_SHARING;