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 */
 

Reply via email to