[PATCH 1/2] tethering: Add wifi interface to bridge after carrier on
From: Martin Xu martin...@intel.com When changing wifi from STA to AP the interface needs to be closed and then opened. Only after the interface is opened and detected carrier, the interface can be added to bridge. --- plugins/wifi.c | 38 ++ 1 files changed, 34 insertions(+), 4 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 78da6ac..33ce0f9 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -66,6 +66,8 @@ struct wifi_data { connman_bool_t connected; connman_bool_t disconnecting; connman_bool_t tethering; + connman_bool_t propose_add_bridge; + char *bridge; int index; unsigned flags; unsigned int watch; @@ -112,6 +114,24 @@ static int get_bssid(struct connman_device *device, return 0; } +static void handle_tethering(struct wifi_data *wifi) +{ + if (wifi-tethering == FALSE) + return; + + if (wifi-bridge == NULL) + return; + + if (wifi-propose_add_bridge == FALSE) + return; + + DBG(index %d bridge %s, wifi-index, wifi-bridge); + + connman_inet_add_to_bridge(wifi-index, wifi-bridge); + + wifi-propose_add_bridge = FALSE; +} + static void wifi_newlink(unsigned flags, unsigned change, void *user_data) { struct connman_device *device = user_data; @@ -130,9 +150,11 @@ static void wifi_newlink(unsigned flags, unsigned change, void *user_data) } if ((wifi-flags IFF_LOWER_UP) != (flags IFF_LOWER_UP)) { - if (flags IFF_LOWER_UP) + if (flags IFF_LOWER_UP) { DBG(carrier on); - else + + handle_tethering(wifi); + } else DBG(carrier off); } @@ -152,6 +174,8 @@ static int wifi_probe(struct connman_device *device) wifi-connected = FALSE; wifi-disconnecting = FALSE; wifi-tethering = FALSE; + wifi-propose_add_bridge = FALSE; + wifi-bridge = NULL; wifi-state = G_SUPPLICANT_STATE_INACTIVE; connman_device_set_data(device, wifi); @@ -982,7 +1006,8 @@ static void sta_remove_callback(int result, info-wifi-interface = NULL; connman_technology_tethering_notify(info-technology, TRUE); - connman_inet_add_to_bridge(info-wifi-index, info-bridge); + + info-wifi-propose_add_bridge = TRUE; g_supplicant_interface_create(info-ifname, driver, info-bridge, ap_create_callback, @@ -1007,8 +1032,11 @@ static int tech_set_tethering(struct connman_technology *technology, for (list = iface_list; list; list = list-next) { wifi = list-data; - if (wifi-tethering == TRUE) + if (wifi-tethering == TRUE) { wifi-tethering = FALSE; + wifi-propose_add_bridge = FALSE; + g_free(wifi-bridge); + } } connman_technology_tethering_notify(technology, FALSE); @@ -1051,6 +1079,8 @@ static int tech_set_tethering(struct connman_technology *technology, } info-wifi-tethering = TRUE; + g_free(info-wifi-bridge); + info-wifi-bridge = g_strdup(bridge); err = g_supplicant_interface_remove(interface, sta_remove_callback, -- 1.6.1.3 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 2/2] tethering: Using /proc/sys/net/bridge to detect the support of bridge
From: Martin Xu martin...@intel.com If bridge is built in knerl, /sys/module/bridge can not be used to detect the support of bridge in kernel. --- src/tethering.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/tethering.c b/src/tethering.c index 705f5ee..15e1ed9 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -35,7 +35,7 @@ #include gdhcp/gdhcp.h -#define BRIDGE_SYSFS_DIR /sys/module/bridge +#define BRIDGE_SYSFS_DIR /proc/sys/net/bridge #define BRIDGE_NAME tether #define BRIDGE_IP 192.168.218.1 -- 1.6.1.3 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH 1/1]: Fix Memory-map and Double-free Errors in Statistics Handling (was Re: Connman-0.67 Crashes and/or Hangs on Start-up)
Good Morning Grant, On 02/17/2011 11:48 PM, Grant Erickson wrote: On 2/17/11 12:13 PM, Daniel Wagner wrote: On 02/17/2011 05:38 PM, Grant Erickson wrote: Thanks for taking the time to submit a comment for the code detailing the motivation for selecting MAP_PRIVATE. I have done some more research to determine why the MAP_SHARED fails on my platform. From what I can see, this is a limitation of JFFS2. For it's mmap method, it specifies: % grep 'mmap' linux/fs/jffs2/*.c linux/fs/jffs2/file.c:.mmap =generic_file_readonly_mmap, So, in short, for JFFS2 users in a top-of-tree kernel, connman statistics will never work with a PROT_WRITE + MAP_SHARED mapping. Thanks for tracking this down. In this case, it might make sense to add some fallback. My idea is to use MAP_PRIVATE and write the whole contents into a file after a certain period. The whole idea behind MAP_SHARED is to make sure the data really hits the disk. But until now, nobody with deep understanding of filesystem under Linux has done a review. So the current approach might be bogus. So if you are fine with having a fallback to MAP_PRIVATE + periodic write a file, then we should add this feature. Opinions? Were I writing this anew, I think I'd have skipped the mmap altogether, maintained the statistics in memory and flushed things out to a file at the appropriate times. If I understand you correctly, then allocating a memory block and use the current append write to this block can easily implemented withouth the use of mmap. Instead of allocating per mmap we just have to use malloc (or the glib wrapper for it g_try_new0()) for this. Working with what's there, I think I'd do away with MAP_SHARED, convert the mapping to MAP_PRIVATE and then call msync within the _stats_update path. This should be fairly simple to achieve. All that is said, however, without a savvy perspective on how statistic are used within connman. I have only second hand knowledge about the garantees we have to provide on the numbers. Marcel told me there exists a requirement for mobile phone manufacturers to grantee that the statistic numbers are like 95% accurate. How this number is computed or derived from is unclear. From this we thought we need to make sure that we really write data to the disk and also do not have too much disk IO. Currently, there is for each update at max two pages to flush to the disk. As I said nobody of us was really sure if this is what is going to work as expected. So if you have a better understanding what is really needed please be my guest ;) I'm glad to learn here something! cheers, daniel ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH 2/2] tethering: Using /proc/sys/net/bridge to detect the support of bridge
martin...@intel.com writes: From: Martin Xu martin...@intel.com If bridge is built in knerl, /sys/module/bridge can not be used to detect the support of bridge in kernel. --- src/tethering.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/tethering.c b/src/tethering.c index 705f5ee..15e1ed9 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -35,7 +35,7 @@ #include gdhcp/gdhcp.h -#define BRIDGE_SYSFS_DIR /sys/module/bridge +#define BRIDGE_SYSFS_DIR /proc/sys/net/bridge SYSFS_DIR is misleading now. -- Kalle Valo ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 6to4 v2 0/7] Create 6to4 tunnel automatically if enabled
Hi, the v2 patch checks if the tunnel has internet connectivity. Only change to v1 is the patch #7 which adds the connectivity check. The check is done by trying to connect to ipv6.google.com:80 via the tunnel. The google host was choosen as it only provides connectivity via IPv6. This could be changed to connman.net when it provides the same kind of service. The IPv6 address of the host is resolved by async DNS so that mainloop is not blocked. The timeouts I used were 10 sec for DNS query and 2 sec for connection test but these can be tweaked of course. Any comments or suggestions? Regards, Jukka Jukka Rissanen (7): doc: Add comment about 6to4 tunnelling. ipconfig: Add function to return the system address pointer. 6to4: Add 6to4 tunnel support. service: Create 6to4 tunnel if enabled. test: Add support for 6to4 tunnel status printing. test: Add support for enabling/disabling 6to4 tunnel. 6to4: Check the connectivity via tunnel after creating it. Makefile.am | 10 +- configure.ac|4 + doc/service-api.txt |9 + src/6to4.c | 789 +++ src/connman.h |6 + src/ipconfig.c |9 + src/ipv4.c |5 + src/service.c | 56 test/list-services |2 +- test/test-connman | 28 ++ 10 files changed, 912 insertions(+), 6 deletions(-) create mode 100644 src/6to4.c ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 6to4 v2 1/7] doc: Add comment about 6to4 tunnelling.
--- doc/service-api.txt |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/doc/service-api.txt b/doc/service-api.txt index 9695059..c662aaf 100644 --- a/doc/service-api.txt +++ b/doc/service-api.txt @@ -377,6 +377,15 @@ Properties string State [readonly] until the new configuration has been successfully installed. + boolean 6to4 [readwrite] + + If set to true, the service will create 6to4 + tunnel if the service IPv4 address is not private. + Default value is false meaning that 6to4 tunnel is + not created. Only one tunnel is created even if + there are more than one active service that have + public IPv4 address. + dict Proxy [readonly] string Method [readonly] -- 1.7.0.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH 6to4 v2 3/7] 6to4: Add 6to4 tunnel support.
--- Makefile.am |2 +- src/6to4.c| 569 + src/connman.h |3 + 3 files changed, 573 insertions(+), 1 deletions(-) create mode 100644 src/6to4.c diff --git a/Makefile.am b/Makefile.am index 144fcc5..8f13f56 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,7 +77,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \ src/wifi.c src/storage.c src/dbus.c src/config.c \ src/technology.c src/counter.c src/location.c \ src/session.c src/tethering.c src/wpad.c src/wispr.c \ - src/stats.c src/iptables.c src/dnsproxy.c + src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \ @CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl diff --git a/src/6to4.c b/src/6to4.c new file mode 100644 index 000..b07eeed --- /dev/null +++ b/src/6to4.c @@ -0,0 +1,569 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2011 Nokia Corporation. All rights reserved. + * + * 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 stdio.h +#include string.h +#include sys/socket.h +#include netinet/in.h +#include arpa/inet.h +#include net/if.h +#include linux/ip.h +#include linux/if_tunnel.h +#include linux/netlink.h +#include linux/rtnetlink.h +#include sys/ioctl.h +#include unistd.h + +#include connman.h +#include connman/log.h + +static int tunnel_created; + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((void *)(nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len))) + +#ifndef IP_DF +#define IP_DF 0x4000 /* Flag: Don't Fragment */ +#endif + +struct rtnl_handle { + int fd; + struct sockaddr_nl local; + struct sockaddr_nl peer; + __u32 seq; + __u32 dump; +}; + +/* Note that addattr32(), addattr_l(), rtnl_close(), rtnl_open() and + * rtnl_talk() are from libnetlink.c that is found in iproute2 package + * and copyright by Alexey Kuznetsov et al. + */ +static int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data) +{ + int len = RTA_LENGTH(4); + struct rtattr *rta; + if (NLMSG_ALIGN(n-nlmsg_len) + len (unsigned int)maxlen) { + DBG(Error! max allowed bound %d exceeded, maxlen); + return -1; + } + rta = NLMSG_TAIL(n); + rta-rta_type = type; + rta-rta_len = len; + memcpy(RTA_DATA(rta), data, 4); + n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + len; + + return 0; +} + +static int addattr_l(struct nlmsghdr *n, int maxlen, int type, + const void *data, int alen) +{ + int len = RTA_LENGTH(alen); + struct rtattr *rta; + + if (NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len) + (unsigned int)maxlen) { + DBG(addattr_l message exceeded bound of %d, maxlen); + return -1; + } + rta = NLMSG_TAIL(n); + rta-rta_type = type; + rta-rta_len = len; + memcpy(RTA_DATA(rta), data, alen); + n-nlmsg_len = NLMSG_ALIGN(n-nlmsg_len) + RTA_ALIGN(len); + + return 0; +} + +static void rtnl_close(struct rtnl_handle *rth) +{ + if (rth-fd = 0) { + close(rth-fd); + rth-fd = -1; + } +} + +static int rtnl_open(struct rtnl_handle *rth) +{ + socklen_t addr_len; + int sndbuf = 32768; + int rcvbuf = 32768; + + memset(rth, 0, sizeof(*rth)); + + rth-fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (rth-fd 0) { + DBG(Cannot open netlink socket: %s, strerror(errno)); + return -1; + } + + if (setsockopt(rth-fd, SOL_SOCKET, SO_SNDBUF, sndbuf, + sizeof(sndbuf)) 0) { + DBG(SO_SNDBUF: %s, strerror(errno)); + return -1; + } + + if (setsockopt(rth-fd, SOL_SOCKET, SO_RCVBUF, rcvbuf, + sizeof(rcvbuf)) 0) { + DBG(SO_RCVBUF: %s, strerror(errno)); + return -1; + } + + memset(rth-local, 0, sizeof(rth-local)); + rth-local.nl_family = AF_NETLINK;
[PATCH 6to4 v2 4/7] service: Create 6to4 tunnel if enabled.
--- src/connman.h |1 + src/ipv4.c|5 + src/service.c | 56 3 files changed, 62 insertions(+), 0 deletions(-) diff --git a/src/connman.h b/src/connman.h index a8ef170..0d90b6b 100644 --- a/src/connman.h +++ b/src/connman.h @@ -481,6 +481,7 @@ struct connman_ipconfig *__connman_service_get_ip4config( struct connman_service *service); struct connman_ipconfig *__connman_service_get_ip6config( struct connman_service *service); +connman_bool_t __connman_service_6to4_enabled(struct connman_service *service); const char *__connman_service_get_ident(struct connman_service *service); const char *__connman_service_get_path(struct connman_service *service); unsigned int __connman_service_get_order(struct connman_service *service); diff --git a/src/ipv4.c b/src/ipv4.c index e77b8ee..1ab0338 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -103,6 +103,9 @@ static int ipv4_probe(struct connman_element *element) if (err 0) return err; + if (__connman_service_6to4_enabled(service) == TRUE) + __connman_6to4_probe(address); + return 0; } @@ -152,6 +155,8 @@ static void ipv4_remove(struct connman_element *element) AF_INET, address, peer, prefixlen, broadcast) 0)) DBG(address removal failed); + __connman_6to4_remove(); + connman_element_unref(element); } diff --git a/src/service.c b/src/service.c index 9a0d499..7293354 100644 --- a/src/service.c +++ b/src/service.c @@ -103,6 +103,7 @@ struct connman_service { char **excludes; char *pac; connman_bool_t wps; + connman_bool_t enabled_6to4; }; static void append_path(gpointer value, gpointer user_data) @@ -1649,6 +1650,9 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, connman_dbus_dict_append_dict(dict, IPv6.Configuration, append_ipv6config, service); + connman_dbus_dict_append_basic(dict, 6to4, + DBUS_TYPE_BOOLEAN, service-enabled_6to4); + connman_dbus_dict_append_array(dict, Nameservers, DBUS_TYPE_STRING, append_dns, service); @@ -1851,6 +1855,21 @@ void __connman_service_set_passphrase(struct connman_service *service, __connman_storage_save_service(service); } +connman_bool_t __connman_service_6to4_enabled(struct connman_service *service) +{ + enum connman_ipconfig_method method; + + if (service == NULL) + return FALSE; + + method = __connman_ipconfig_get_method(service-ipconfig_ipv6); + if (method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || + method == CONNMAN_IPCONFIG_METHOD_OFF) + return FALSE; + + return service-enabled_6to4; +} + static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *user_data) { @@ -2281,6 +2300,31 @@ static DBusMessage *set_property(DBusConnection *conn, ipv4, ipv6); __connman_storage_save_service(service); + } else if (g_str_equal(name, 6to4) == TRUE) { + connman_bool_t six2four; + + if (type != DBUS_TYPE_BOOLEAN) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(value, six2four); + + if (service-enabled_6to4 == six2four) + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + + service-enabled_6to4 = six2four; + if (service-enabled_6to4 == TRUE) { + if (__connman_service_6to4_enabled(service) == TRUE) { + struct connman_ipaddress *address; + address = + __connman_ipconfig_get_system_address( + service-ipconfig_ipv4); + if (address) + __connman_6to4_probe(address-local); + } + } else + __connman_6to4_remove(); + + __connman_storage_save_service(service); } else return __connman_error_invalid_property(msg); @@ -4756,6 +4800,8 @@ static int service_load(struct connman_service *service) case CONNMAN_SERVICE_TYPE_UNKNOWN: case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_ETHERNET: + service-enabled_6to4 = g_key_file_get_boolean(keyfile, + service-identifier, 6to4, NULL); case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: case CONNMAN_SERVICE_TYPE_GADGET: @@ -4830,6
[PATCH 6to4 v2 5/7] test: Add support for 6to4 tunnel status printing.
--- test/list-services |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/test/list-services b/test/list-services index 3ae6a4d..20295b1 100755 --- a/test/list-services +++ b/test/list-services @@ -50,7 +50,7 @@ for path in properties[Services]: val = extract_list(properties[key]) elif key in [Favorite, Immutable, AutoConnect, LoginRequired, SetupRequired, - PassphraseRequired]: + PassphraseRequired, 6to4]: if properties[key] == dbus.Boolean(1): val = true else: -- 1.7.0.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH] Avoid More Double-Frees When Deallocating Statistics on a Failed Mapping
Hi Grant, In-Reply-To: 1297982431-9098-1-git-send-email-maratho...@gmail.com On Thu, Feb 17, 2011 at 02:40:31PM -0800, Grant Erickson wrote: Added debugging statements and ensure, following calls to g_free, that the statistics file name field is set to NULL to ensure that a failed file mapping and a subsequent call to stats_free doesn't fault when trying to double-free it. Added an informational message when mmap fails with EINVAL in stats_file_remap. Signed-off-by: Grant Erickson maratho...@gmail.com diff --git a/src/stats.c b/src/stats.c index 679a372..243a9b8 100644 --- a/src/stats.c +++ b/src/stats.c @@ -214,26 +214,27 @@ static void stats_free(gpointer user_data) { struct stats_file *file = user_data; - msync(file-addr, file-len, MS_SYNC); + if (file) { + msync(file-addr, file-len, MS_SYNC); Prefered style in ConnMan is to have an early exist, e.g. if (file == NULL) return; Would you mind to update your patch accordingly? thanks, daniel ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v2] ipconfig: Enable IPv6 properly when loading config and disable IPv6 properly when connecting service.
--- Hi, this sets the IPv6 status correctly by - enabling IPv6 when service config is loaded and method is AUTO or MANUAL - and disabling IPv6 when service is connected and method is OFF Regards, Jukka include/ipconfig.h |1 + src/ipconfig.c | 25 ++--- src/service.c |7 +++ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/ipconfig.h b/include/ipconfig.h index 9bc97d5..7d62330 100644 --- a/include/ipconfig.h +++ b/include/ipconfig.h @@ -95,6 +95,7 @@ int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig, enum connman_ipconfig_method method); void connman_ipconfig_bind(struct connman_ipconfig *ipconfig, struct connman_ipaddress *ipaddress); +void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig); #ifdef __cplusplus } diff --git a/src/ipconfig.c b/src/ipconfig.c index 62d3766..6511370 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -1379,6 +1379,14 @@ static void enable_ipv6(struct connman_ipconfig *ipconfig) set_ipv6_state(ipdevice-ifname, TRUE); } +void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig) +{ + if (ipconfig == NULL || ipconfig-type != CONNMAN_IPCONFIG_TYPE_IPV6) + return; + + disable_ipv6(ipconfig); +} + int __connman_ipconfig_enable(struct connman_ipconfig *ipconfig) { struct connman_ipdevice *ipdevice; @@ -1861,23 +1869,10 @@ int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, ipconfig-method = CONNMAN_IPCONFIG_METHOD_OFF; if (ipconfig-type == CONNMAN_IPCONFIG_TYPE_IPV6) { - if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_OFF) - disable_ipv6(ipconfig); - else if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO || + if (ipconfig-method == CONNMAN_IPCONFIG_METHOD_AUTO || ipconfig-method == CONNMAN_IPCONFIG_METHOD_MANUAL) { - enable_ipv6(ipconfig); __connman_ipconfig_enable(ipconfig); - - if (ipconfig-ops_data) { - struct connman_service *service = - ipconfig-ops_data; - struct connman_network *network; - network = __connman_service_get_network( - service); - if (network) - __connman_network_set_ipconfig(network, - NULL, ipconfig); - } + enable_ipv6(ipconfig); } } diff --git a/src/service.c b/src/service.c index 9a0d499..1696e5a 100644 --- a/src/service.c +++ b/src/service.c @@ -3319,6 +3319,7 @@ int __connman_service_indicate_state(struct connman_service *service, if (state == CONNMAN_SERVICE_STATE_READY) { enum connman_service_proxy_method proxy_config; + enum connman_ipconfig_method method; set_reconnect_state(service, TRUE); @@ -3371,6 +3372,12 @@ int __connman_service_indicate_state(struct connman_service *service, } default_changed(); + + method = __connman_ipconfig_get_method(service-ipconfig_ipv6); + if (method == CONNMAN_IPCONFIG_METHOD_OFF) + __connman_ipconfig_disable_ipv6( + service-ipconfig_ipv6); + } else if (state == CONNMAN_SERVICE_STATE_DISCONNECT) { __connman_location_finish(service); -- 1.7.0.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH] Avoid More Double-Frees When Deallocating Statistics on a Failed Mapping
Hi Grant, On Fri, Feb 18, 2011 at 09:54:52AM +0100, Daniel Wagner wrote: Hi Grant, In-Reply-To: 1297982431-9098-1-git-send-email-maratho...@gmail.com On Thu, Feb 17, 2011 at 02:40:31PM -0800, Grant Erickson wrote: Added debugging statements and ensure, following calls to g_free, that the statistics file name field is set to NULL to ensure that a failed file mapping and a subsequent call to stats_free doesn't fault when trying to double-free it. Added an informational message when mmap fails with EINVAL in stats_file_remap. Signed-off-by: Grant Erickson maratho...@gmail.com diff --git a/src/stats.c b/src/stats.c index 679a372..243a9b8 100644 --- a/src/stats.c +++ b/src/stats.c @@ -214,26 +214,27 @@ static void stats_free(gpointer user_data) { struct stats_file *file = user_data; - msync(file-addr, file-len, MS_SYNC); + if (file) { + msync(file-addr, file-len, MS_SYNC); Prefered style in ConnMan is to have an early exist, e.g. if (file == NULL) return; Would you mind to update your patch accordingly? While you're doing so, please remove the Signed-off-by line from your changelog. Cheers, Samuel. -- Intel Open Source Technology Centre http://oss.intel.com/ ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH ipv6routes v1 1/2] rtnl: Catch IPv6 route netlink messages.
--- src/rtnl.c | 122 +++ 1 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/rtnl.c b/src/rtnl.c index 5b09ca4..42b1632 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -633,7 +633,7 @@ static void process_deladdr(unsigned char family, unsigned char prefixlen, prefixlen, ip_string); } -static void extract_route(struct rtmsg *msg, int bytes, int *index, +static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index, struct in_addr *dst, struct in_addr *gateway) { @@ -658,30 +658,79 @@ static void extract_route(struct rtmsg *msg, int bytes, int *index, } } +static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index, + struct in6_addr *dst, + struct in6_addr *gateway) +{ + struct rtattr *attr; + + for (attr = RTM_RTA(msg); RTA_OK(attr, bytes); + attr = RTA_NEXT(attr, bytes)) { + switch (attr-rta_type) { + case RTA_DST: + if (dst != NULL) + *dst = *((struct in6_addr *) RTA_DATA(attr)); + break; + case RTA_GATEWAY: + if (gateway != NULL) + *gateway = + *((struct in6_addr *) RTA_DATA(attr)); + break; + case RTA_OIF: + if (index != NULL) + *index = *((int *) RTA_DATA(attr)); + break; + } + } +} + static void process_newroute(unsigned char family, unsigned char scope, struct rtmsg *msg, int bytes) { GSList *list; - struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY }; - char dststr[16], gatewaystr[16]; + char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN]; int index = -1; - if (family != AF_INET) - return; + if (family == AF_INET) { + struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY }; - extract_route(msg, bytes, index, dst, gateway); + extract_ipv4_route(msg, bytes, index, dst, gateway); - inet_ntop(family, dst, dststr, sizeof(dststr)); - inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr)); + inet_ntop(family, dst, dststr, sizeof(dststr)); + inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr)); - __connman_ipconfig_newroute(index, family, scope, dststr, gatewaystr); + __connman_ipconfig_newroute(index, family, scope, dststr, + gatewaystr); - /* skip host specific routes */ - if (scope != RT_SCOPE_UNIVERSE + /* skip host specific routes */ + if (scope != RT_SCOPE_UNIVERSE !(scope == RT_SCOPE_LINK dst.s_addr == INADDR_ANY)) - return; + return; - if (dst.s_addr != INADDR_ANY) + if (dst.s_addr != INADDR_ANY) + return; + + } else if (family == AF_INET6) { + struct in6_addr dst = IN6ADDR_ANY_INIT, + gateway = IN6ADDR_ANY_INIT; + + extract_ipv6_route(msg, bytes, index, dst, gateway); + + inet_ntop(family, dst, dststr, sizeof(dststr)); + inet_ntop(family, gateway, gatewaystr, sizeof(gatewaystr)); + + __connman_ipconfig_newroute(index, family, scope, dststr, + gatewaystr); + + /* skip host specific routes */ + if (scope != RT_SCOPE_UNIVERSE + !(scope == RT_SCOPE_LINK + IN6_IS_ADDR_UNSPECIFIED(dst))) + return; + + if (!IN6_IS_ADDR_UNSPECIFIED(dst)) + return; + } else return; for (list = rtnl_list; list; list = list-next) { @@ -696,26 +745,49 @@ static void process_delroute(unsigned char family, unsigned char scope, struct rtmsg *msg, int bytes) { GSList *list; - struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY }; - char dststr[16], gatewaystr[16]; + char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN]; int index = -1; - if (family != AF_INET) - return; + if (family == AF_INET) { + struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY }; - extract_route(msg, bytes,
[PATCH ipv6routes v1 0/2] Catch IPv6 default gw messages
Hi, here is some preliminary work for IPv6 route handling. The patch catches IPv6 route additions and deletions and updates ipconfig accordingly. Regards, Jukka Jukka Rissanen (2): rtnl: Catch IPv6 route netlink messages. ipconfig: Catch IPv6 default route creation and deletion. src/ipconfig.c | 16 +--- src/rtnl.c | 122 --- 2 files changed, 107 insertions(+), 31 deletions(-) ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH ipv6routes v1 2/2] ipconfig: Catch IPv6 default route creation and deletion.
--- src/ipconfig.c | 16 ++-- 1 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ipconfig.c b/src/ipconfig.c index 62d3766..59dd987 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -720,7 +720,8 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope, if (ipdevice == NULL) return; - if (scope == 0 g_strcmp0(dst, 0.0.0.0) == 0) { + if (scope == 0 (g_strcmp0(dst, 0.0.0.0) == 0 || + g_strcmp0(dst, ::) == 0)) { GSList *list; GList *config_list; @@ -734,7 +735,7 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope, ipdevice-config_ipv6-system-gateway = g_strdup(gateway); } - } else { + } else if (family == AF_INET) { g_free(ipdevice-ipv4_gateway); ipdevice-ipv4_gateway = g_strdup(gateway); @@ -744,7 +745,8 @@ void __connman_ipconfig_newroute(int index, int family, unsigned char scope, ipdevice-config_ipv4-system-gateway = g_strdup(gateway); } - } + } else + return; for (list = ipdevice-address_list; list; list = list-next) { struct connman_ipaddress *ipaddress = list-data; @@ -784,7 +786,8 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope, if (ipdevice == NULL) return; - if (scope == 0 g_strcmp0(dst, 0.0.0.0) == 0) { + if (scope == 0 (g_strcmp0(dst, 0.0.0.0) == 0 || + g_strcmp0(dst, ::) == 0)) { GSList *list; GList *config_list; @@ -797,7 +800,7 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope, g_free(ipdevice-config_ipv6-system-gateway); ipdevice-config_ipv6-system-gateway = NULL; } - } else { + } else if (family == AF_INET) { g_free(ipdevice-ipv4_gateway); ipdevice-ipv4_gateway = NULL; @@ -806,7 +809,8 @@ void __connman_ipconfig_delroute(int index, int family, unsigned char scope, g_free(ipdevice-config_ipv4-system-gateway); ipdevice-config_ipv4-system-gateway = NULL; } - } + } else + return; for (list = ipdevice-address_list; list; list = list-next) { struct connman_ipaddress *ipaddress = list-data; -- 1.7.0.4 ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH 2/2] tethering: Using /proc/sys/net/bridge to detect the support of bridge
Hi Martin, On Fri, Feb 18, 2011 at 03:57:22PM +0800, martin...@intel.com wrote: From: Martin Xu martin...@intel.com If bridge is built in knerl, /sys/module/bridge can not be used to detect the support of bridge in kernel. Good catch. However, as Kalle pointed out: -#define BRIDGE_SYSFS_DIR /sys/module/bridge +#define BRIDGE_SYSFS_DIR /proc/sys/net/bridge Please rename that to BRIDGE_PROC_DIR Cheers, Samuel. -- Intel Open Source Technology Centre http://oss.intel.com/ ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH 2/2] tethering: Using /proc/sys/net/bridge to detect the support of bridge
Hi Martin, If bridge is built in knerl, /sys/module/bridge can not be used to detect the support of bridge in kernel. --- src/tethering.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/tethering.c b/src/tethering.c index 705f5ee..15e1ed9 100644 --- a/src/tethering.c +++ b/src/tethering.c @@ -35,7 +35,7 @@ #include gdhcp/gdhcp.h -#define BRIDGE_SYSFS_DIR /sys/module/bridge +#define BRIDGE_SYSFS_DIR /proc/sys/net/bridge are you sure this is correct? Even builtin kernel modules should show up under /sys/module. Regards Marcel ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
Re: [PATCH privacy v2 1/3] doc: Add description about IPv6 privacy setting.
Hi Jukka, On Thu, Feb 17, 2011 at 03:50:04PM +0200, Jukka Rissanen wrote: --- doc/service-api.txt | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/doc/service-api.txt b/doc/service-api.txt index b3e758e..55c5b6e 100644 --- a/doc/service-api.txt +++ b/doc/service-api.txt @@ -375,6 +375,24 @@ Properties string State [readonly] The current configured IPv6 gateway. + int32 Privacy [readonly] An int16 would have been just fine. + Enable or disable IPv6 privacy extension + that is described in RFC 4941. The value + has only meaning if Method is set to auto. + + Value = 0 means that privacy extension is + disabled and normal autoconf addresses are + used. + Value 1 means that privacy extension is + enabled and system prefers to use public + addresses over temporary addresses. + Value = 2 means that privacy extension is + enabled and system prefers temporary addresses + over public addresses. + + Default value is 1. Now that this is user configurable, the default value should just be 0. Cheers, Samuel. -- Intel Open Source Technology Centre http://oss.intel.com/ ___ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman
[PATCH v1 2/6] Redo EnableTechnology API logic.
From: Alok Barsode alok.bars...@nokia.com EnableTechnology used to traverse the whole element tree enabling devices. Instead traverse technology-device_list and enable each device. --- src/connman.h|3 ++- src/element.c| 53 - src/manager.c|2 +- src/technology.c | 26 ++ 4 files changed, 29 insertions(+), 55 deletions(-) diff --git a/src/connman.h b/src/connman.h index f6521eb..5d3d74e 100644 --- a/src/connman.h +++ b/src/connman.h @@ -180,7 +180,6 @@ struct connman_device *__connman_element_get_device(struct connman_element *elem struct connman_device *__connman_element_find_device(enum connman_service_type type); int __connman_element_request_scan(enum connman_service_type type); -int __connman_element_enable_technology(enum connman_service_type type); int __connman_element_disable_technology(enum connman_service_type type); gboolean __connman_element_device_isfiltered(const char *devname); @@ -316,6 +315,8 @@ void __connman_technology_list(DBusMessageIter *iter, void *user_data); int __connman_technology_add_device(struct connman_device *device); int __connman_technology_remove_device(struct connman_device *device); int __connman_technology_enable(enum connman_service_type type); +int technology_enable(enum connman_service_type type); + int __connman_technology_disable(enum connman_service_type type); int __connman_technology_add_rfkill(unsigned int index, enum connman_service_type type, diff --git a/src/element.c b/src/element.c index ac62aaa..2584fbc 100644 --- a/src/element.c +++ b/src/element.c @@ -317,59 +317,6 @@ int __connman_element_request_scan(enum connman_service_type type) return 0; } -static gboolean enable_technology(GNode *node, gpointer user_data) -{ - struct connman_element *element = node-data; - struct find_data *data = user_data; - enum connman_service_type type; - int err; - - if (element-type != CONNMAN_ELEMENT_TYPE_DEVICE) - return FALSE; - - if (element-device == NULL) - return FALSE; - - type = __connman_device_get_service_type(element-device); - - switch (type) { - case CONNMAN_SERVICE_TYPE_UNKNOWN: - case CONNMAN_SERVICE_TYPE_SYSTEM: - case CONNMAN_SERVICE_TYPE_GPS: - case CONNMAN_SERVICE_TYPE_VPN: - case CONNMAN_SERVICE_TYPE_GADGET: - return FALSE; - case CONNMAN_SERVICE_TYPE_ETHERNET: - case CONNMAN_SERVICE_TYPE_WIFI: - case CONNMAN_SERVICE_TYPE_WIMAX: - case CONNMAN_SERVICE_TYPE_BLUETOOTH: - case CONNMAN_SERVICE_TYPE_CELLULAR: - if (data-type != CONNMAN_SERVICE_TYPE_UNKNOWN - data-type != type) - return FALSE; - break; - } - - err = __connman_device_enable(element-device); - if (err == 0 || (err 0 err == -EINPROGRESS)) - data-error = FALSE; - - return FALSE; -} - -int __connman_element_enable_technology(enum connman_service_type type) -{ - struct find_data data = { .type = type, .device = NULL, .error = TRUE }; - - g_node_traverse(element_root, G_PRE_ORDER, - G_TRAVERSE_ALL, -1, enable_technology, data); - - if (data.error == TRUE) - return -ENODEV; - - return 0; -} - static gboolean disable_technology(GNode *node, gpointer user_data) { struct connman_element *element = node-data; diff --git a/src/manager.c b/src/manager.c index 0a11f5d..2c7d632 100644 --- a/src/manager.c +++ b/src/manager.c @@ -329,7 +329,7 @@ static DBusMessage *enable_technology(DBusConnection *conn, technology_enabled = TRUE; technology_pending = dbus_message_ref(msg); - err = __connman_element_enable_technology(type); + err = technology_enable(type); if (err 0 err != -EINPROGRESS) technology_reply(-err); else diff --git a/src/technology.c b/src/technology.c index 513fffc..077a35c 100644 --- a/src/technology.c +++ b/src/technology.c @@ -674,6 +674,32 @@ int __connman_technology_remove_device(struct connman_device *device) return 0; } +int technology_enable(enum connman_service_type type) +{ + GSList *list; + struct connman_technology *technology; + + technology = technology_find(type); + if (technology == NULL) + return -ENXIO; + + if (technology-device_list == NULL) + return -ENODEV; + + for (list = technology-device_list; list; list = list-next) { + struct connman_device *device = list-data; + + /* Tracking error from every device is not possible. + hence ignore the return value */ + __connman_device_enable(device); + } + + /* This will trigger a 15 sec timeout.
[PATCH v1 1/6] Remove __connman_device_[enable/disable]_persistent.
From: Alok Barsode alok.bars...@nokia.com Use __connman_device_[enable/disable] to store the peristent states of device instead. connman_device_set_powered is the asyc func called by the plugin on successfully changing the power state. We also change technology state after successfully changing the power state. --- include/device.h |2 +- src/device.c | 113 +- src/element.c|4 +- src/technology.c |4 +- 4 files changed, 32 insertions(+), 91 deletions(-) diff --git a/include/device.h b/include/device.h index 5cb34d7..7a1d3c8 100644 --- a/include/device.h +++ b/include/device.h @@ -68,7 +68,7 @@ void connman_device_set_ident(struct connman_device *device, const char *ident); const char *connman_device_get_ident(struct connman_device *device); -int connman_device_set_powered(struct connman_device *device, +void connman_device_set_powered(struct connman_device *device, connman_bool_t powered); int connman_device_set_scanning(struct connman_device *device, connman_bool_t scanning); diff --git a/src/device.c b/src/device.c index 07c427d..5ff39ce 100644 --- a/src/device.c +++ b/src/device.c @@ -188,7 +188,6 @@ enum connman_service_type __connman_device_get_service_type(struct connman_devic int __connman_device_enable(struct connman_device *device) { int err; - enum connman_service_type type; DBG(device %p %d, device, device-blocked); @@ -201,28 +200,17 @@ int __connman_device_enable(struct connman_device *device) if (device-blocked == TRUE) return -ENOLINK; + device-powered_persistent = TRUE; + __connman_storage_save_device(device); + connman_device_set_disconnected(device, FALSE); device-scanning = FALSE; - err = device-driver-enable(device); - if (err 0 err != -EALREADY) { - if (err == -EINPROGRESS) { - device-powered_pending = TRUE; - device-offlinemode = FALSE; - if (__connman_profile_get_offlinemode() == TRUE) - __connman_profile_set_offlinemode(FALSE, FALSE); - } - return err; - } - device-powered_pending = TRUE; - device-powered = TRUE; - device-offlinemode = FALSE; - if (__connman_profile_get_offlinemode() == TRUE) - __connman_profile_set_offlinemode(FALSE, FALSE); - type = __connman_device_get_service_type(device); - __connman_technology_enable(type); + err = device-driver-enable(device); + if (err 0 err != -EINPROGRESS) + return err; return 0; } @@ -230,7 +218,6 @@ int __connman_device_enable(struct connman_device *device) int __connman_device_disable(struct connman_device *device) { int err; - enum connman_service_type type; DBG(device %p, device); @@ -249,20 +236,14 @@ int __connman_device_disable(struct connman_device *device) g_hash_table_remove_all(device-networks); - err = device-driver-disable(device); - if (err 0 err != -EALREADY) { - if (err == -EINPROGRESS) - device-powered_pending = FALSE; - return err; - } - - device-connections = 0; + device-powered_persistent = FALSE; + __connman_storage_save_device(device); device-powered_pending = FALSE; - device-powered = FALSE; - type = __connman_device_get_service_type(device); - __connman_technology_disable(type); + err = device-driver-disable(device); + if (err 0 err != -EINPROGRESS) + return err; return 0; } @@ -283,8 +264,7 @@ static int setup_device(struct connman_device *device) __connman_technology_add_device(device); - if (device-offlinemode == FALSE - device-powered_persistent == TRUE) + if (device-powered_persistent == TRUE) __connman_device_enable(device); return 0; @@ -636,49 +616,44 @@ const char *connman_device_get_ident(struct connman_device *device) * * Change power state of device */ -int connman_device_set_powered(struct connman_device *device, +void connman_device_set_powered(struct connman_device *device, connman_bool_t powered) { - int err; enum connman_service_type type; + connman_bool_t offlinemode = __connman_profile_get_offlinemode(); DBG(driver %p powered %d, device, powered); - if (device-powered == powered) { - device-powered_pending = powered; - return -EALREADY; - } + /* This is to safeguard against power toggles. + We always process only the last request */
[PATCH v1 4/6] Redo offlinemode logic.
From: Alok Barsode alok.bars...@nokia.com set/unset offlinemode used to traverse the whole element tree. Instead traverse technology_list and enable/disable all technologies. Also removed device-offlinemode. The property reflected current profile's offlinemode states which can be checked with __connman_profile_get_offlinemode. --- src/connman.h|4 ++-- src/device.c | 53 - src/manager.c|4 +--- src/profile.c|8 +++- src/technology.c | 43 +-- 5 files changed, 35 insertions(+), 77 deletions(-) diff --git a/src/connman.h b/src/connman.h index e4400cd..7006203 100644 --- a/src/connman.h +++ b/src/connman.h @@ -375,7 +375,7 @@ connman_bool_t __connman_device_get_reconnect(struct connman_device *device); const char *__connman_device_get_type(struct connman_device *device); -int __connman_device_set_offlinemode(connman_bool_t offlinemode); +int technology_set_offlinemode(connman_bool_t offlinemode); #include connman/network.h @@ -412,7 +412,7 @@ int __connman_profile_init(); void __connman_profile_cleanup(void); connman_bool_t __connman_profile_get_offlinemode(void); -int __connman_profile_set_offlinemode(connman_bool_t offlinemode, connman_bool_t all_devices); +int __connman_profile_set_offlinemode(connman_bool_t offlinemode); int __connman_profile_save_default(void); void __connman_profile_list(DBusMessageIter *iter, void *user_data); diff --git a/src/device.c b/src/device.c index 5ff39ce..e1ceec7 100644 --- a/src/device.c +++ b/src/device.c @@ -31,7 +31,6 @@ struct connman_device { struct connman_element element; enum connman_device_type type; - connman_bool_t offlinemode; connman_bool_t blocked; connman_bool_t powered; connman_bool_t powered_pending; @@ -620,7 +619,6 @@ void connman_device_set_powered(struct connman_device *device, connman_bool_t powered) { enum connman_service_type type; - connman_bool_t offlinemode = __connman_profile_get_offlinemode(); DBG(driver %p powered %d, device, powered); @@ -631,13 +629,6 @@ void connman_device_set_powered(struct connman_device *device, device-powered = powered; - if (offlinemode powered) { - __connman_profile_set_offlinemode(FALSE, FALSE); - __connman_profile_save_default(); - - device-offlinemode = FALSE; - } - type = __connman_device_get_service_type(device); if (powered) @@ -665,9 +656,6 @@ int __connman_device_set_blocked(struct connman_device *device, device-blocked = blocked; - if (device-offlinemode == TRUE) - return 0; - connman_info(%s {rfkill} blocked %d, device-interface, blocked); if (blocked == FALSE) @@ -909,45 +897,6 @@ const char *connman_device_get_string(struct connman_device *device, return connman_element_get_string(device-element, key); } -static void set_offlinemode(struct connman_element *element, gpointer user_data) -{ - struct connman_device *device = element-device; - connman_bool_t offlinemode = GPOINTER_TO_UINT(user_data); - connman_bool_t powered; - - DBG(element %p name %s, element, element-name); - - if (device == NULL) - return; - - device-offlinemode = offlinemode; - - if (device-blocked == TRUE) - return; - - powered = (offlinemode == TRUE) ? FALSE : TRUE; - - if (device-powered == powered) - return; - - if (device-powered_persistent == FALSE) - powered = FALSE; - - set_powered(device, powered); -} - -int __connman_device_set_offlinemode(connman_bool_t offlinemode) -{ - DBG(offlinmode %d, offlinemode); - - __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, - set_offlinemode, GUINT_TO_POINTER(offlinemode)); - - __connman_notifier_offlinemode(offlinemode); - - return 0; -} - void __connman_device_increase_connections(struct connman_device *device) { if (device == NULL) @@ -1085,8 +1034,6 @@ int connman_device_register(struct connman_device *device) { __connman_storage_load_device(device); - device-offlinemode = __connman_profile_get_offlinemode(); - return connman_element_register(device-element, NULL); } diff --git a/src/manager.c b/src/manager.c index 7eff3d5..ccd55de 100644 --- a/src/manager.c +++ b/src/manager.c @@ -113,9 +113,7 @@ static DBusMessage *set_property(DBusConnection *conn, dbus_message_iter_get_basic(value, offlinemode); - __connman_profile_set_offlinemode(offlinemode, TRUE); - - __connman_profile_save_default(); + technology_set_offlinemode(offlinemode); } else if (g_str_equal(name, ActiveProfile) == TRUE) {