Discussion:
[RFC] VLAN
Marcus Folkesson
2015-03-31 18:08:38 UTC
Permalink
This patch enable support for Virtual LANs.
It has been tested and works pretty well.

The VLAN technology is similiar to the ethernet dito.
At first, I was thinking about to integrate the support in the Ethernet
technology itself, but I think is should be a seperate technology for better
mapping into the current driver model.
Feedback on this is appreciated.

Another thing I want feedback on is the service name. For now the
service appear as:
vlan_<MAC to bounded IF>_<VLAN IFNAME>
For example:
vlan_5c260a4bf6a3_vlan3

The group is set to IFNAME. I think the group-name should be "virtual" instead,
but we need some way to seperate all VLANs.
The MAC address is fixed and the technology should also be fixed (to "vlan").
Then it's just the group field left.

Cheers
Marcus Folkesson
Marcus Folkesson
2015-03-31 18:08:39 UTC
Permalink
From: Marcus Folkesson <***@gmail.com>

Support for multiple VLANs binded to the same interface.
VLAN services appear as:
vlan_<MAC to bounded IF>_<VLAN IFNAME>
For example:
vlan_5c260a4bf6a3_vlan3

Signed-off-by: Marcus Folkesson <***@gmail.com>
---
Makefile.plugins | 5 +
README | 8 ++
configure.ac | 5 +
include/device.h | 1 +
include/network.h | 1 +
include/service.h | 3 +-
plugins/vlan.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/config.c | 1 +
src/detect.c | 1 +
src/device.c | 10 ++
src/network.c | 7 ++
src/notifier.c | 2 +
src/rfkill.c | 1 +
src/rtnl.c | 3 +
src/service.c | 27 +++-
src/session.c | 2 +
src/technology.c | 4 +
src/wispr.c | 1 +
18 files changed, 448 insertions(+), 3 deletions(-)
create mode 100644 plugins/vlan.c

diff --git a/Makefile.plugins b/Makefile.plugins
index e90ad19..590f89e 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -13,6 +13,11 @@ builtin_modules += ethernet
builtin_sources += plugins/ethernet.c
endif

+if VLAN
+builtin_modules += vlan
+builtin_sources += plugins/vlan.c
+endif
+
if GADGET
builtin_modules += gadget
builtin_sources += plugins/gadget.c
diff --git a/README b/README
index 531f396..c505fd9 100644
--- a/README
+++ b/README
@@ -71,6 +71,14 @@ For a working system, certain configuration options need to be enabled:
enabled. This option can be used to build a small daemon
for a specific system if Ethernet support is not required.

+ --disable-vlan
+
+ Disable support for VLAN on Ethernet and/or WiFi interfaces
+
+ By default VLAN technology support is built-in and
+ enabled. This option can be used to build a small daemon
+ for a specific system if VLAN support is not required.
+
--disable-gadget

