bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/4] lwip: Call if_change_flags() inside a thread-safe context


From: Joan Lledó
Subject: [PATCH 4/4] lwip: Call if_change_flags() inside a thread-safe context
Date: Thu, 2 May 2019 11:55:02 +0200

* lwip/port/netif/ifcommon.c:
        * Changing flags for a device (e.g. by inetutils-ifconfig) now
          takes the big lock to ensure the stack is not doing anything else.
---
 lwip/port/netif/ifcommon.c | 61 +++++++++++++++++++++++++++++++++-----
 1 file changed, 54 insertions(+), 7 deletions(-)

diff --git a/lwip/port/netif/ifcommon.c b/lwip/port/netif/ifcommon.c
index a7f28351..eb4dae20 100644
--- a/lwip/port/netif/ifcommon.c
+++ b/lwip/port/netif/ifcommon.c
@@ -25,6 +25,8 @@
 #include <net/if.h>
 #include <errno.h>
 
+#include <lwip/tcpip.h>
+
 /* Open the device and set the interface up */
 static error_t
 if_open (struct netif *netif)
@@ -99,22 +101,67 @@ if_terminate (struct netif * netif)
   return ifc->terminate (netif);
 }
 
+/* Args for _if_change_flags() */
+struct if_change_flags_args
+{
+  struct netif *netif;
+  uint16_t flags;
+};
+
+/*
+ * Implementation of if_change_flags(), called inside a thread-safe context
+ */
+static void
+_if_change_flags (void *arg)
+{
+  error_t err;
+  struct ifcommon *ifc;
+  uint16_t oldflags;
+  struct if_change_flags_args *args = (struct if_change_flags_args *) arg;
+
+  ifc = netif_get_state (args->netif);
+
+  if (ifc == NULL)
+    {
+      /* The user provided no interface */
+      errno = EINVAL;
+      return;
+    }
+
+  oldflags = ifc->flags;
+
+  err = ifc->change_flags (args->netif, args->flags);
+
+  if (!err && ((oldflags ^ args->flags) & IFF_UP))     /* Bit is different  ? 
*/
+    err = ((oldflags & IFF_UP) ? if_close : if_open) (args->netif);
+
+  if (err)
+    errno = err;
+
+  free (args);
+
+  return;
+}
+
 /*
  * Change device flags.
  *
  * If IFF_UP changes, it opens/closes the device accordingly.
  */
 error_t
-if_change_flags (struct netif * netif, uint16_t flags)
+if_change_flags (struct netif *netif, uint16_t flags)
 {
   error_t err;
-  struct ifcommon *ifc = netif_get_state (netif);
-  uint16_t oldflags = ifc->flags;
 
-  err = ifc->change_flags (netif, flags);
+  /* Call _if_change_flags() inside the tcpip_thread */
+  struct if_change_flags_args *args =
+    calloc (1, sizeof (struct if_change_flags_args));
+  args->netif = netif;
+  args->flags = flags;
+  err = tcpip_callback (_if_change_flags, args);
 
-  if ((oldflags ^ flags) & IFF_UP)     /* Bit is different  ? */
-    ((oldflags & IFF_UP) ? if_close : if_open) (netif);
+  if (err)
+    return err;
 
-  return err;
+  return errno;
 }
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]