Relax the IP Family check in XfrmController

To enable dual sockets, the family check in xfrmcontroller
is very strict. This has been relaxed so that IP V6 sockets
do not throw "Mismatched Address family" exception if V4 address
is used.
Also added Unit test to verify the same.

Bug: 70160694
Test: Ran runtest -x system/netd/server/netd_unit_test.cpp
Change-Id: Ib1bba21037ec1de3858c595fa32fee5e833d18bf
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index c9389cd..24ccee4 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -612,10 +612,10 @@
         return status;
     }
 
-    if (saInfo.addrFamily != saddr.ss_family) {
-        ALOGE("Transform address family(%d) differs from socket address "
-              "family(%d)!",
-              saInfo.addrFamily, saddr.ss_family);
+    if (saddr.ss_family == AF_INET && saInfo.addrFamily != AF_INET) {
+        ALOGE("IPV4 socket address family(%d) should match IPV4 Transform "
+              "address family(%d)!",
+              saddr.ss_family, saInfo.addrFamily);
         return netdutils::statusFromErrno(EINVAL, "Mismatched address family");
     }
 
@@ -630,7 +630,7 @@
     LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
 
     int sockOpt, sockLayer;
-    switch (saInfo.addrFamily) {
+    switch (saddr.ss_family) {
         case AF_INET:
             sockOpt = IP_XFRM_POLICY;
             sockLayer = SOL_IP;
diff --git a/server/XfrmControllerTest.cpp b/server/XfrmControllerTest.cpp
index cb8bb0e..a588cc5 100644
--- a/server/XfrmControllerTest.cpp
+++ b/server/XfrmControllerTest.cpp
@@ -139,7 +139,12 @@
 
 // Helper to make generated test names readable.
 std::string FamilyName(::testing::TestParamInfo<int> info) {
-    return (info.param == AF_INET) ? "AF_INET" : "AF_INET6";
+    switch(info.param) {
+        case 4: return "IPv4";
+        case 5: return "IPv64DualStack";
+        case 6: return "IPv6";
+    }
+    return android::base::StringPrintf("UNKNOWN family type: %d", info.param);
 }
 
 /* Generate function to set value refered to by 3rd argument.
@@ -210,13 +215,14 @@
 }
 
 // The TEST_P cases below will run with each of the following value parameters.
-INSTANTIATE_TEST_CASE_P(ByFamily, XfrmControllerParameterizedTest, Values(AF_INET, AF_INET6),
+INSTANTIATE_TEST_CASE_P(ByFamily, XfrmControllerParameterizedTest, Values(4, 5, 6),
                         FamilyName);
 
 TEST_P(XfrmControllerParameterizedTest, TestIpSecAllocateSpi) {
-    const int family = GetParam();
-    const std::string localAddr = (family == AF_INET6) ? LOCALHOST_V6 : LOCALHOST_V4;
-    const std::string remoteAddr = (family == AF_INET6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
+    const int version = GetParam();
+    const int family = (version == 6) ? AF_INET6 : AF_INET;
+    const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
+    const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
 
     NetlinkResponse response{};
     response.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;
@@ -254,10 +260,11 @@
     EXPECT_EQ(DROID_SPI, static_cast<int>(userspi.max));
 }
 
-void testIpSecAddSecurityAssociation(int family, const MockSyscalls& mockSyscalls,
+void testIpSecAddSecurityAssociation(int version, const MockSyscalls& mockSyscalls,
                                      const XfrmMode& mode) {
-    const std::string localAddr = (family == AF_INET6) ? LOCALHOST_V6 : LOCALHOST_V4;
-    const std::string remoteAddr = (family == AF_INET6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
+    const int family = (version == 6) ? AF_INET6 : AF_INET;
+    const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
+    const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
 
     NetlinkResponse response{};
     response.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;
@@ -343,13 +350,13 @@
 }
 
 TEST_P(XfrmControllerParameterizedTest, TestTransportModeIpSecAddSecurityAssociation) {
-    const int family = GetParam();
-    testIpSecAddSecurityAssociation(family, mockSyscalls, XfrmMode::TRANSPORT);
+    const int version = GetParam();
+    testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TRANSPORT);
 }
 
 TEST_P(XfrmControllerParameterizedTest, TestTunnelModeIpSecAddSecurityAssociation) {
-    const int family = GetParam();
-    testIpSecAddSecurityAssociation(family, mockSyscalls, XfrmMode::TUNNEL);
+    const int version = GetParam();
+    testIpSecAddSecurityAssociation(version, mockSyscalls, XfrmMode::TUNNEL);
 }
 
 TEST_F(XfrmControllerTest, TestIpSecAddSecurityAssociationIPv4Encap) {
@@ -370,10 +377,29 @@
     EXPECT_FALSE(isOk(res)) << "IPv6 UDP encap not rejected";
 }
 
+TEST_F(XfrmControllerTest, TestIpSecApplyTransportModeTransformChecksFamily) {
+    struct sockaddr socketaddr;
+    socketaddr.sa_family = AF_INET;
+
+    unique_fd sock(socket(AF_INET, SOCK_STREAM, 0));
+
+    EXPECT_CALL(mockSyscalls, getsockname(Fd(sock), _, _))
+        .WillOnce(DoAll(SetArgPointee<1>(socketaddr), Return(netdutils::status::ok)));
+
+    XfrmController ctrl;
+    Status res = ctrl.ipSecApplyTransportModeTransform(sock, 1 /* resourceId */,
+                                                       static_cast<int>(XfrmDirection::OUT),
+                                                       LOCALHOST_V6, TEST_ADDR_V6, DROID_SPI);
+
+    EXPECT_EQ(res.code(), EINVAL);
+}
+
 TEST_P(XfrmControllerParameterizedTest, TestIpSecApplyTransportModeTransform) {
-    const int family = GetParam();
-    const std::string localAddr = (family == AF_INET6) ? LOCALHOST_V6 : LOCALHOST_V4;
-    const std::string remoteAddr = (family == AF_INET6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
+    const int version = GetParam();
+    const int sockFamily = (version == 4) ? AF_INET : AF_INET6;
+    const int xfrmFamily = (version == 6) ? AF_INET6: AF_INET;
+    const std::string localAddr = (version == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
+    const std::string remoteAddr = (version == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
 
     size_t optlen = 0;
     Policy policy{};
@@ -384,9 +410,9 @@
     };
 
     struct sockaddr socketaddr;
-    socketaddr.sa_family = family;
+    socketaddr.sa_family = sockFamily;
 
-    unique_fd sock(socket(family, SOCK_STREAM, 0));
+    unique_fd sock(socket(sockFamily, SOCK_STREAM, 0));
 
     EXPECT_CALL(mockSyscalls, getsockname(_, _, _))
         .WillOnce(DoAll(SetArgPointee<1>(socketaddr), Return(netdutils::status::ok)));
@@ -406,14 +432,14 @@
     EXPECT_EQ(1 /* resourceId */, static_cast<int>(policy.tmpl.reqid));
     EXPECT_EQ(htonl(DROID_SPI), policy.tmpl.id.spi);
 
-    expectAddressEquals(family, localAddr, policy.tmpl.saddr);
-    expectAddressEquals(family, remoteAddr, policy.tmpl.id.daddr);
+    expectAddressEquals(xfrmFamily, localAddr, policy.tmpl.saddr);
+    expectAddressEquals(xfrmFamily, remoteAddr, policy.tmpl.id.daddr);
 }
 
 TEST_P(XfrmControllerParameterizedTest, TestIpSecDeleteSecurityAssociation) {
-    const int family = GetParam();
-    const std::string localAddr = (family == AF_INET6) ? LOCALHOST_V6 : LOCALHOST_V4;
-    const std::string remoteAddr = (family == AF_INET6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
+    const int family = (GetParam() == 6) ? AF_INET6 : AF_INET;
+    const std::string localAddr = (family == 6) ? LOCALHOST_V6 : LOCALHOST_V4;
+    const std::string remoteAddr = (family == 6) ? TEST_ADDR_V6 : TEST_ADDR_V4;
 
     NetlinkResponse response{};
     response.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;