Disable support for USB Ethernet Gadget devices
diff --git a/configure.ac b/configure.ac
index dd4b271..80655ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -291,6 +291,11 @@ AC_ARG_ENABLE(gadget, AC_HELP_STRING([--disable-gadget],
[enable_gadget=${enableval}])
AM_CONDITIONAL(GADGET, test "${enable_gadget}" != "no")

+AC_ARG_ENABLE(vlan, AC_HELP_STRING([--disable-vlan],
+ [disable VLAN support]),
+ [enable_vlan=${enableval}])
+AM_CONDITIONAL(VLAN, test "${enable_vlan}" != "no")
+
AC_ARG_ENABLE(wifi, AC_HELP_STRING([--disable-wifi],
[disable WiFi support]),
[enable_wifi=${enableval}])
diff --git a/include/device.h b/include/device.h
index 57b925c..cd734b3 100644
--- a/include/device.h
+++ b/include/device.h
@@ -43,6 +43,7 @@ enum connman_device_type {
CONNMAN_DEVICE_TYPE_CELLULAR = 4,
CONNMAN_DEVICE_TYPE_GPS = 5,
CONNMAN_DEVICE_TYPE_GADGET = 6,
+ CONNMAN_DEVICE_TYPE_VLAN = 7,
CONNMAN_DEVICE_TYPE_VENDOR = 10000,
};

diff --git a/include/network.h b/include/network.h
index d772699..5212b6f 100644
--- a/include/network.h
+++ b/include/network.h
@@ -46,6 +46,7 @@ enum connman_network_type {
CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN = 9,
CONNMAN_NETWORK_TYPE_CELLULAR = 10,
CONNMAN_NETWORK_TYPE_GADGET = 11,
+ CONNMAN_NETWORK_TYPE_VLAN = 12,
CONNMAN_NETWORK_TYPE_VENDOR = 10000,
};

diff --git a/include/service.h b/include/service.h
index 31dfce7..36786e6 100644
--- a/include/service.h
+++ b/include/service.h
@@ -45,8 +45,9 @@ enum connman_service_type {
CONNMAN_SERVICE_TYPE_VPN = 7,
CONNMAN_SERVICE_TYPE_GADGET = 8,
CONNMAN_SERVICE_TYPE_P2P = 9,
+ CONNMAN_SERVICE_TYPE_VLAN = 10,
};
-#define MAX_CONNMAN_SERVICE_TYPES 10
+#define MAX_CONNMAN_SERVICE_TYPES 11


enum connman_service_security {
diff --git a/plugins/vlan.c b/plugins/vlan.c
new file mode 100644
index 0000000..679f92d
--- /dev/null
+++ b/plugins/vlan.c
@@ -0,0 +1,369 @@
+/*
+ *
+* Connection Manager
+ *
+ * Copyright (C) 2015 Marcus Folkesson <***@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <net/if.h>
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP 0x10000
+#endif
+
+#include <glib.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/technology.h>
+#include <connman/plugin.h>
+#include <connman/device.h>
+#include <connman/inet.h>
+#include <connman/rtnl.h>
+#include <connman/log.h>
+#include <connman/setting.h>
+
+static bool vlan_tethering = false;
+
+struct ethernet_data {
+ int index;
+ unsigned flags;
+ unsigned int watch;
+ struct connman_network *network;
+};
+
+static int vlan_network_probe(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ return 0;
+}
+
+static void vlan_network_remove(struct connman_network *network)
+{
+ DBG("network %p", network);
+}
+
+static int vlan_network_connect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ connman_network_set_connected(network, true);
+
+ return 0;
+}
+
+static int vlan_network_disconnect(struct connman_network *network)
+{
+ DBG("network %p", network);
+
+ connman_network_set_connected(network, false);
+
+ return 0;
+}
+
+static struct connman_network_driver vlan_network_driver = {
+ .name = "vlan",
+ .type = CONNMAN_NETWORK_TYPE_VLAN,
+ .probe = vlan_network_probe,
+ .remove = vlan_network_remove,
+ .connect = vlan_network_connect,
+ .disconnect = vlan_network_disconnect,
+};
+
+static void add_network(struct connman_device *device,
+ struct ethernet_data *ethernet)
+{
+ struct connman_network *network;
+ int index;
+
+ network = connman_network_create("vlan",
+ CONNMAN_NETWORK_TYPE_VLAN);
+ if (!network)
+ return;
+
+ index = connman_device_get_index(device);
+ connman_network_set_index(network, index);
+
+ connman_network_set_name(network, "VLAN");
+
+ if (connman_device_add_network(device, network) < 0) {
+ connman_network_unref(network);
+ return;
+ }
+
+ if (!vlan_tethering)
+ /*
+ * Prevent service from starting the reconnect
+ * procedure as we do not want the DHCP client
+ * to run when tethering.
+ */
+ connman_network_set_group(network, connman_device_get_string(device, "Interface"));
+
+ ethernet->network = network;
+}
+
+static void remove_network(struct connman_device *device,
+ struct ethernet_data *ethernet)
+{
+ if (!ethernet->network)
+ return;
+
+ connman_device_remove_network(device, ethernet->network);
+ connman_network_unref(ethernet->network);
+
+ ethernet->network = NULL;
+}
+
+static void ethernet_newlink(unsigned flags, unsigned change, void *user_data)
+{
+ struct connman_device *device = user_data;
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+
+ DBG("index %d flags %d change %d", ethernet->index, flags, change);
+
+ if ((ethernet->flags & IFF_UP) != (flags & IFF_UP)) {
+ if (flags & IFF_UP) {
+ DBG("power on");
+ connman_device_set_powered(device, true);
+ } else {
+ DBG("power off");
+ connman_device_set_powered(device, false);
+ }
+ }
+
+ if ((ethernet->flags & IFF_LOWER_UP) != (flags & IFF_LOWER_UP)) {
+ if (flags & IFF_LOWER_UP) {
+ DBG("carrier on");
+ add_network(device, ethernet);
+ } else {
+ DBG("carrier off");
+ remove_network(device, ethernet);
+ }
+ }
+
+ ethernet->flags = flags;
+}
+
+static int vlan_dev_probe(struct connman_device *device)
+{
+ struct ethernet_data *ethernet;
+
+ DBG("device %p", device);
+
+ ethernet = g_try_new0(struct ethernet_data, 1);
+ if (!ethernet)
+ return -ENOMEM;
+
+ connman_device_set_data(device, ethernet);
+
+ ethernet->index = connman_device_get_index(device);
+ ethernet->flags = 0;
+
+ ethernet->watch = connman_rtnl_add_newlink_watch(ethernet->index,
+ ethernet_newlink, device);
+
+ return 0;
+}
+
+static void vlan_dev_remove(struct connman_device *device)
+{
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+
+ DBG("device %p", device);
+
+ connman_device_set_data(device, NULL);
+
+ connman_rtnl_remove_watch(ethernet->watch);
+
+ remove_network(device, ethernet);
+
+ g_free(ethernet);
+}
+
+static int vlan_dev_enable(struct connman_device *device)
+{
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+
+ DBG("device %p", device);
+
+ return connman_inet_ifup(ethernet->index);
+}
+
+static int vlan_dev_disable(struct connman_device *device)
+{
+ struct ethernet_data *ethernet = connman_device_get_data(device);
+
+ DBG("device %p", device);
+
+ return connman_inet_ifdown(ethernet->index);
+}
+
+static struct connman_device_driver vlan_dev_driver = {
+ .name = "vlan",
+ .type = CONNMAN_DEVICE_TYPE_VLAN,
+ .probe = vlan_dev_probe,
+ .remove = vlan_dev_remove,
+ .enable = vlan_dev_enable,
+ .disable = vlan_dev_disable,
+};
+
+static int vlan_tech_probe(struct connman_technology *technology)
+{
+ return 0;
+}
+
+static void vlan_tech_remove(struct connman_technology *technology)
+{
+ DBG("");
+}
+
+static GList *vlan_interface_list = NULL;
+
+static void vlan_tech_add_interface(struct connman_technology *technology,
+ int index, const char *name, const char *ident)
+{
+ DBG("index %d name %s ident %s", index, name, ident);
+
+ if (g_list_find(vlan_interface_list, GINT_TO_POINTER((int)index)))
+ return;
+
+ vlan_interface_list = g_list_prepend(vlan_interface_list,
+ (GINT_TO_POINTER((int) index)));
+}
+
+static void vlan_tech_remove_interface(struct connman_technology *technology,
+ int index)
+{
+ DBG("index %d", index);
+
+ vlan_interface_list = g_list_remove(vlan_interface_list,
+ GINT_TO_POINTER((int) index));
+}
+
+static void vlan_tech_enable_tethering(struct connman_technology *technology,
+ const char *bridge)
+{
+ GList *list;
+ struct ethernet_data *ethernet;
+
+ for (list = vlan_interface_list; list; list = list->next) {
+ int index = GPOINTER_TO_INT(list->data);
+ struct connman_device *device =
+ connman_device_find_by_index(index);
+
+ if (device) {
+ ethernet = connman_device_get_data(device);
+ if (ethernet)
+ remove_network(device, ethernet);
+ }
+
+ connman_technology_tethering_notify(technology, true);
+
+ connman_inet_ifup(index);
+
+ connman_inet_add_to_bridge(index, bridge);
+
+ vlan_tethering = true;
+ }
+}
+
+static void vlan_tech_disable_tethering(struct connman_technology *technology,
+ const char *bridge)
+{
+ GList *list;
+
+ for (list = vlan_interface_list; list; list = list->next) {
+ int index = GPOINTER_TO_INT(list->data);
+ struct connman_device *device =
+ connman_device_find_by_index(index);
+
+ connman_inet_remove_from_bridge(index, bridge);
+
+ connman_technology_tethering_notify(technology, false);
+
+ if (device)
+ connman_device_reconnect_service(device);
+
+ vlan_tethering = false;
+ }
+}
+
+static int vlan_tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
+ const char *bridge, bool enabled)
+{
+ if (!connman_technology_is_tethering_allowed(
+ CONNMAN_SERVICE_TYPE_VLAN))
+ return 0;
+
+ DBG("bridge %s enabled %d", bridge, enabled);
+
+ if (enabled)
+ vlan_tech_enable_tethering(technology, bridge);
+ else
+ vlan_tech_disable_tethering(technology, bridge);
+
+ return 0;
+}
+
+static struct connman_technology_driver vlan_tech_driver = {
+ .name = "vlan",
+ .type = CONNMAN_SERVICE_TYPE_VLAN,
+ .probe = vlan_tech_probe,
+ .remove = vlan_tech_remove,
+ .add_interface = vlan_tech_add_interface,
+ .remove_interface = vlan_tech_remove_interface,
+ .set_tethering = vlan_tech_set_tethering,
+};
+
+static int vlan_init(void)
+{
+ int err;
+
+ err = connman_technology_driver_register(&vlan_tech_driver);
+ if (err < 0)
+ return err;
+
+ err = connman_network_driver_register(&vlan_network_driver);
+ if (err < 0)
+ return err;
+
+ err = connman_device_driver_register(&vlan_dev_driver);
+ if (err < 0) {
+ connman_network_driver_unregister(&vlan_network_driver);
+ return err;
+ }
+
+ return 0;
+}
+
+static void vlan_exit(void)
+{
+ connman_technology_driver_unregister(&vlan_tech_driver);
+
+ connman_network_driver_unregister(&vlan_network_driver);
+
+ connman_device_driver_unregister(&vlan_dev_driver);
+}
+
+CONNMAN_PLUGIN_DEFINE(vlan, "VLAN interface plugin", VERSION,
+ CONNMAN_PLUGIN_PRIORITY_DEFAULT, vlan_init, vlan_exit)
diff --git a/src/config.c b/src/config.c
index a4c117e..9c47a97 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1137,6 +1137,7 @@ static int try_provision_service(struct connman_config_service *config,

case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:

if (__connman_service_string2type(config->type) != type)
return -ENOENT;
diff --git a/src/detect.c b/src/detect.c
index 6c03920..0de05f9 100644
--- a/src/detect.c
+++ b/src/detect.c
@@ -63,6 +63,7 @@ static void detect_newlink(unsigned short type, int index,
case CONNMAN_DEVICE_TYPE_ETHERNET:
case CONNMAN_DEVICE_TYPE_WIFI:
case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_VLAN:
break;
}

diff --git a/src/device.c b/src/device.c
index c0683ab..c7248ab 100644
--- a/src/device.c
+++ b/src/device.c
@@ -97,6 +97,8 @@ static const char *type2description(enum connman_device_type type)
return "Cellular";
case CONNMAN_DEVICE_TYPE_GADGET:
return "Gadget";
+ case CONNMAN_DEVICE_TYPE_VLAN:
+ return "VLAN";

}

