2024-10-29, 11:47:21 +0100, Antonio Quartulli wrote: > +static void ovpn_send(struct ovpn_struct *ovpn, struct sk_buff *skb, > + struct ovpn_peer *peer) > +{ > + struct sk_buff *curr, *next; > + > + if (likely(!peer)) > + /* retrieve peer serving the destination IP of this packet */ > + peer = ovpn_peer_get_by_dst(ovpn, skb); > + if (unlikely(!peer)) { > + net_dbg_ratelimited("%s: no peer to send data to\n", > + ovpn->dev->name); > + dev_core_stats_tx_dropped_inc(ovpn->dev); > + goto drop; > + } > + > + /* this might be a GSO-segmented skb list: process each skb > + * independently > + */ > + skb_list_walk_safe(skb, curr, next) nit (if you end up reposting): there should probably be some braces around the (multi-line) loop body. > + if (unlikely(!ovpn_encrypt_one(peer, curr))) { > + dev_core_stats_tx_dropped_inc(ovpn->dev); > + kfree_skb(curr); > + } > +void ovpn_udp_send_skb(struct ovpn_struct *ovpn, struct ovpn_peer *peer, > + struct sk_buff *skb) > +{ [...] > + /* crypto layer -> transport (UDP) */ > + pkt_len = skb->len; > + ret = ovpn_udp_output(ovpn, bind, &peer->dst_cache, sock->sk, skb); > + > +out_unlock: > + rcu_read_unlock(); > +out: > + if (unlikely(ret < 0)) { > + dev_core_stats_tx_dropped_inc(ovpn->dev); > + kfree_skb(skb); > + return; > + } > + > + dev_sw_netstats_tx_add(ovpn->dev, 1, pkt_len); If I'm following things correctly, that's already been counted: ovpn_udp_output -> ovpn_udp4_output -> udp_tunnel_xmit_skb -> iptunnel_xmit -> iptunnel_xmit_stats which does (on success) the same thing as dev_sw_netstats_tx_add. On failure it increments a different tx_dropped counter than what dev_core_stats_tx_dropped_inc, but they should get summed in the end. > +} -- Sabrina