tethering: Fix bridge module loading problem
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Wed, 5 Sep 2012 14:52:45 +0000 (17:52 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 7 Sep 2012 05:44:23 +0000 (08:44 +0300)
Connman tries to check if bridging is supported by the kernel by checking
whether "/proc/sys/net/bridge" is present. If the bridge is a kernel
module which is not already loaded, then tethering cannot be enabled.

Instead of checking for the file we invoke the "get bridge version" socket
ioctl and the kernel will handle module loading issues - if the bridge
module is not loaded, it will first load it, and then check the version.

src/tethering.c

index decb1122689db881aea8507a6536e9a3e30de765..b7343032df28920a75b8036ca85c0575ca95599f 100644 (file)
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <linux/if_tun.h>
+#include <linux/if_bridge.h>
 
 #include "connman.h"
 
@@ -46,8 +47,6 @@
 #define DBUS_TYPE_UNIX_FD -1
 #endif
 
-#define BRIDGE_PROC_DIR "/proc/sys/net/bridge"
-
 #define BRIDGE_NAME "tether"
 #define BRIDGE_DNS "8.8.8.8"
 
@@ -79,12 +78,19 @@ struct connman_private_network {
 
 const char *__connman_tethering_get_bridge(void)
 {
-       struct stat st;
+       int sk, err;
+       unsigned long args[3];
 
-       if (stat(BRIDGE_PROC_DIR, &st) < 0) {
-               connman_error("Missing support for 802.1d ethernet bridging");
+       sk = socket(AF_INET, SOCK_STREAM, 0);
+       if (sk < 0)
+               return NULL;
+
+       args[0] = BRCTL_GET_VERSION;
+       args[1] = args[2] = 0;
+       err = ioctl(sk, SIOCGIFBR, &args);
+       close(sk);
+       if (err == -1)
                return NULL;
-       }
 
        return BRIDGE_NAME;
 }