@@ -121,6 +123,8 @@ static const char *type2string(enum connman_device_type type)
return "cellular";
case CONNMAN_DEVICE_TYPE_GADGET:
return "gadget";
+ case CONNMAN_DEVICE_TYPE_VLAN:
+ return "vlan";

}

@@ -147,6 +151,8 @@ enum connman_service_type __connman_device_get_service_type(
return CONNMAN_SERVICE_TYPE_CELLULAR;
case CONNMAN_DEVICE_TYPE_GADGET:
return CONNMAN_SERVICE_TYPE_GADGET;
+ case CONNMAN_DEVICE_TYPE_VLAN:
+ return CONNMAN_SERVICE_TYPE_VLAN;

}

@@ -852,6 +858,7 @@ int connman_device_add_network(struct connman_device *device,
const char *identifier = connman_network_get_identifier(network);

DBG("device %p network %p", device, network);
+ DBG("IDENTIFIER: %s\n", identifier);

if (!identifier)
return -EINVAL;
@@ -1093,6 +1100,7 @@ int __connman_device_request_scan(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
return -EOPNOTSUPP;
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_P2P:
@@ -1261,6 +1269,7 @@ struct connman_device *connman_device_create_from_index(int index)
return NULL;
case CONNMAN_DEVICE_TYPE_ETHERNET:
case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_VLAN:
case CONNMAN_DEVICE_TYPE_WIFI:
name = index2ident(index, "");
addr = index2addr(index);
@@ -1284,6 +1293,7 @@ struct connman_device *connman_device_create_from_index(int index)
break;
case CONNMAN_DEVICE_TYPE_ETHERNET:
case CONNMAN_DEVICE_TYPE_GADGET:
+ case CONNMAN_DEVICE_TYPE_VLAN:
ident = index2ident(index, NULL);
break;
case CONNMAN_DEVICE_TYPE_WIFI:
diff --git a/src/network.c b/src/network.c
index f61f698..9b7d544 100644
--- a/src/network.c
+++ b/src/network.c
@@ -101,6 +101,8 @@ static const char *type2string(enum connman_network_type type)
return "ethernet";
case CONNMAN_NETWORK_TYPE_GADGET:
return "gadget";
+ case CONNMAN_NETWORK_TYPE_VLAN:
+ return "vlan";
case CONNMAN_NETWORK_TYPE_WIFI:
return "wifi";
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
@@ -749,6 +751,7 @@ static int network_probe(struct connman_network *network)
return 0;
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -779,6 +782,7 @@ static void network_remove(struct connman_network *network)
break;
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -1091,6 +1095,7 @@ void connman_network_set_group(struct connman_network *network,
return;
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -1142,6 +1147,7 @@ bool __connman_network_get_weakness(struct connman_network *network)
case CONNMAN_NETWORK_TYPE_VENDOR:
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -2041,6 +2047,7 @@ void connman_network_update(struct connman_network *network)
return;
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
diff --git a/src/notifier.c b/src/notifier.c
index 5ba5324..8517190 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -149,6 +149,7 @@ void __connman_notifier_connect(enum connman_service_type type)
return;
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
@@ -196,6 +197,7 @@ void __connman_notifier_disconnect(enum connman_service_type type)
return;
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
diff --git a/src/rfkill.c b/src/rfkill.c
index 2bfb092..2480c70 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -88,6 +88,7 @@ static enum rfkill_type convert_service_type(enum connman_service_type type)
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_P2P:
case CONNMAN_SERVICE_TYPE_UNKNOWN:
return NUM_RFKILL_TYPES;
diff --git a/src/rtnl.c b/src/rtnl.c
index b8b02c4..15827ab 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface)
} else if (strcmp(line + 8, "gadget") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
+ } else if (strcmp(line + 8, "vlan") == 0) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_VLAN;
+ interface->device_type = CONNMAN_DEVICE_TYPE_VLAN;

} else {
interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
diff --git a/src/service.c b/src/service.c
index 7538bdd..fa355ec 100644
--- a/src/service.c
+++ b/src/service.c
@@ -200,6 +200,8 @@ const char *__connman_service_type2string(enum connman_service_type type)
return "vpn";
case CONNMAN_SERVICE_TYPE_GADGET:
return "gadget";
+ case CONNMAN_SERVICE_TYPE_VLAN:
+ return "vlan";
case CONNMAN_SERVICE_TYPE_P2P:
return "p2p";
}
@@ -216,6 +218,8 @@ enum connman_service_type __connman_service_string2type(const char *str)
return CONNMAN_SERVICE_TYPE_ETHERNET;
if (strcmp(str, "gadget") == 0)
return CONNMAN_SERVICE_TYPE_GADGET;
+ if (strcmp(str, "vlan") == 0)
+ return CONNMAN_SERVICE_TYPE_VLAN;
if (strcmp(str, "wifi") == 0)
return CONNMAN_SERVICE_TYPE_WIFI;
if (strcmp(str, "cellular") == 0)
@@ -372,6 +376,7 @@ int __connman_service_load_modifiable(struct connman_service *service)
/* fall through */
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_ETHERNET:
@@ -488,6 +493,7 @@ static int service_load(struct connman_service *service)
/* fall through */

