]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
vlan: Use new bridge ioctl()
authorSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Tue, 21 Nov 2017 20:14:45 +0000 (23:14 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 1 Jan 2019 22:23:43 +0000 (00:23 +0200)
Legacy ioctl() through SIOCDEVPRIVATE are deprecated. Follow the
approach taken by bridge-utils and make use of new bridge ioctl's
whenever possible.

For example, using legacy ioctl() breaks dynamic VLAN mode on 32-bit
Linux systems running 64-bit kernels.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
src/ap/vlan_full.c
src/common/linux_bridge.h
src/drivers/linux_ioctl.c

index cb39a8f214c96fb8f57c8304f748b00a2314d4e3..19aa3c649a5db23c12a7abfecdb7f04e45f35276 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "utils/common.h"
 #include "drivers/priv_netlink.h"
+#include "drivers/linux_ioctl.h"
 #include "common/linux_bridge.h"
 #include "common/linux_vlan.h"
 #include "utils/eloop.h"
@@ -143,6 +144,9 @@ static int br_delif(const char *br_name, const char *if_name)
                return -1;
        }
 
+       if (linux_br_del_if(fd, br_name, if_name) == 0)
+               goto done;
+
        if_index = if_nametoindex(if_name);
 
        if (if_index == 0) {
@@ -168,6 +172,7 @@ static int br_delif(const char *br_name, const char *if_name)
                return -1;
        }
 
+done:
        close(fd);
        return 0;
 }
@@ -194,6 +199,14 @@ static int br_addif(const char *br_name, const char *if_name)
                return -1;
        }
 
+       if (linux_br_add_if(fd, br_name, if_name) == 0)
+               goto done;
+       if (errno == EBUSY) {
+               /* The interface is already added. */
+               close(fd);
+               return 1;
+       }
+
        if_index = if_nametoindex(if_name);
 
        if (if_index == 0) {
@@ -224,6 +237,7 @@ static int br_addif(const char *br_name, const char *if_name)
                return -1;
        }
 
+done:
        close(fd);
        return 0;
 }
@@ -241,6 +255,9 @@ static int br_delbr(const char *br_name)
                return -1;
        }
 
+       if (linux_br_del(fd, br_name) == 0)
+               goto done;
+
        arg[0] = BRCTL_DEL_BRIDGE;
        arg[1] = (unsigned long) br_name;
 
@@ -252,6 +269,7 @@ static int br_delbr(const char *br_name)
                return -1;
        }
 
+done:
        close(fd);
        return 0;
 }
@@ -277,11 +295,19 @@ static int br_addbr(const char *br_name)
                return -1;
        }
 
+       if (linux_br_add(fd, br_name) == 0)
+               goto done;
+       if (errno == EEXIST) {
+               /* The bridge is already added. */
+               close(fd);
+               return 1;
+       }
+
        arg[0] = BRCTL_ADD_BRIDGE;
        arg[1] = (unsigned long) br_name;
 
        if (ioctl(fd, SIOCGIFBR, arg) < 0) {
-               if (errno == EEXIST) {
+               if (errno == EEXIST) {
                        /* The bridge is already added. */
                        close(fd);
                        return 1;
@@ -294,6 +320,7 @@ static int br_addbr(const char *br_name)
                }
        }
 
+done:
        /* Decrease forwarding delay to avoid EAPOL timeouts. */
        os_memset(&ifr, 0, sizeof(ifr));
        os_strlcpy(ifr.ifr_name, br_name, IFNAMSIZ);
index 7b768464fb542df27f90a2fef8376019fbba48a3..84386e60f7504889a1555e9ade9f8d467c903ee1 100644 (file)
@@ -9,6 +9,21 @@
 #ifndef LINUX_BRIDGE_H
 #define LINUX_BRIDGE_H
 
+/* This ioctl is defined in linux/sockios.h */
+
+#ifndef SIOCBRADDBR
+#define SIOCBRADDBR 0x89a0
+#endif
+#ifndef SIOCBRDELBR
+#define SIOCBRDELBR 0x89a1
+#endif
+#ifndef SIOCBRADDIF
+#define SIOCBRADDIF 0x89a2
+#endif
+#ifndef SIOCBRDELIF
+#define SIOCBRDELIF 0x89a3
+#endif
+
 /* This interface is defined in linux/if_bridge.h */
 
 #define BRCTL_GET_VERSION 0
index e21147af1bcd6f0e7d0fe8e890b09f86b91f6db1..7edb9df2edd49a3bfafec49ef1b0307ebc99cb6e 100644 (file)
@@ -12,6 +12,7 @@
 #include <net/if_arp.h>
 
 #include "utils/common.h"
+#include "common/linux_bridge.h"
 #include "linux_ioctl.h"
 
 
@@ -119,25 +120,14 @@ int linux_set_ifhwaddr(int sock, const char *ifname, const u8 *addr)
 }
 
 
-#ifndef SIOCBRADDBR
-#define SIOCBRADDBR 0x89a0
-#endif
-#ifndef SIOCBRDELBR
-#define SIOCBRDELBR 0x89a1
-#endif
-#ifndef SIOCBRADDIF
-#define SIOCBRADDIF 0x89a2
-#endif
-#ifndef SIOCBRDELIF
-#define SIOCBRDELIF 0x89a3
-#endif
-
-
 int linux_br_add(int sock, const char *brname)
 {
        if (ioctl(sock, SIOCBRADDBR, brname) < 0) {
+               int saved_errno = errno;
+
                wpa_printf(MSG_DEBUG, "Could not add bridge %s: %s",
                           brname, strerror(errno));
+               errno = saved_errno;
                return -1;
        }
 
@@ -170,8 +160,11 @@ int linux_br_add_if(int sock, const char *brname, const char *ifname)
        os_strlcpy(ifr.ifr_name, brname, IFNAMSIZ);
        ifr.ifr_ifindex = ifindex;
        if (ioctl(sock, SIOCBRADDIF, &ifr) < 0) {
+               int saved_errno = errno;
+
                wpa_printf(MSG_DEBUG, "Could not add interface %s into bridge "
                           "%s: %s", ifname, brname, strerror(errno));
+               errno = saved_errno;
                return -1;
        }