drivers/net/tun.c: Call ipv[4|6]_input dynamically by checking packet header and remove the code duplication
This commit is contained in:
parent
3f1b6543db
commit
8193c28e91
@ -74,6 +74,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* If processing is not done at the interrupt level, then high priority
|
/* If processing is not done at the interrupt level, then high priority
|
||||||
* work queue support is required.
|
* work queue support is required.
|
||||||
*/
|
*/
|
||||||
@ -111,6 +112,11 @@
|
|||||||
# define BUF ((struct eth_hdr_s *)priv->dev.d_buf)
|
# define BUF ((struct eth_hdr_s *)priv->dev.d_buf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is a helper pointer for accessing the contents of the ip header */
|
||||||
|
|
||||||
|
#define IPv4BUF ((struct ipv4_hdr_s *)(priv->dev.d_buf + priv->dev.d_llhdrlen))
|
||||||
|
#define IPv6BUF ((struct ipv6_hdr_s *)(priv->dev.d_buf + priv->dev.d_llhdrlen))
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -196,8 +202,8 @@ static int tun_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
|||||||
static void tun_ipv6multicast(FAR struct tun_device_s *priv);
|
static void tun_ipv6multicast(FAR struct tun_device_s *priv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int tun_dev_init(FAR struct tun_device_s *priv,
|
static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep,
|
||||||
FAR struct file *filep, FAR const char *devfmt);
|
FAR const char *devfmt, bool tun);
|
||||||
static int tun_dev_uninit(FAR struct tun_device_s *priv);
|
static int tun_dev_uninit(FAR struct tun_device_s *priv);
|
||||||
|
|
||||||
/* File interface */
|
/* File interface */
|
||||||
@ -329,7 +335,7 @@ static void tun_pollnotify(FAR struct tun_device_s *priv, pollevent_t eventset)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: tun_transmit
|
* Name: tun_fd_transmit
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Start hardware transmission. Called either from the txdone interrupt
|
* Start hardware transmission. Called either from the txdone interrupt
|
||||||
@ -451,23 +457,21 @@ static int tun_txpoll_tap(struct net_driver_s *dev)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
#ifdef CONFIG_NET_IPv4
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
if (IFF_IS_IPv4(priv->dev.d_flags))
|
if (IFF_IS_IPv4(priv->dev.d_flags))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
arp_out(&priv->dev);
|
arp_out(&priv->dev);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv4 */
|
#endif /* CONFIG_NET_IPv4 */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
#ifdef CONFIG_NET_IPv4
|
if (IFF_IS_IPv6(priv->dev.d_flags))
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
neighbor_out(&priv->dev);
|
neighbor_out(&priv->dev);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPv6 */
|
#endif /* CONFIG_NET_IPv6 */
|
||||||
|
|
||||||
|
if (!devif_loopback(dev))
|
||||||
|
{
|
||||||
/* Send the packet */
|
/* Send the packet */
|
||||||
|
|
||||||
priv->read_d_len = priv->dev.d_len;
|
priv->read_d_len = priv->dev.d_len;
|
||||||
@ -475,6 +479,7 @@ static int tun_txpoll_tap(struct net_driver_s *dev)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If zero is returned, the polling will continue until all connections have
|
/* If zero is returned, the polling will continue until all connections have
|
||||||
* been examined.
|
* been examined.
|
||||||
@ -518,6 +523,8 @@ static int tun_txpoll_tun(struct net_driver_s *dev)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->dev.d_len > 0)
|
if (priv->dev.d_len > 0)
|
||||||
|
{
|
||||||
|
if (!devif_loopback(dev))
|
||||||
{
|
{
|
||||||
/* Send the packet */
|
/* Send the packet */
|
||||||
|
|
||||||
@ -526,6 +533,7 @@ static int tun_txpoll_tun(struct net_driver_s *dev)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If zero is returned, the polling will continue until all connections have
|
/* If zero is returned, the polling will continue until all connections have
|
||||||
* been examined.
|
* been examined.
|
||||||
@ -585,8 +593,6 @@ static void tun_net_receive(FAR struct tun_device_s *priv)
|
|||||||
#ifdef CONFIG_NET_ETHERNET
|
#ifdef CONFIG_NET_ETHERNET
|
||||||
static void tun_net_receive_tap(FAR struct tun_device_s *priv)
|
static void tun_net_receive_tap(FAR struct tun_device_s *priv)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Copy the data data from the hardware to priv->dev.d_buf. Set amount of
|
/* Copy the data data from the hardware to priv->dev.d_buf. Set amount of
|
||||||
* data in priv->dev.d_len
|
* data in priv->dev.d_len
|
||||||
*/
|
*/
|
||||||
@ -607,32 +613,54 @@ static void tun_net_receive_tap(FAR struct tun_device_s *priv)
|
|||||||
ninfo("IPv4 frame\n");
|
ninfo("IPv4 frame\n");
|
||||||
NETDEV_RXIPV4(&priv->dev);
|
NETDEV_RXIPV4(&priv->dev);
|
||||||
|
|
||||||
/* Give the IPv4 packet to the network layer. ipv4_input will return
|
/* Give the IPv4 packet to the network layer. */
|
||||||
* an error if it is unable to dispatch the packet at this time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
arp_ipin(&priv->dev);
|
arp_ipin(&priv->dev);
|
||||||
ret = ipv4_input(&priv->dev);
|
ipv4_input(&priv->dev);
|
||||||
|
}
|
||||||
if (ret == OK)
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
if (BUF->type == HTONS(ETHTYPE_IP6))
|
||||||
{
|
{
|
||||||
|
ninfo("Iv6 frame\n");
|
||||||
|
NETDEV_RXIPV6(&priv->dev);
|
||||||
|
|
||||||
|
/* Give the IPv6 packet to the network layer. */
|
||||||
|
|
||||||
|
ipv6_input(&priv->dev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_NET_ARP
|
||||||
|
if (BUF->type == htons(ETHTYPE_ARP))
|
||||||
|
{
|
||||||
|
arp_arpin(&priv->dev);
|
||||||
|
NETDEV_RXARP(&priv->dev);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
NETDEV_RXDROPPED(&priv->dev);
|
||||||
|
priv->dev.d_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the above function invocation resulted in data that should be
|
/* If the above function invocation resulted in data that should be
|
||||||
* sent out on the network, the field d_len will set to a value > 0.
|
* sent out on the network, the field d_len will set to a value > 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (priv->dev.d_len > 0)
|
if (priv->dev.d_len > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Update the Ethernet header with the correct MAC address */
|
/* Update the Ethernet header with the correct MAC address */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv4
|
||||||
if (IFF_IS_IPv4(priv->dev.d_flags))
|
if (IFF_IS_IPv4(priv->dev.d_flags))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
arp_out(&priv->dev);
|
arp_out(&priv->dev);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
else
|
if (IFF_IS_IPv6(priv->dev.d_flags))
|
||||||
{
|
{
|
||||||
neighbor_out(&priv->dev);
|
neighbor_out(&priv->dev);
|
||||||
}
|
}
|
||||||
@ -643,89 +671,6 @@ static void tun_net_receive_tap(FAR struct tun_device_s *priv)
|
|||||||
priv->write_d_len = priv->dev.d_len;
|
priv->write_d_len = priv->dev.d_len;
|
||||||
tun_fd_transmit(priv);
|
tun_fd_transmit(priv);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->dev.d_len = 0;
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
if (BUF->type == HTONS(ETHTYPE_IP6))
|
|
||||||
{
|
|
||||||
ninfo("Iv6 frame\n");
|
|
||||||
NETDEV_RXIPV6(&priv->dev);
|
|
||||||
|
|
||||||
/* Give the IPv6 packet to the network layer. ipv6_input will return
|
|
||||||
* an error if it is unable to dispatch the packet at this time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = ipv6_input(&priv->dev);
|
|
||||||
|
|
||||||
if (ret == OK)
|
|
||||||
{
|
|
||||||
if (priv->dev.d_len > 0)
|
|
||||||
{
|
|
||||||
/* Update the Ethernet header with the correct MAC address */
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv4
|
|
||||||
if (IFF_IS_IPv4(priv->dev.d_flags))
|
|
||||||
{
|
|
||||||
arp_out(&priv->dev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
|
||||||
{
|
|
||||||
neighbor_out(&priv->dev);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
priv->write_d_len = priv->dev.d_len;
|
|
||||||
tun_fd_transmit(priv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->write_d_len = 0;
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_ARP
|
|
||||||
if (BUF->type == htons(ETHTYPE_ARP))
|
|
||||||
{
|
|
||||||
arp_arpin(&priv->dev);
|
|
||||||
NETDEV_RXARP(&priv->dev);
|
|
||||||
|
|
||||||
/* If the above function invocation resulted in data that should be
|
|
||||||
* sent out on the network, the field d_len will set to a value > 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->dev.d_len > 0)
|
|
||||||
{
|
|
||||||
priv->write_d_len = priv->dev.d_len;
|
|
||||||
tun_fd_transmit(priv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
NETDEV_RXDROPPED(&priv->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -748,8 +693,6 @@ static void tun_net_receive_tap(FAR struct tun_device_s *priv)
|
|||||||
|
|
||||||
static void tun_net_receive_tun(FAR struct tun_device_s *priv)
|
static void tun_net_receive_tun(FAR struct tun_device_s *priv)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Copy the data data from the hardware to priv->dev.d_buf. Set amount of
|
/* Copy the data data from the hardware to priv->dev.d_buf. Set amount of
|
||||||
* data in priv->dev.d_len
|
* data in priv->dev.d_len
|
||||||
*/
|
*/
|
||||||
@ -762,50 +705,37 @@ static void tun_net_receive_tun(FAR struct tun_device_s *priv)
|
|||||||
pkt_input(&priv->dev);
|
pkt_input(&priv->dev);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We only accept IP packets of the configured type and ARP packets */
|
/* We only accept IP packets of the configured type */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4)
|
#if defined(CONFIG_NET_IPv4)
|
||||||
|
if ((IPv4BUF->vhl & IP_VERSION_MASK) == IPv4_VERSION)
|
||||||
|
{
|
||||||
ninfo("IPv4 frame\n");
|
ninfo("IPv4 frame\n");
|
||||||
NETDEV_RXIPV4(&priv->dev);
|
NETDEV_RXIPV4(&priv->dev);
|
||||||
|
|
||||||
/* Give the IPv4 packet to the network layer. ipv4_input will return
|
/* Give the IPv4 packet to the network layer. */
|
||||||
* an error if it is unable to dispatch the packet at this time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = ipv4_input(&priv->dev);
|
ipv4_input(&priv->dev);
|
||||||
if (ret == OK)
|
|
||||||
{
|
|
||||||
/* If the above function invocation resulted in data that should be
|
|
||||||
* sent out on the network, the field d_len will set to a value > 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (priv->dev.d_len > 0)
|
|
||||||
{
|
|
||||||
priv->write_d_len = priv->dev.d_len;
|
|
||||||
tun_fd_transmit(priv);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_NET_IPv6)
|
||||||
|
if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION)
|
||||||
{
|
{
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->dev.d_len = 0;
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(CONFIG_NET_IPv6)
|
|
||||||
ninfo("Iv6 frame\n");
|
ninfo("Iv6 frame\n");
|
||||||
NETDEV_RXIPV6(&priv->dev);
|
NETDEV_RXIPV6(&priv->dev);
|
||||||
|
|
||||||
/* Give the IPv6 packet to the network layer. ipv6_input will return
|
/* Give the IPv6 packet to the network layer. */
|
||||||
* an error if it is unable to dispatch the packet at this time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = ipv6_input(&priv->dev);
|
ipv6_input(&priv->dev);
|
||||||
if (ret == OK)
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
NETDEV_RXDROPPED(&priv->dev);
|
||||||
|
priv->dev.d_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the above function invocation resulted in data that should be
|
/* If the above function invocation resulted in data that should be
|
||||||
* sent out on the network, the field d_len will set to a value > 0.
|
* sent out on the network, the field d_len will set to a value > 0.
|
||||||
*/
|
*/
|
||||||
@ -815,20 +745,6 @@ static void tun_net_receive_tun(FAR struct tun_device_s *priv)
|
|||||||
priv->write_d_len = priv->dev.d_len;
|
priv->write_d_len = priv->dev.d_len;
|
||||||
tun_fd_transmit(priv);
|
tun_fd_transmit(priv);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
priv->write_d_len = 0;
|
|
||||||
tun_pollnotify(priv, POLLOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
NETDEV_RXDROPPED(&priv->dev);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1047,7 +963,7 @@ static void tun_txavail_work(FAR void *arg)
|
|||||||
|
|
||||||
/* Check if there is room to hold another network packet. */
|
/* Check if there is room to hold another network packet. */
|
||||||
|
|
||||||
if (priv->read_d_len != 0 || priv->write_d_len != 0)
|
if (priv->read_d_len != 0)
|
||||||
{
|
{
|
||||||
tun_unlock(priv);
|
tun_unlock(priv);
|
||||||
return;
|
return;
|
||||||
@ -1191,7 +1107,7 @@ static void tun_ipv6multicast(FAR struct tun_device_s *priv)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep,
|
static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep,
|
||||||
FAR const char *devfmt)
|
FAR const char *devfmt, bool tun)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -1222,15 +1138,6 @@ static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep,
|
|||||||
|
|
||||||
priv->txpoll = wd_create(); /* Create periodic poll timer */
|
priv->txpoll = wd_create(); /* Create periodic poll timer */
|
||||||
|
|
||||||
/* Initialize other variables */
|
|
||||||
|
|
||||||
priv->write_d_len = 0;
|
|
||||||
priv->read_wait = false;
|
|
||||||
|
|
||||||
/* Put the interface in the down state */
|
|
||||||
|
|
||||||
tun_ifdown(&priv->dev);
|
|
||||||
|
|
||||||
/* Assign d_ifname if specified. */
|
/* Assign d_ifname if specified. */
|
||||||
|
|
||||||
if (devfmt)
|
if (devfmt)
|
||||||
@ -1240,8 +1147,7 @@ static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep,
|
|||||||
|
|
||||||
/* Register the device with the OS so that socket IOCTLs can be performed */
|
/* Register the device with the OS so that socket IOCTLs can be performed */
|
||||||
|
|
||||||
ret = netdev_register(&priv->dev, NET_LL_TUN);
|
ret = netdev_register(&priv->dev, tun ? NET_LL_TUN : NET_LL_ETHERNET);
|
||||||
|
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
nxsem_destroy(&priv->waitsem);
|
nxsem_destroy(&priv->waitsem);
|
||||||
@ -1297,7 +1203,7 @@ static int tun_close(FAR struct file *filep)
|
|||||||
FAR struct tun_device_s *priv = filep->f_priv;
|
FAR struct tun_device_s *priv = filep->f_priv;
|
||||||
int intf;
|
int intf;
|
||||||
|
|
||||||
if (!priv)
|
if (priv == NULL)
|
||||||
{
|
{
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -1323,7 +1229,7 @@ static ssize_t tun_write(FAR struct file *filep, FAR const char *buffer,
|
|||||||
FAR struct tun_device_s *priv = filep->f_priv;
|
FAR struct tun_device_s *priv = filep->f_priv;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (!priv)
|
if (priv == NULL)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -1372,7 +1278,7 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
size_t write_d_len;
|
size_t write_d_len;
|
||||||
size_t read_d_len;
|
size_t read_d_len;
|
||||||
|
|
||||||
if (!priv)
|
if (priv == NULL)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -1394,15 +1300,9 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
ret = (ssize_t)write_d_len;
|
ret = (ssize_t)write_d_len;
|
||||||
|
|
||||||
priv->write_d_len = 0;
|
priv->write_d_len = 0;
|
||||||
|
NETDEV_TXDONE(&priv->dev);
|
||||||
tun_pollnotify(priv, POLLOUT);
|
tun_pollnotify(priv, POLLOUT);
|
||||||
|
|
||||||
if (priv->read_d_len == 0)
|
|
||||||
{
|
|
||||||
net_lock();
|
|
||||||
tun_txdone(priv);
|
|
||||||
net_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,16 +1355,11 @@ int tun_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
|||||||
pollevent_t eventset;
|
pollevent_t eventset;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
if (!priv)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some sanity checking */
|
/* Some sanity checking */
|
||||||
|
|
||||||
if (!priv || !fds)
|
if (priv == NULL || fds == NULL)
|
||||||
{
|
{
|
||||||
return -ENODEV;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tun_lock(priv);
|
tun_lock(priv);
|
||||||
@ -1531,7 +1426,8 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
int intf;
|
int intf;
|
||||||
FAR struct ifreq *ifr = (FAR struct ifreq *)arg;
|
FAR struct ifreq *ifr = (FAR struct ifreq *)arg;
|
||||||
|
|
||||||
if (!ifr || ((ifr->ifr_flags & IFF_MASK) != IFF_TUN &&
|
if (ifr == NULL ||
|
||||||
|
((ifr->ifr_flags & IFF_MASK) != IFF_TUN &&
|
||||||
(ifr->ifr_flags & IFF_MASK) != IFF_TAP))
|
(ifr->ifr_flags & IFF_MASK) != IFF_TAP))
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -1552,7 +1448,8 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
intf++, free_tuns >>= 1);
|
intf++, free_tuns >>= 1);
|
||||||
|
|
||||||
ret = tun_dev_init(&g_tun_devices[intf], filep,
|
ret = tun_dev_init(&g_tun_devices[intf], filep,
|
||||||
*ifr->ifr_name ? ifr->ifr_name : 0);
|
*ifr->ifr_name ? ifr->ifr_name : 0,
|
||||||
|
(ifr->ifr_flags & IFF_MASK) == IFF_TUN);
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
tundev_unlock(tun);
|
tundev_unlock(tun);
|
||||||
@ -1563,30 +1460,6 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
|
|
||||||
priv = filep->f_priv;
|
priv = filep->f_priv;
|
||||||
strncpy(ifr->ifr_name, priv->dev.d_ifname, IFNAMSIZ);
|
strncpy(ifr->ifr_name, priv->dev.d_ifname, IFNAMSIZ);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ETHERNET
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Also, set the link type to NET_LL_ETHERNET */
|
|
||||||
|
|
||||||
priv->dev.d_lltype = NET_LL_ETHERNET;
|
|
||||||
}
|
|
||||||
else if ((ifr->ifr_flags & IFF_MASK) == IFF_TUN)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* TUN device -> handling an application data stream
|
|
||||||
* -> no header
|
|
||||||
*/
|
|
||||||
|
|
||||||
priv->dev.d_llhdrlen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tundev_unlock(tun);
|
tundev_unlock(tun);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@ -1603,7 +1476,7 @@ static int tun_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
* Name: tun_initialize
|
* Name: tun_initialize
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Instantiate a SLIP network interface.
|
* Instantiate a TUN network interface.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
*
|
*
|
||||||
@ -1625,3 +1498,4 @@ int tun_initialize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET && CONFIG_NET_TUN */
|
#endif /* CONFIG_NET && CONFIG_NET_TUN */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user