case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
autoconnect = g_key_file_get_boolean(keyfile,
service->identifier, "AutoConnect", &error);
if (!error)
@@ -657,6 +663,7 @@ static int service_save(struct connman_service *service)
/* fall through */

case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
if (service->favorite)
g_key_file_set_boolean(keyfile, service->identifier,
"AutoConnect", service->autoconnect);
@@ -2324,6 +2331,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
connman_dbus_dict_append_dict(dict, "Ethernet",
append_ethernet, service);
break;
@@ -3562,6 +3570,7 @@ void __connman_service_set_active_session(bool enable, GSList *list)
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
if (enable)
active_sessions[type]++;
else
@@ -3582,12 +3591,13 @@ void __connman_service_set_active_session(bool enable, GSList *list)
list = g_slist_next(list);
}

- DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
+ DBG("eth %d wifi %d bt %d cellular %d gadget %d vlan %d sessions %d",
active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
+ active_sessions[CONNMAN_SERVICE_TYPE_VLAN],
active_count);
}

@@ -4009,7 +4019,8 @@ static DBusMessage *disconnect_service(DBusConnection *conn,
bool __connman_service_remove(struct connman_service *service)
{
if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
- service->type == CONNMAN_SERVICE_TYPE_GADGET)
+ service->type == CONNMAN_SERVICE_TYPE_GADGET ||
+ service->type == CONNMAN_SERVICE_TYPE_VLAN)
return false;

