From 602fb0a7a17973dbf2d2c1fc010a94d6185532ec Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Wed, 26 Jun 2013 11:35:17 +0200 Subject: [PATCH] connman: add upstream patches to fix connman/tethering routing problem Signed-off-by: Stephan Raue --- ...bug_print_so_we_know_when_restarting.patch | 29 ++++ ...m_ippool_instead_of_hard_coded_value.patch | 77 +++++++++ ...ink_functions_to_set_default_gateway.patch | 57 +++++++ ...ove_unused_gateway_setting_functions.patch | 156 ++++++++++++++++++ ...hering_when_connman_is_shutting_down.patch | 36 ++++ 5 files changed, 355 insertions(+) create mode 100644 packages/network/connman/patches/connman-990.01.01-tethering-Add_debug_print_so_we_know_when_restarting.patch create mode 100644 packages/network/connman/patches/connman-990.01.02-tethering-Use_the_prefix_lenght_from_ippool_instead_of_hard_coded_value.patch create mode 100644 packages/network/connman/patches/connman-990.01.03-connection-Use_netlink_functions_to_set_default_gateway.patch create mode 100644 packages/network/connman/patches/connman-990.01.04-inet-Remove_unused_gateway_setting_functions.patch create mode 100644 packages/network/connman/patches/connman-990.02.01-tethering-Cleanup_tethering_when_connman_is_shutting_down.patch diff --git a/packages/network/connman/patches/connman-990.01.01-tethering-Add_debug_print_so_we_know_when_restarting.patch b/packages/network/connman/patches/connman-990.01.01-tethering-Add_debug_print_so_we_know_when_restarting.patch new file mode 100644 index 0000000000..b15cf64e1d --- /dev/null +++ b/packages/network/connman/patches/connman-990.01.01-tethering-Add_debug_print_so_we_know_when_restarting.patch @@ -0,0 +1,29 @@ + +Betreff: +[PATCH 1/5] tethering: Add debug print so we know when restarting +Von: +Jukka Rissanen +Datum: +25.06.2013 14:58 +An: +connman@connman.net + +--- + src/tethering.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/tethering.c b/src/tethering.c +index 223873b..eb05056 100644 +--- a/src/tethering.c ++++ b/src/tethering.c +@@ -176,6 +176,7 @@ static void dhcp_server_stop(GDHCPServer *server) + + static void tethering_restart(struct connman_ippool *pool, void *user_data) + { ++ DBG("pool %p", pool); + __connman_tethering_set_disabled(); + __connman_tethering_set_enabled(); + } +-- +1.7.11.7 + diff --git a/packages/network/connman/patches/connman-990.01.02-tethering-Use_the_prefix_lenght_from_ippool_instead_of_hard_coded_value.patch b/packages/network/connman/patches/connman-990.01.02-tethering-Use_the_prefix_lenght_from_ippool_instead_of_hard_coded_value.patch new file mode 100644 index 0000000000..692fe47514 --- /dev/null +++ b/packages/network/connman/patches/connman-990.01.02-tethering-Use_the_prefix_lenght_from_ippool_instead_of_hard_coded_value.patch @@ -0,0 +1,77 @@ + +Betreff: +[PATCH 2/5] tethering: Use the prefix lenght from ippool instead of hard coded value +Von: +Jukka Rissanen +Datum: +25.06.2013 14:58 +An: +connman@connman.net + +We were always using prefix length 24 instead of the correct +value from ippool. +--- + src/bridge.c | 8 ++++---- + src/connman.h | 4 ++-- + src/tethering.c | 4 +++- + 3 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/bridge.c b/src/bridge.c +index e46cdda..1610f96 100644 +--- a/src/bridge.c ++++ b/src/bridge.c +@@ -111,8 +111,8 @@ int __connman_bridge_remove(const char *name) + return 0; + } + +-int __connman_bridge_enable(const char *name, const char *gateway, +- const char *broadcast) ++int __connman_bridge_enable(const char *name, const char *ip_address, ++ int prefix_len, const char *broadcast) + { + int err, index; + +@@ -121,8 +121,8 @@ int __connman_bridge_enable(const char *name, const char *gateway, + return index; + + err = __connman_inet_modify_address(RTM_NEWADDR, +- NLM_F_REPLACE | NLM_F_ACK, index, AF_INET, +- gateway, NULL, 24, broadcast); ++ NLM_F_REPLACE | NLM_F_ACK, index, AF_INET, ++ ip_address, NULL, prefix_len, broadcast); + if (err < 0) + return err; + +diff --git a/src/connman.h b/src/connman.h +index 11dbc35..96f8466 100644 +--- a/src/connman.h ++++ b/src/connman.h +@@ -899,8 +899,8 @@ void __connman_ippool_deladdr(int index, const char *address, + + int __connman_bridge_create(const char *name); + int __connman_bridge_remove(const char *name); +-int __connman_bridge_enable(const char *name, const char *gateway, +- const char *broadcast); ++int __connman_bridge_enable(const char *name, const char *ip_address, ++ int prefix_len, const char *broadcast); + int __connman_bridge_disable(const char *name); + + int __connman_nat_init(void); +diff --git a/src/tethering.c b/src/tethering.c +index eb05056..0b373b9 100644 +--- a/src/tethering.c ++++ b/src/tethering.c +@@ -221,7 +221,9 @@ void __connman_tethering_set_enabled(void) + start_ip = __connman_ippool_get_start_ip(dhcp_ippool); + end_ip = __connman_ippool_get_end_ip(dhcp_ippool); + +- err = __connman_bridge_enable(BRIDGE_NAME, gateway, broadcast); ++ err = __connman_bridge_enable(BRIDGE_NAME, gateway, ++ __connman_ipaddress_netmask_prefix_len(subnet_mask), ++ broadcast); + if (err < 0 && err != -EALREADY) { + __connman_ippool_unref(dhcp_ippool); + __connman_bridge_remove(BRIDGE_NAME); +-- +1.7.11.7 + diff --git a/packages/network/connman/patches/connman-990.01.03-connection-Use_netlink_functions_to_set_default_gateway.patch b/packages/network/connman/patches/connman-990.01.03-connection-Use_netlink_functions_to_set_default_gateway.patch new file mode 100644 index 0000000000..dbd1ed1834 --- /dev/null +++ b/packages/network/connman/patches/connman-990.01.03-connection-Use_netlink_functions_to_set_default_gateway.patch @@ -0,0 +1,57 @@ + +Betreff: +[PATCH 3/5] connection: Use netlink functions to set default gateway +Von: +Jukka Rissanen +Datum: +25.06.2013 14:58 +An: +connman@connman.net + +We were using earlier the ioctl() to set the default gateway. +In some cases that could fail because the desired interface +was not set when calling the ioctl(). +This happened with tethering with following scenario: +* Ethernet cable (uplink connection) is not connected +* Wifi tethering is started with address 192.168.1.1 +* Ethernet cable is connected, uplink address is 192.168.1.0/24 +* There is now a conflict, ippool resolves that in __connman_ippool_newaddr() + and calls tethering_restart() which stops and then starts tethering +* Because of the problems when calling the SIOCADDRT (we do not know + to what interface the default route was added to), the default route + of uplink connection was added to tethering interface (tether) instead + of uplink interface (eth0). This caused the default route to disappear + when tether interface was taken down. +* Solution was to use the netlink interface to set the default gateway + as we can unambiguously set the desired default route to be via the + uplink interface + +Thanks for Stephan Raue for reporting this issue. +--- + src/connection.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/connection.c b/src/connection.c +index c7b1f62..c0fdaf8 100644 +--- a/src/connection.c ++++ b/src/connection.c +@@ -479,12 +479,12 @@ static void set_default_gateway(struct gateway_data *data, + } + + if (do_ipv6 == TRUE && data->ipv6_gateway != NULL) +- status6 = connman_inet_set_ipv6_gateway_address(index, +- data->ipv6_gateway->gateway); ++ status6 = __connman_inet_add_default_to_table(RT_TABLE_MAIN, ++ index, data->ipv6_gateway->gateway); + + if (do_ipv4 == TRUE && data->ipv4_gateway != NULL) +- status4 = connman_inet_set_gateway_address(index, +- data->ipv4_gateway->gateway); ++ status4 = __connman_inet_add_default_to_table(RT_TABLE_MAIN, ++ index, data->ipv4_gateway->gateway); + + if (status4 < 0 || status6 < 0) + return; +-- +1.7.11.7 + diff --git a/packages/network/connman/patches/connman-990.01.04-inet-Remove_unused_gateway_setting_functions.patch b/packages/network/connman/patches/connman-990.01.04-inet-Remove_unused_gateway_setting_functions.patch new file mode 100644 index 0000000000..1a04aada5e --- /dev/null +++ b/packages/network/connman/patches/connman-990.01.04-inet-Remove_unused_gateway_setting_functions.patch @@ -0,0 +1,156 @@ + +Betreff: +[PATCH 4/5] inet: Remove unused gateway setting functions +Von: +Jukka Rissanen +Datum: +25.06.2013 14:58 +An: +connman@connman.net + +No need for these functions any more as we are using the netlink +variants to set the default gateway. +--- + include/inet.h | 2 -- + src/inet.c | 98 ---------------------------------------------------------- + 2 files changed, 100 deletions(-) + +diff --git a/include/inet.h b/include/inet.h +index 8f7a35c..10d9dae 100644 +--- a/include/inet.h ++++ b/include/inet.h +@@ -50,7 +50,6 @@ int connman_inet_del_host_route(int index, const char *host); + int connman_inet_add_network_route(int index, const char *host, const char *gateway, + const char *netmask); + int connman_inet_del_network_route(int index, const char *host); +-int connman_inet_set_gateway_address(int index, const char *gateway); + int connman_inet_clear_gateway_address(int index, const char *gateway); + int connman_inet_set_gateway_interface(int index); + int connman_inet_clear_gateway_interface(int index); +@@ -66,7 +65,6 @@ int connman_inet_add_ipv6_host_route(int index, const char *host, + int connman_inet_del_ipv6_network_route(int index, const char *host, + unsigned char prefix_len); + int connman_inet_del_ipv6_host_route(int index, const char *host); +-int connman_inet_set_ipv6_gateway_address(int index, const char *gateway); + int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway); + int connman_inet_set_ipv6_gateway_interface(int index); + int connman_inet_clear_ipv6_gateway_interface(int index); +diff --git a/src/inet.c b/src/inet.c +index ed98dd5..840f9b1 100644 +--- a/src/inet.c ++++ b/src/inet.c +@@ -727,47 +727,6 @@ int connman_inet_add_ipv6_host_route(int index, const char *host, + return connman_inet_add_ipv6_network_route(index, host, gateway, 128); + } + +-int connman_inet_set_ipv6_gateway_address(int index, const char *gateway) +-{ +- struct in6_rtmsg rt; +- int sk, err = 0; +- +- DBG("index %d gateway %s", index, gateway); +- +- if (gateway == NULL) +- return -EINVAL; +- +- memset(&rt, 0, sizeof(rt)); +- +- if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { +- err = -errno; +- goto out; +- } +- +- rt.rtmsg_flags = RTF_UP | RTF_GATEWAY; +- rt.rtmsg_metric = 1; +- rt.rtmsg_dst_len = 0; +- rt.rtmsg_ifindex = index; +- +- sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); +- if (sk < 0) { +- err = -errno; +- goto out; +- } +- +- if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST) +- err = -errno; +- +- close(sk); +- +-out: +- if (err < 0) +- connman_error("Set default IPv6 gateway error (%s)", +- strerror(-err)); +- +- return err; +-} +- + int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway) + { + struct in6_rtmsg rt; +@@ -809,63 +768,6 @@ out: + return err; + } + +-int connman_inet_set_gateway_address(int index, const char *gateway) +-{ +- struct ifreq ifr; +- struct rtentry rt; +- struct sockaddr_in addr; +- int sk, err = 0; +- +- DBG("index %d gateway %s", index, gateway); +- +- sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); +- if (sk < 0) { +- err = -errno; +- goto out; +- } +- +- memset(&ifr, 0, sizeof(ifr)); +- ifr.ifr_ifindex = index; +- +- if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { +- err = -errno; +- close(sk); +- goto out; +- } +- +- DBG("ifname %s", ifr.ifr_name); +- +- memset(&rt, 0, sizeof(rt)); +- rt.rt_flags = RTF_UP | RTF_GATEWAY; +- +- memset(&addr, 0, sizeof(addr)); +- addr.sin_family = AF_INET; +- addr.sin_addr.s_addr = INADDR_ANY; +- memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); +- +- memset(&addr, 0, sizeof(addr)); +- addr.sin_family = AF_INET; +- addr.sin_addr.s_addr = inet_addr(gateway); +- memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); +- +- memset(&addr, 0, sizeof(addr)); +- addr.sin_family = AF_INET; +- addr.sin_addr.s_addr = INADDR_ANY; +- memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); +- +- if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST) +- err = -errno; +- +- close(sk); +- +-out: +- if (err < 0) +- connman_error("Setting default gateway route failed (%s)", +- strerror(-err)); +- +- return err; +-} +- + int connman_inet_set_gateway_interface(int index) + { + struct ifreq ifr; +-- +1.7.11.7 + diff --git a/packages/network/connman/patches/connman-990.02.01-tethering-Cleanup_tethering_when_connman_is_shutting_down.patch b/packages/network/connman/patches/connman-990.02.01-tethering-Cleanup_tethering_when_connman_is_shutting_down.patch new file mode 100644 index 0000000000..337ae19655 --- /dev/null +++ b/packages/network/connman/patches/connman-990.02.01-tethering-Cleanup_tethering_when_connman_is_shutting_down.patch @@ -0,0 +1,36 @@ + +Betreff: +[PATCH] tethering: Cleanup tethering when connman is shutting down +Von: +Jukka Rissanen +Datum: +26.06.2013 09:40 +An: +connman@connman.net + +We do not want to leave the tether interface and bridge hanging +around after shutdown. +--- + src/tethering.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tethering.c b/src/tethering.c +index 0b373b9..03ed02a 100644 +--- a/src/tethering.c ++++ b/src/tethering.c +@@ -532,10 +532,10 @@ int __connman_tethering_init(void) + + void __connman_tethering_cleanup(void) + { +- DBG(""); ++ DBG("enabled %d", tethering_enabled); + + __sync_synchronize(); +- if (tethering_enabled == 0) { ++ if (tethering_enabled > 0) { + if (tethering_dhcp_server) + dhcp_server_stop(tethering_dhcp_server); + __connman_bridge_disable(BRIDGE_NAME); +-- +1.7.11.7 +