net: l2: ethernet: Handle Ethernet II minimal frame size relevantly

Minimal frame size is 60 bytes, but IP frame might be smaller than this
size minus the ethernet header. In that case, Ethernet frames are padded
so it does reach this minimal size. In this case, ethernet L2 should
update the buffer list so it remove the padding length from the whole.

Change-Id: Id370cad09ad82bb54febeb60b05f7e430cc8f963
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2016-12-02 14:47:29 +01:00
commit cff19c17c4
2 changed files with 41 additions and 3 deletions

View file

@ -28,12 +28,15 @@
#include <net/net_ip.h>
#include <net/nbuf.h>
#include <misc/util.h>
#define NET_ETH_BUF(buf) ((struct net_eth_hdr *)net_nbuf_ll(buf))
#define NET_ETH_PTYPE_ARP 0x0806
#define NET_ETH_PTYPE_IP 0x0800
#define NET_ETH_PTYPE_IPV6 0x86dd
#define NET_ETH_PTYPE_ARP 0x0806
#define NET_ETH_PTYPE_IP 0x0800
#define NET_ETH_PTYPE_IPV6 0x86dd
#define NET_ETH_MINIMAL_FRAME_SIZE 60
struct net_eth_addr {
uint8_t addr[6];

View file

@ -59,6 +59,39 @@ const struct net_eth_addr *net_eth_broadcast_addr(void)
#define print_ll_addrs(...)
#endif
static inline void ethernet_update_length(struct net_if *iface,
struct net_buf *buf)
{
uint16_t len;
/* Let's check IP payload's length. If it's smaller than 46 bytes,
* i.e. smaller than minimal Ethernet frame size minus ethernet
* header size,then Ethernet has padded so it fits in the minimal
* frame size of 60 bytes. In that case, we need to get rid of it.
*/
if (net_nbuf_family(buf) == AF_INET) {
len = ((NET_IPV4_BUF(buf)->len[0] << 8) +
NET_IPV4_BUF(buf)->len[1]);
} else {
len = ((NET_IPV6_BUF(buf)->len[0] << 8) +
NET_IPV6_BUF(buf)->len[1]);
}
if (len < NET_ETH_MINIMAL_FRAME_SIZE - sizeof(struct net_eth_hdr)) {
struct net_buf *frag;
for (frag = buf->frags; frag; frag = frag->frags) {
if (frag->len < len) {
len -= frag->len;
} else {
frag->len = len;
len = 0;
}
}
}
}
static enum net_verdict ethernet_recv(struct net_if *iface,
struct net_buf *buf)
{
@ -116,6 +149,8 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
return net_arp_input(buf);
}
#endif
ethernet_update_length(iface, buf);
return NET_CONTINUE;
}