if (service->immutable || service->hidden ||
@@ -4708,6 +4719,11 @@ static gint service_compare(gconstpointer a, gconstpointer b)
return -1;
if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
return 1;
+
+ if (service_a->type == CONNMAN_SERVICE_TYPE_VLAN)
+ return -1;
+ if (service_b->type == CONNMAN_SERVICE_TYPE_VLAN)
+ return 1;
}

strength = (gint) service_b->strength - (gint) service_a->strength;
@@ -5787,6 +5803,7 @@ static bool prepare_network(struct connman_service *service)
break;
case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_GADGET:
+ case CONNMAN_NETWORK_TYPE_VLAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
case CONNMAN_NETWORK_TYPE_CELLULAR:
@@ -5845,6 +5862,7 @@ static int service_connect(struct connman_service *service)
return -EINVAL;
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_VPN:
@@ -5970,6 +5988,7 @@ int __connman_service_connect(struct connman_service *service,

case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_VPN:
@@ -6580,6 +6599,8 @@ static enum connman_service_type convert_network_type(struct connman_network *ne
return CONNMAN_SERVICE_TYPE_CELLULAR;
case CONNMAN_NETWORK_TYPE_GADGET:
return CONNMAN_SERVICE_TYPE_GADGET;
+ case CONNMAN_NETWORK_TYPE_VLAN:
+ return CONNMAN_SERVICE_TYPE_VLAN;
}

return CONNMAN_SERVICE_TYPE_UNKNOWN;
@@ -6724,6 +6745,7 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_CELLULAR:
case CONNMAN_SERVICE_TYPE_P2P:
@@ -6760,6 +6782,7 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
break;

case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_ETHERNET:
if (service->autoconnect) {
__connman_service_connect(service,
diff --git a/src/session.c b/src/session.c
index 08facc1..03e824b 100644
--- a/src/session.c
+++ b/src/session.c
@@ -178,6 +178,8 @@ static char *service2bearer(enum connman_service_type type)
return "ethernet";
case CONNMAN_SERVICE_TYPE_GADGET:
return "gadget";
+ case CONNMAN_SERVICE_TYPE_VLAN:
+ return "vlan";
case CONNMAN_SERVICE_TYPE_WIFI:
return "wifi";
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
diff --git a/src/technology.c b/src/technology.c
index 55303a0..bbd2621 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -140,6 +140,8 @@ static const char *get_name(enum connman_service_type type)
break;
case CONNMAN_SERVICE_TYPE_GADGET:
return "Gadget";
+ case CONNMAN_SERVICE_TYPE_VLAN:
+ return "VLAN";
case CONNMAN_SERVICE_TYPE_ETHERNET:
return "Wired";
case CONNMAN_SERVICE_TYPE_WIFI:
@@ -1334,6 +1336,7 @@ void __connman_technology_add_interface(enum connman_service_type type,
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_P2P:
break;
}
@@ -1385,6 +1388,7 @@ void __connman_technology_remove_interface(enum connman_service_type type,
case CONNMAN_SERVICE_TYPE_GPS:
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_P2P:
break;
}
diff --git a/src/wispr.c b/src/wispr.c
index ef4bdab..80c669d 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -839,6 +839,7 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)

switch (service_type) {
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VLAN:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
--
1.9.1
Jukka Rissanen
2015-04-01 07:33:20 UTC
Permalink
Hi Marcus,
Post by Marcus Folkesson
Support for multiple VLANs binded to the same interface.
vlan_<MAC to bounded IF>_<VLAN IFNAME>
vlan_5c260a4bf6a3_vlan3
diff --git a/src/rtnl.c b/src/rtnl.c
index b8b02c4..15827ab 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface)
} else if (strcmp(line + 8, "gadget") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
+ } else if (strcmp(line + 8, "vlan") == 0) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_VLAN;
+ interface->device_type = CONNMAN_DEVICE_TYPE_VLAN;
} else {
Checked this with ancient 3.2 kernel and for vlan interface there is no
DEVTYPE defined. For newer 3.19 kernel, the DEVTYPE is set to vlan as
expected.

I just wonder would it be possible to treat vlan device as a normal
ethernet device without separation between vlan and ethernet types. This
would solve this issue with different kernel versions.


Cheers,
Jukka
Marcus Folkesson
2015-04-01 09:12:17 UTC
Permalink
Post by Jukka Rissanen
Hi Marcus,
Post by Marcus Folkesson
Support for multiple VLANs binded to the same interface.
vlan_<MAC to bounded IF>_<VLAN IFNAME>
vlan_5c260a4bf6a3_vlan3
diff --git a/src/rtnl.c b/src/rtnl.c
index b8b02c4..15827ab 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface)
} else if (strcmp(line + 8, "gadget") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
+ } else if (strcmp(line + 8, "vlan") == 0) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_VLAN;
+ interface->device_type = CONNMAN_DEVICE_TYPE_VLAN;
} else {
Checked this with ancient 3.2 kernel and for vlan interface there is no
DEVTYPE defined. For newer 3.19 kernel, the DEVTYPE is set to vlan as
expected.
I just wonder would it be possible to treat vlan device as a normal
ethernet device without separation between vlan and ethernet types. This
would solve this issue with different kernel versions.
Cheers,
Jukka
Hi Jukka,

I have now checked with v3.0.35 and DEVTYPE is indeed not there (not even
for standard ethernet).
If I read the code right, (rtnl.c:read_uevent()), the only types
supported without DEVTYPE is just ethernet and wifi?

The first implementation was to let the ethernet device handle vlans,
but I was creating a separate class because I think it is a better
mapping to the driver model in Connman.

But yes, it is possible to treat VLANs normal ethernet-devices. The problem
is that the vlan interface will then show up with the same technology
(ethernet), the same MAC address, and the same group (cable), the
service name will therefor be identical.

I think both "ethernet" and "cable" is misleading since it should be
clear that it is a vlan-interface, and the interface is not necessary
cable-bound (could be bound to wifi, gadget and so on).

The patch is replacing the group-name with the IFNAME, which also is not
the preferred way, but that was the only way I saw to make it uniq.

I think there is a structural point in keeping the seperation, but it should not
get a too big impact on the usage, ofcause.

Does connman make use of the group-name at all?
One way may be to replace the group-name for the ethernet-class by the
IFNAME and also keep the vlan technology.
The result will be that if there is a ancient kernel, the ethernet
device will handle the vlan interface. In newer kernels the vlan-device
will take over.

It makes it possible to extend the interface to set vlan-specific
attributes such as VLAN ID and so on by connmanctl/dbus in the future.

If that is the way forward, I may look at it.
I'm currently in a project that needs the functionality (unfortunately
on an ancient kernel....), but I think it would be terrific if we came
up with a solution that also may be contributed to the Connman project.

