vpnd: Make sure provider is taken to ready state
authorJukka Rissanen <jukka.rissanen@linux.intel.com>
Mon, 12 Nov 2012 12:07:50 +0000 (14:07 +0200)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 23 Nov 2012 10:58:52 +0000 (12:58 +0200)
If the connman_inet_ifup() says the interface is already UP,
then it is possible that we might not get a call to vpn_newlink().
That would be really bad as the provider would then never go to
ready state. So in this case we manually call vpn_newlink() to
take the interface UP. If the newlink was called before our call,
then our manual call will be ignored.

vpn/plugins/vpn.c

index 2a0fdaf..3b0fd3a 100644 (file)
@@ -216,7 +216,7 @@ static DBusMessage *vpn_notify(struct connman_task *task,
        struct vpn_data *data;
        struct vpn_driver_data *vpn_driver_data;
        const char *name;
-       int state, index;
+       int state, index, err;
 
        data = vpn_provider_get_data(provider);
 
@@ -236,7 +236,22 @@ static DBusMessage *vpn_notify(struct connman_task *task,
                vpn_provider_ref(provider);
                data->watch = vpn_rtnl_add_newlink_watch(index,
                                                     vpn_newlink, provider);
-               connman_inet_ifup(index);
+               err = connman_inet_ifup(index);
+               if (err < 0) {
+                       if (err == -EALREADY)
+                               /*
+                                * So the interface is up already, that is just
+                                * great. Unfortunately in this case the
+                                * newlink watch might not have been called at
+                                * all. We must manually call it here so that
+                                * the provider can go to ready state and the
+                                * routes are setup properly.
+                                */
+                               vpn_newlink(IFF_UP, 0, provider);
+                       else
+                               DBG("Cannot take interface %d up err %d/%s",
+                                       index, -err, strerror(-err));
+               }
                break;
 
        case VPN_STATE_UNKNOWN: