static netdev_tx_t nsim_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct netdevsim *ns = netdev_priv(dev);
+       unsigned int len = skb->len;
+       struct netdevsim *peer_ns;
 
+       rcu_read_lock();
        if (!nsim_ipsec_tx(ns, skb))
-               goto out;
+               goto out_drop_free;
 
+       peer_ns = rcu_dereference(ns->peer);
+       if (!peer_ns)
+               goto out_drop_free;
+
+       skb_tx_timestamp(skb);
+       if (unlikely(dev_forward_skb(peer_ns->netdev, skb) == NET_RX_DROP))
+               goto out_drop_cnt;
+
+       rcu_read_unlock();
        u64_stats_update_begin(&ns->syncp);
        ns->tx_packets++;
-       ns->tx_bytes += skb->len;
+       ns->tx_bytes += len;
        u64_stats_update_end(&ns->syncp);
+       return NETDEV_TX_OK;
 
-out:
+out_drop_free:
        dev_kfree_skb(skb);
-
+out_drop_cnt:
+       rcu_read_unlock();
+       u64_stats_update_begin(&ns->syncp);
+       ns->tx_dropped++;
+       u64_stats_update_end(&ns->syncp);
        return NETDEV_TX_OK;
 }
 
                start = u64_stats_fetch_begin(&ns->syncp);
                stats->tx_bytes = ns->tx_bytes;
                stats->tx_packets = ns->tx_packets;
+               stats->tx_dropped = ns->tx_dropped;
        } while (u64_stats_fetch_retry(&ns->syncp, start));
 }
 
        eth_hw_addr_random(dev);
 
        dev->tx_queue_len = 0;
-       dev->flags |= IFF_NOARP;
        dev->flags &= ~IFF_MULTICAST;
        dev->priv_flags |= IFF_LIVE_ADDR_CHANGE |
                           IFF_NO_QUEUE;