diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 4763087162..65d60e9fe0 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1159,7 +1159,7 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg) int intf; FAR struct ifreq *ifr = (FAR struct ifreq *)arg; - if (!ifr || (ifr->ifr_flags & IFF_MASK) != IFF_TUN) + if (!ifr || ((ifr->ifr_flags & IFF_MASK) != IFF_TUN && (ifr->ifr_flags & IFF_MASK) != IFF_TAP)) { return -EINVAL; } @@ -1191,6 +1191,21 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg) priv = filep->f_priv; strncpy(ifr->ifr_name, priv->dev.d_ifname, IFNAMSIZ); + if ((ifr->ifr_flags & IFF_MASK) == IFF_TAP) + { + /* TAP device -> handling raw Ethernet packets + * -> set appropriate Ethernet header length + */ + priv->dev.d_llhdrlen = ETH_HDRLEN; + } + else if ((ifr->ifr_flags & IFF_MASK) == IFF_TUN) + { + /* TUN device -> handling an application data stream + * -> no header + */ + priv->dev.d_llhdrlen = 0; + } + tundev_unlock(tun); return OK; diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c index 737d51195b..a3de997c85 100644 --- a/net/netdev/netdev_register.c +++ b/net/netdev/netdev_register.c @@ -251,7 +251,7 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype) #ifdef CONFIG_NET_TUN case NET_LL_TUN: /* Virtual Network Device (TUN) */ - dev->d_llhdrlen = 0; + dev->d_llhdrlen = 0; /* this will be overwritten by tun_ioctl if used as a TAP (layer 2) device */ dev->d_mtu = CONFIG_NET_TUN_MTU; #ifdef CONFIG_NET_TCP dev->d_recvwndo = CONFIG_NET_TUN_TCP_RECVWNDO;