This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 2b34bcfcb1e0eeb91c4e63d0fa4c3dbdf6ca43a2 Author: Zhe Weng <[email protected]> AuthorDate: Tue Jan 7 17:30:59 2025 +0800 netdev/ioctl: Add support for simple VLAN ioctl Supporting ADD_VLAN_CMD and DEL_VLAN_CMD of SIOCSIFVLAN Ref: https://github.com/torvalds/linux/blob/v6.12/net/8021q/vlan.c#L621 Signed-off-by: Zhe Weng <[email protected]> --- drivers/net/netdev_upperhalf.c | 47 ++++++++++++++++++++++++++++++++-- include/nuttx/net/ioctl.h | 5 ++++ include/nuttx/net/vlan.h | 29 +++++++++++++++++++++ net/netdev/netdev_ioctl.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) diff --git a/drivers/net/netdev_upperhalf.c b/drivers/net/netdev_upperhalf.c index 3c6bd282bae..8e79525dff0 100644 --- a/drivers/net/netdev_upperhalf.c +++ b/drivers/net/netdev_upperhalf.c @@ -1133,6 +1133,40 @@ int netdev_upper_wireless_ioctl(FAR struct netdev_lowerhalf_s *lower, } #endif /* CONFIG_NETDEV_WIRELESS_HANDLER */ +/**************************************************************************** + * Name: netdev_upper_vlan_ioctl + * + * Description: + * Support for VLAN handlers in ioctl. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_VLAN +int netdev_upper_vlan_ioctl(FAR struct netdev_lowerhalf_s *lower, + int cmd, unsigned long arg) +{ + FAR struct vlan_ioctl_args *args = + (FAR struct vlan_ioctl_args *)(uintptr_t)arg; + + if (cmd != SIOCSIFVLAN && cmd != SIOCGIFVLAN) + { + return -ENOTTY; + } + + switch (args->cmd) + { + case ADD_VLAN_CMD: + return vlan_register(lower, args->u.VID); + + case DEL_VLAN_CMD: + vlan_unregister(lower); + return OK; + } + + return -ENOSYS; +} +#endif /* CONFIG_NET_VLAN */ + /**************************************************************************** * Name: netdev_upper_ifup/ifdown/addmac/rmmac/ioctl * @@ -1241,11 +1275,12 @@ static int netdev_upper_ioctl(FAR struct net_driver_s *dev, int cmd, { FAR struct netdev_upperhalf_s *upper = dev->d_private; FAR struct netdev_lowerhalf_s *lower = upper->lower; + int ret = -ENOTTY; #ifdef CONFIG_NETDEV_WIRELESS_HANDLER if (lower->iw_ops) { - int ret = netdev_upper_wireless_ioctl(lower, cmd, arg); + ret = netdev_upper_wireless_ioctl(lower, cmd, arg); if (ret != -ENOTTY) { return ret; @@ -1253,12 +1288,20 @@ static int netdev_upper_ioctl(FAR struct net_driver_s *dev, int cmd, } #endif +#ifdef CONFIG_NET_VLAN + ret = netdev_upper_vlan_ioctl(lower, cmd, arg); + if (ret != -ENOTTY) + { + return ret; + } +#endif + if (lower->ops->ioctl) { return lower->ops->ioctl(lower, cmd, arg); } - return -ENOTTY; + return ret; } #endif diff --git a/include/nuttx/net/ioctl.h b/include/nuttx/net/ioctl.h index aedd0ab6af3..75bf689f9d5 100644 --- a/include/nuttx/net/ioctl.h +++ b/include/nuttx/net/ioctl.h @@ -154,6 +154,11 @@ #define SIOCNOTIFYRECVCPU _SIOC(0x003F) /* RSS notify recv cpu */ +/* VLAN control *************************************************************/ + +#define SIOCGIFVLAN _SIOC(0x0043) /* Get VLAN interface */ +#define SIOCSIFVLAN _SIOC(0x0044) /* Set VLAN interface */ + /**************************************************************************** * Public Type Definitions ****************************************************************************/ diff --git a/include/nuttx/net/vlan.h b/include/nuttx/net/vlan.h index 1085d540534..5a685651cb3 100644 --- a/include/nuttx/net/vlan.h +++ b/include/nuttx/net/vlan.h @@ -49,6 +49,35 @@ * Public Type Definitions ****************************************************************************/ +/* Passed in vlan_ioctl_args structure to determine behaviour. */ + +enum vlan_ioctl_cmds +{ + ADD_VLAN_CMD, + DEL_VLAN_CMD, + SET_VLAN_INGRESS_PRIORITY_CMD, + SET_VLAN_EGRESS_PRIORITY_CMD, + GET_VLAN_INGRESS_PRIORITY_CMD, + GET_VLAN_EGRESS_PRIORITY_CMD, + SET_VLAN_NAME_TYPE_CMD, + SET_VLAN_FLAG_CMD, + GET_VLAN_REALDEV_NAME_CMD, /* If this works, you know it's a VLAN device, btw */ + GET_VLAN_VID_CMD /* Get the VID of this VLAN (specified by name) */ +}; + +struct vlan_ioctl_args +{ + int cmd; /* Should be one of the vlan_ioctl_cmds enum above. */ + char device1[IFNAMSIZ]; + + union + { + int16_t VID; + } u; + + int16_t vlan_qos; +}; + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 134f5b10bfa..e5474842d09 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -45,6 +45,7 @@ #include <nuttx/net/netdev.h> #include <nuttx/net/radiodev.h> +#include <nuttx/net/vlan.h> #ifdef CONFIG_NET_6LOWPAN # include <nuttx/net/sixlowpan.h> @@ -653,6 +654,53 @@ static int netdev_wifr_ioctl(FAR struct socket *psock, int cmd, } #endif +/**************************************************************************** + * Name: netdev_vlan_ioctl + * + * Description: + * Perform VLAN network device specific operations. + * + * Input Parameters: + * psock Socket structure + * cmd The ioctl command + * req The argument of the ioctl cmd + * + * Returned Value: + * >=0 on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_VLAN) +static int netdev_vlan_ioctl(FAR struct socket *psock, int cmd, + FAR struct vlan_ioctl_args *req) +{ + FAR struct net_driver_s *dev; + int ret = -ENOTTY; + + /* Verify that this is a valid VLAN IOCTL command */ + + if (cmd == SIOCGIFVLAN || cmd == SIOCSIFVLAN) + { + /* Get the network device associated with the IOCTL command */ + + dev = netdev_findbyname(req->device1); + if (dev != NULL) + { + /* Just forward the IOCTL to the network driver */ + + ret = dev->d_ioctl(dev, cmd, (unsigned long)(uintptr_t)req); + } + else + { + ret = -ENODEV; + } + } + + return ret; +} +#endif + /**************************************************************************** * Name: netdev_ifr_split_idx * @@ -1865,6 +1913,16 @@ int psock_vioctl(FAR struct socket *psock, int cmd, va_list ap) } #endif +#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_VLAN) + /* Check for a VLAN command */ + + if (ret == -ENOTTY) + { + ret = netdev_vlan_ioctl(psock, cmd, + (FAR struct vlan_ioctl_args *)(uintptr_t)arg); + } +#endif + #ifdef HAVE_IEEE802154_IOCTL /* Check for a IEEE802.15.4 network device IOCTL command */