Cheers
Marcus Folkesson
Justin Maggard
2015-04-01 19:35:21 UTC
Permalink
We have a VLAN implementation for Connman that associates the virtual
interfaces with the ethernet interface. It creates and deletes the
VLAN interfaces as needed based on the events from the underlying
ethernet service. If this is something of interest to the wider
Connman audience, maybe we can clean it up and get it merged. I'll
send it shortly.

-Justin

On Wed, Apr 1, 2015 at 2:12 AM, Marcus Folkesson
Post by Marcus Folkesson
Post by Jukka Rissanen
Hi Marcus,
Post by Marcus Folkesson
Support for multiple VLANs binded to the same interface.
vlan_<MAC to bounded IF>_<VLAN IFNAME>
vlan_5c260a4bf6a3_vlan3
diff --git a/src/rtnl.c b/src/rtnl.c
index b8b02c4..15827ab 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -170,6 +170,9 @@ static void read_uevent(struct interface_data *interface)
} else if (strcmp(line + 8, "gadget") == 0) {
interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
+ } else if (strcmp(line + 8, "vlan") == 0) {
+ interface->service_type = CONNMAN_SERVICE_TYPE_VLAN;
+ interface->device_type = CONNMAN_DEVICE_TYPE_VLAN;
} else {
Checked this with ancient 3.2 kernel and for vlan interface there is no
DEVTYPE defined. For newer 3.19 kernel, the DEVTYPE is set to vlan as
expected.
I just wonder would it be possible to treat vlan device as a normal
ethernet device without separation between vlan and ethernet types. This
would solve this issue with different kernel versions.
Cheers,
Jukka
Hi Jukka,
I have now checked with v3.0.35 and DEVTYPE is indeed not there (not even
for standard ethernet).
If I read the code right, (rtnl.c:read_uevent()), the only types
supported without DEVTYPE is just ethernet and wifi?
The first implementation was to let the ethernet device handle vlans,
but I was creating a separate class because I think it is a better
mapping to the driver model in Connman.
But yes, it is possible to treat VLANs normal ethernet-devices. The problem
is that the vlan interface will then show up with the same technology
(ethernet), the same MAC address, and the same group (cable), the
service name will therefor be identical.
I think both "ethernet" and "cable" is misleading since it should be
clear that it is a vlan-interface, and the interface is not necessary
cable-bound (could be bound to wifi, gadget and so on).
The patch is replacing the group-name with the IFNAME, which also is not
the preferred way, but that was the only way I saw to make it uniq.
I think there is a structural point in keeping the seperation, but it should not
get a too big impact on the usage, ofcause.
Does connman make use of the group-name at all?
One way may be to replace the group-name for the ethernet-class by the
IFNAME and also keep the vlan technology.
The result will be that if there is a ancient kernel, the ethernet
device will handle the vlan interface. In newer kernels the vlan-device
will take over.
It makes it possible to extend the interface to set vlan-specific
attributes such as VLAN ID and so on by connmanctl/dbus in the future.
If that is the way forward, I may look at it.
I'm currently in a project that needs the functionality (unfortunately
on an ancient kernel....), but I think it would be terrific if we came
up with a solution that also may be contributed to the Connman project.
Cheers
Marcus Folkesson
_______________________________________________
connman mailing list
https://lists.connman.net/mailman/listinfo/connman
Marcus Folkesson
2015-09-03 14:50:39 UTC
Permalink
dbus library calls abort() if it got a non-expected type passed to it.
---
src/agent-connman.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 3 deletions(-)
diff --git a/src/agent-connman.c b/src/agent-connman.c
index 2d714b5..381fd25 100644
--- a/src/agent-connman.c
+++ b/src/agent-connman.c
@@ -54,6 +54,34 @@ static bool check_reply_has_dict(DBusMessage *reply)
return false;
}
+static bool check_message_is_basic_type(DBusMessageIter *entry)
+{
+ int type = dbus_message_iter_get_arg_type(entry);
+ switch (type) {
+ return true;
+
+ return false;
+ }
+}
+
struct request_input_reply {
struct connman_service *service;
struct connman_peer *peer;
@@ -110,7 +138,14 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
if (dbus_message_iter_get_arg_type(&entry)
!= DBUS_TYPE_VARIANT)
break;
+
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &identity);
} else if (g_str_equal(key, "Passphrase")) {
@@ -118,7 +153,14 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
if (dbus_message_iter_get_arg_type(&entry)
!= DBUS_TYPE_VARIANT)
break;
+
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &passphrase);
} else if (g_str_equal(key, "WPS")) {
@@ -128,7 +170,14 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
if (dbus_message_iter_get_arg_type(&entry)
!= DBUS_TYPE_VARIANT)
break;
+
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &wpspin);
break;
} else if (g_str_equal(key, "Name")) {
@@ -136,7 +185,14 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
if (dbus_message_iter_get_arg_type(&entry)
!= DBUS_TYPE_VARIANT)
break;
+
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &name);
name_len = strlen(name);
} else if (g_str_equal(key, "SSID")) {
@@ -144,16 +200,25 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data)
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
- != DBUS_TYPE_VARIANT)
+ != DBUS_TYPE_VARIANT) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
break;
+ }
dbus_message_iter_recurse(&entry, &value);
if (dbus_message_iter_get_arg_type(&value)
- != DBUS_TYPE_ARRAY)
+ != DBUS_TYPE_ARRAY) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
break;
+ }
dbus_message_iter_recurse(&value, &array_iter);
if (dbus_message_iter_get_arg_type(&array_iter)
- != DBUS_TYPE_BYTE)
+ != DBUS_TYPE_BYTE) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
break;
+ }
dbus_message_iter_get_fixed_array(&array_iter, &name,
&name_len);
}
@@ -401,7 +466,14 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data)
if (dbus_message_iter_get_arg_type(&entry)
!= DBUS_TYPE_VARIANT)
break;
+
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &username);
} else if (g_str_equal(key, "Password")) {
@@ -410,6 +482,12 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data)
DBUS_TYPE_VARIANT)
break;
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ values_received = false;
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &password);
}
@@ -718,6 +796,11 @@ static void request_peer_authorization_reply(DBusMessage *reply,
!= DBUS_TYPE_VARIANT)
break;
dbus_message_iter_recurse(&entry, &value);
+ if (!check_message_is_basic_type(&value)) {
+ error = CONNMAN_ERROR_INTERFACE ".InvalidArguments";
+ break;
+ }
+
dbus_message_iter_get_basic(&value, &wpspin);
break;
}
--
1.9.1
Just saw a patch from jhannika posted on the channel:
jgke.fi/dump/typecheck.patch

