network: Aggregate statistics from the device, if any are provided.

This way, we report the real receive/send statistics, not just
the ones the stack knows.

Adjust the FreeBSD compatibility layer to report its stats directly
so they are accounted for this way.
This commit is contained in:
Augustin Cavalier 2024-11-13 13:55:58 -05:00
parent de8d5cfb5f
commit 5c9dc91f64
2 changed files with 30 additions and 2 deletions

View File

@ -886,9 +886,19 @@ interface_protocol_control(net_datalink_protocol* _protocol, int32 option,
case SIOCGIFSTATS: case SIOCGIFSTATS:
{ {
// get stats // get stats
struct ifreq_stats stats = interface->DeviceInterface()->device->stats;
struct ifreq_stats deviceStats;
if (protocol->device_module->control(protocol->device, SIOCGIFSTATS,
&deviceStats, sizeof(struct ifreq_stats)) == B_OK) {
stats.receive.dropped += deviceStats.receive.dropped;
stats.receive.errors += deviceStats.receive.errors;
stats.send = deviceStats.send;
stats.collisions += deviceStats.collisions;
}
return user_memcpy(&((struct ifreq*)argument)->ifr_stats, return user_memcpy(&((struct ifreq*)argument)->ifr_stats,
&interface->DeviceInterface()->device->stats, &stats, sizeof(struct ifreq_stats));
sizeof(struct ifreq_stats));
} }
case SIOCGIFTYPE: case SIOCGIFTYPE:

View File

@ -346,6 +346,24 @@ compat_control(void *cookie, uint32 op, void *arg, size_t length)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
return compat_receive(cookie, (net_buffer**)arg); return compat_receive(cookie, (net_buffer**)arg);
case SIOCGIFSTATS:
{
struct ifreq_stats stats;
stats.receive.packets = ifp->if_data.ifi_ipackets;
stats.receive.errors = ifp->if_data.ifi_ierrors;
stats.receive.bytes = ifp->if_data.ifi_ibytes;
stats.receive.multicast_packets = ifp->if_data.ifi_imcasts;
stats.receive.dropped = ifp->if_data.ifi_iqdrops;
stats.send.packets = ifp->if_data.ifi_opackets;
stats.send.errors = ifp->if_data.ifi_oerrors;
stats.send.bytes = ifp->if_data.ifi_obytes;
stats.send.multicast_packets = ifp->if_data.ifi_omcasts;
stats.send.dropped = ifp->if_data.ifi_oqdrops;
stats.collisions = ifp->if_data.ifi_collisions;
memcpy(arg, &stats, sizeof(stats));
return B_OK;
}
case SIOCSIFFLAGS: case SIOCSIFFLAGS:
case SIOCSIFMEDIA: case SIOCSIFMEDIA:
case SIOCSIFMTU: case SIOCSIFMTU: