Use RTM_NEWADDR, RTM_DELADDR to receive info about an IP address.
authorhyuna0213.jo <hyuna0213.jo@samsung.com>
Mon, 14 Nov 2016 06:50:36 +0000 (15:50 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Wed, 7 Dec 2016 04:20:19 +0000 (04:20 +0000)
We use RTM_NEWLINK multicast group mask to receive information about
a created or removed network interface. and If a specific network
interface is added, we call getifaddrs() to get an IP address
associated with an interface. but it is more correct to use
RTM_NEWADDR, RTM_DELADDR to detect IP address changes.

Change-Id: I9389cac95473583a015dd4d40489943dc856e0fd
Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/14277
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
Reviewed-by: Phil Coval <philippe.coval@osg.samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c

index 5c2b06e..c7f9727 100644 (file)
@@ -836,7 +836,8 @@ static void CARegisterForAddressChanges()
     caglobals.ip.netlinkFd = OC_INVALID_SOCKET;
 #ifdef __linux__
     // create NETLINK fd for interface change notifications
-    struct sockaddr_nl sa = { AF_NETLINK, 0, 0, RTMGRP_LINK };
+    struct sockaddr_nl sa = { AF_NETLINK, 0, 0,
+                              RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR };
 
     caglobals.ip.netlinkFd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
     if (caglobals.ip.netlinkFd == OC_INVALID_SOCKET)
index c64b6a0..26fbef8 100644 (file)
@@ -330,37 +330,38 @@ u_arraylist_t *CAFindInterfaceChange()
 
     for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len))
     {
-        if (nh != NULL && nh->nlmsg_type != RTM_NEWLINK)
+        if (nh != NULL && (nh->nlmsg_type != RTM_DELADDR && nh->nlmsg_type != RTM_NEWADDR))
         {
             continue;
         }
 
-        struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
-        if (!ifi)
+        if (RTM_DELADDR == nh->nlmsg_type)
         {
-            OIC_LOG_V(ERROR, TAG, "ifi is NULL");
-            return NULL;
-        }
-
-        int ifiIndex = ifi->ifi_index;
-
-        if ((ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING))
-        {
-            bool isFound = CACmpNetworkList(ifiIndex);
-            if (isFound)
+            struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA (nh);
+            if (ifa)
             {
-                CARemoveNetworkMonitorList(ifiIndex);
-                CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
+                int ifiIndex = ifa->ifa_index;
+                bool isFound = CACmpNetworkList(ifiIndex);
+                if (isFound)
+                {
+                    CARemoveNetworkMonitorList(ifiIndex);
+                    CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
+                }
             }
             continue;
         }
 
-        iflist = CAIPGetInterfaceInformation(ifiIndex);
-
-        if (!iflist)
+        // Netlink message type is RTM_NEWADDR.
+        struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA (nh);
+        if (ifa)
         {
-            OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
-            return NULL;
+            int ifiIndex = ifa->ifa_index;
+            iflist = CAIPGetInterfaceInformation(ifiIndex);
+            if (!iflist)
+            {
+                OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+                return NULL;
+            }
         }
     }
 #endif