It practically to the same thing.

Cheers,
Marcus Folkesson
Patrik Flykt
2015-09-04 07:03:27 UTC
Permalink
Post by Marcus Folkesson
jgke.fi/dump/typecheck.patch
It practically to the same thing.
Probably, but if it's not on this ml, it does not exist ;-). As a
coincidence, me and jhannika actually discussed this yesterday.

Cheers,

Patrik
Marcus Folkesson
2015-09-04 08:25:53 UTC
Permalink
Post by Patrik Flykt
Post by Marcus Folkesson
jgke.fi/dump/typecheck.patch
It practically to the same thing.
Probably, but if it's not on this ml, it does not exist ;-). As a
coincidence, me and jhannika actually discussed this yesterday.
Cheers,
Patrik
_______________________________________________
connman mailing list
https://lists.connman.net/mailman/listinfo/connman
Yeah, I wrote about the bug on the channel for two days ago.
Is it worth to go through all calls to dbus_message_iter_basic() and do type-checking?

Maybe wrap it into a function that we use everywhere so we have a generic way to do it
E.g.

bool get_basic_type(DBusMessageIter *iter, void *value, int expected_type)
{
int type = dbus_message_iter_get_arg_type(entry);
if (type != expected_type)
return false;
dbus_message_iter_basic(iter, value);
return true;
}

Cheers,
Marcus Folkesson

Loading...