If the IP address changes when VPN restarts, then we handle that by clearing the old address and setting the routes properly. --- vpn/plugins/vpn.c | 25 +++++++++++++++++++++++++ vpn/vpn-provider.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index 080086d..a1c5f18 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -245,6 +245,31 @@ static DBusMessage *vpn_notify(struct connman_task *task, switch (state) { case VPN_STATE_CONNECT: case VPN_STATE_READY: + if (data->state == VPN_STATE_READY) { + /* + * This is the restart case, in which case we must + * just set the IP address. + * + * We need to remove first the old address, just + * replacing the old address will not work as expected + * because the old address will linger in the interface + * and not disapper so the clearing is needed here. + * + * Also the state must change, otherwise the routes + * will not be set properly. + */ + vpn_provider_set_state(provider, + VPN_PROVIDER_STATE_CONNECT); + + vpn_provider_clear_address(provider, AF_INET); + vpn_provider_clear_address(provider, AF_INET6); + + vpn_provider_change_address(provider); + vpn_provider_set_state(provider, + VPN_PROVIDER_STATE_READY); + break; + } + index = vpn_provider_get_index(provider); vpn_provider_ref(provider); data->watch = vpn_rtnl_add_newlink_watch(index, diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index 5bc6093..f922730 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -2308,19 +2308,41 @@ int vpn_provider_set_ipaddress(struct vpn_provider *provider, break; } - DBG("provider %p ipconfig %p family %d", provider, ipconfig, - ipaddress->family); + DBG("provider %p state %d ipconfig %p family %d", provider, + provider->state, ipconfig, ipaddress->family); if (!ipconfig) return -EINVAL; provider->family = ipaddress->family; - __vpn_ipconfig_set_local(ipconfig, ipaddress->local); - __vpn_ipconfig_set_peer(ipconfig, ipaddress->peer); - __vpn_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast); - __vpn_ipconfig_set_gateway(ipconfig, ipaddress->gateway); - __vpn_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen); + if (provider->state == VPN_PROVIDER_STATE_CONNECT || + provider->state == VPN_PROVIDER_STATE_READY) { + struct connman_ipaddress *addr = + __vpn_ipconfig_get_address(ipconfig); + + /* + * Remember the old address so that we can remove it in notify + * function in plugins/vpn.c if we ever restart + */ + if (ipaddress->family == AF_INET6) { + connman_ipaddress_free(provider->prev_ipv6_addr); + provider->prev_ipv6_addr = + connman_ipaddress_copy(addr); + } else { + connman_ipaddress_free(provider->prev_ipv4_addr); + provider->prev_ipv4_addr = + connman_ipaddress_copy(addr); + } + } + + if (ipaddress->local) { + __vpn_ipconfig_set_local(ipconfig, ipaddress->local); + __vpn_ipconfig_set_peer(ipconfig, ipaddress->peer); + __vpn_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast); + __vpn_ipconfig_set_gateway(ipconfig, ipaddress->gateway); + __vpn_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen); + } return 0; } -- 1.8.3.1 _______________________________________________ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman