Parse IFA_F_* values above 0x80.

In RTM_NEWADDR messages, the first 8 flags are reported in the
ifa_flags field in struct ifaddrmsg, but flags above 0x80 are
reported in the IFA_FLAGS attribute. NetlinkEvent currently only
looks at ifa_flags, so it cannot see higher-value flags such as
IFA_F_STABLE_PRIVACY. Fix this by parsing the IFA_FLAGS
attribute.

Bug: 155005831
Test: makes new test in aosp/1295495 pass
Original-Change: https://android-review.googlesource.com/1295670
Merged-In: I723f1106cbcea2186fc6452305942a0f8301fd2a
Change-Id: I723f1106cbcea2186fc6452305942a0f8301fd2a
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 5efe03f..3340f8a 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -180,6 +180,7 @@
     struct ifa_cacheinfo *cacheinfo = nullptr;
     char addrstr[INET6_ADDRSTRLEN] = "";
     char ifname[IFNAMSIZ] = "";
+    uint32_t flags = 0;
 
     if (!checkRtNetlinkLength(nh, sizeof(*ifaddr)))
         return false;
@@ -230,6 +231,10 @@
                 SLOGD("Unknown ifindex %d in %s", ifaddr->ifa_index, msgtype);
             }
 
+            // First 8 bits of flags. In practice will always be overridden by the IFA_FLAGS below,
+            // because that always appears after IFA_ADDRESS. But just in case, support both orders.
+            flags = (flags & 0xffffff00) | ifaddr->ifa_flags;
+
         } else if (rta->rta_type == IFA_CACHEINFO) {
             // Address lifetime information.
             if (maybeLogDuplicateAttribute(cacheinfo, "IFA_CACHEINFO", msgtype))
@@ -242,6 +247,10 @@
             }
 
             cacheinfo = (struct ifa_cacheinfo *) RTA_DATA(rta);
+
+        } else if (rta->rta_type == IFA_FLAGS) {
+            // In practice IFA_FLAGS is always after IFA_ADDRESS, so this will overwrite the flags.
+            flags = *(uint32_t*)RTA_DATA(rta);
         }
     }
 
@@ -256,7 +265,7 @@
     mSubsystem = strdup("net");
     asprintf(&mParams[0], "ADDRESS=%s/%d", addrstr, ifaddr->ifa_prefixlen);
     asprintf(&mParams[1], "INTERFACE=%s", ifname);
-    asprintf(&mParams[2], "FLAGS=%u", ifaddr->ifa_flags);
+    asprintf(&mParams[2], "FLAGS=%u", flags);
     asprintf(&mParams[3], "SCOPE=%u", ifaddr->ifa_scope);
     asprintf(&mParams[4], "IFINDEX=%u", ifaddr->ifa_index);