net: ethernet: Fixes for ethernet stats reporting.

The following fixes were applied:
 - Multicast Rx packets stats were not recorded due not parsing the
ethernet header. The function that tried to parse the ethernet header
was parsing the ethernet packet beyond the ethernet header.
 - Added a new stats for unknown protocol which gets updated when the
ethernet layer encounters an unknown ethernet packet type.

Fixes #53994

Signed-off-by: Chamira Perera <chamira.perera@audinate.com>
This commit is contained in:
Chamira Perera 2023-01-25 16:07:45 +11:00 committed by Fabio Baltieri
commit ce49beb297
3 changed files with 25 additions and 6 deletions

View file

@ -202,6 +202,24 @@ static inline void eth_stats_update_errors_tx(struct net_if *iface)
stats->errors.tx++;
}
static inline void eth_stats_update_unknown_protocol(struct net_if *iface)
{
struct net_stats_eth *stats;
const struct ethernet_api *api = ((const struct ethernet_api *)
net_if_get_device(iface)->api);
if (!api->get_stats) {
return;
}
stats = api->get_stats(net_if_get_device(iface));
if (!stats) {
return;
}
stats->unknown_protocol++;
}
#else /* CONFIG_NET_STATISTICS_ETHERNET */
#define eth_stats_update_bytes_rx(iface, bytes)
@ -214,6 +232,7 @@ static inline void eth_stats_update_errors_tx(struct net_if *iface)
#define eth_stats_update_multicast_tx(iface)
#define eth_stats_update_errors_rx(iface)
#define eth_stats_update_errors_tx(iface)
#define eth_stats_update_unknown_protocol(iface)
#endif /* CONFIG_NET_STATISTICS_ETHERNET */

View file

@ -144,11 +144,9 @@ static inline void ethernet_update_length(struct net_if *iface,
}
static void ethernet_update_rx_stats(struct net_if *iface,
struct net_pkt *pkt, size_t length)
struct net_eth_hdr *hdr, size_t length)
{
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
eth_stats_update_bytes_rx(iface, length);
eth_stats_update_pkts_rx(iface);
@ -213,7 +211,7 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
net_pkt_lladdr_dst(pkt)->addr = hdr->dst.addr;
net_pkt_lladdr_dst(pkt)->len = sizeof(struct net_eth_addr);
net_pkt_lladdr_dst(pkt)->type = NET_LINK_ETHERNET;
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt));
ethernet_update_rx_stats(iface, hdr, net_pkt_get_len(pkt));
return net_eth_bridge_input(ctx, pkt);
}
@ -263,7 +261,8 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
}
NET_DBG("Unknown hdr type 0x%04x iface %p", type, iface);
goto drop;
eth_stats_update_unknown_protocol(iface);
return NET_DROP;
}
/* Set the pointers to ll src and dst addresses */
@ -320,7 +319,7 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
goto drop;
}
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt) + hdr_len);
ethernet_update_rx_stats(iface, hdr, net_pkt_get_len(pkt) + hdr_len);
if (IS_ENABLED(CONFIG_NET_ARP) &&
family == AF_INET && type == NET_ETH_PTYPE_ARP) {