OSDN Git Service

Cleanup p2p0 interface upon tearDownInterfaces().
authorNingyuan Wang <nywang@google.com>
Mon, 13 Mar 2017 16:41:29 +0000 (09:41 -0700)
committerNingyuan Wang <nywang@google.com>
Mon, 13 Mar 2017 21:42:47 +0000 (14:42 -0700)
This replaces NetlinkUtils::GetInterfaceInfo with NetlinkUtils::
GetInterfaces. Instead of picking client interface inside NetlinkUtils,
this change allows wificond main object(server) to dump all the interfaces
from kernel.
Being able to dump all interfaces, wificond main object therefore can mark
down all the interfaces upon cleanup.

Bug: 36139978
Bug: 35949498

Test: compile, unit tests, manual test, integration test

Change-Id: I66dd4f8c3b26087dd182591763de8fa4da29f1d6

net/netlink_utils.cpp
net/netlink_utils.h
server.cpp
server.h
tests/mock_netlink_utils.h
tests/netlink_utils_unittest.cpp
tests/server_unittest.cpp

index af0fee6..6a33d67 100644 (file)
@@ -90,21 +90,19 @@ bool NetlinkUtils::GetWiphyIndex(uint32_t* out_wiphy_index) {
   return true;
 }
 
-bool NetlinkUtils::GetInterfaceInfo(uint32_t wiphy_index,
-                                    string* name,
-                                    uint32_t* index,
-                                    vector<uint8_t>* mac_addr) {
-  NL80211Packet get_interface(
+bool NetlinkUtils::GetInterfaces(uint32_t wiphy_index,
+                                 vector<InterfaceInfo>* interface_info) {
+  NL80211Packet get_interfaces(
       netlink_manager_->GetFamilyId(),
       NL80211_CMD_GET_INTERFACE,
       netlink_manager_->GetSequenceNumber(),
       getpid());
 
-  get_interface.AddFlag(NLM_F_DUMP);
-  NL80211Attr<uint32_t> wiphy(NL80211_ATTR_WIPHY, wiphy_index);
-  get_interface.AddAttribute(wiphy);
+  get_interfaces.AddFlag(NLM_F_DUMP);
+  get_interfaces.AddAttribute(
+      NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY, wiphy_index));
   vector<unique_ptr<const NL80211Packet>> response;
-  if (!netlink_manager_->SendMessageAndGetResponses(get_interface, &response)) {
+  if (!netlink_manager_->SendMessageAndGetResponses(get_interfaces, &response)) {
     LOG(ERROR) << "NL80211_CMD_GET_INTERFACE dump failed";
     return false;
   }
@@ -130,6 +128,16 @@ bool NetlinkUtils::GetInterfaceInfo(uint32_t wiphy_index,
       return false;
     }
 
+    // In some situations, it has been observed that the kernel tells us
+    // about a pseudo interface that does not have a real netdev.  In this
+    // case, responses will have a NL80211_ATTR_WDEV, and not the expected
+    // IFNAME/IFINDEX. In this case we just skip these pseudo interfaces.
+    uint32_t if_index;
+    if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
+      LOG(DEBUG) << "Failed to get interface index";
+      continue;
+    }
+
     // Today we don't check NL80211_ATTR_IFTYPE because at this point of time
     // driver always reports that interface is in STATION mode. Even when we
     // are asking interfaces infomation on behalf of tethering, it is still so
@@ -137,39 +145,20 @@ bool NetlinkUtils::GetInterfaceInfo(uint32_t wiphy_index,
 
     string if_name;
     if (!packet->GetAttributeValue(NL80211_ATTR_IFNAME, &if_name)) {
-      // In some situations, it has been observed that the kernel tells us
-      // about a pseudo-device that does not have a real netdev.  In this
-      // case, responses will have a NL80211_ATTR_WDEV, and not the expected
-      // IFNAME.
-      LOG(DEBUG) << "Failed to get interface name";
-      continue;
-    }
-    if (if_name == "p2p0") {
-      LOG(DEBUG) << "Driver may tell a lie that p2p0 is in STATION mode,"
-                 <<" we need to blacklist it.";
-      continue;
-    }
-
-    uint32_t if_index;
-    if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
-      LOG(DEBUG) << "Failed to get interface index";
+      LOG(WARNING) << "Failed to get interface name";
       continue;
     }
 
     vector<uint8_t> if_mac_addr;
     if (!packet->GetAttributeValue(NL80211_ATTR_MAC, &if_mac_addr)) {
-      LOG(DEBUG) << "Failed to get interface mac address";
+      LOG(WARNING) << "Failed to get interface mac address";
       continue;
     }
 
-    *name = if_name;
-    *index = if_index;
-    *mac_addr = if_mac_addr;
-    return true;
+    interface_info->emplace_back(if_index, if_name, if_mac_addr);
   }
 
-  LOG(ERROR) << "Failed to get expected interface info from kernel";
-  return false;
+  return true;
 }
 
 bool NetlinkUtils::SetInterfaceMode(uint32_t interface_index,
index 65d6335..048deb7 100644 (file)
 namespace android {
 namespace wificond {
 
+struct InterfaceInfo {
+  InterfaceInfo() = default;
+  InterfaceInfo(uint32_t index_,
+                const std::string name_,
+                const std::vector<uint8_t> mac_address_)
+      : index(index_),
+        name(name_),
+        mac_address(mac_address_) {}
+  // Index of this interface.
+  uint32_t index;
+  // Name of this interface.
+  std::string name;
+  // MAC address of this interface.
+  std::vector<uint8_t> mac_address;
+};
+
 struct BandInfo {
   BandInfo() = default;
   BandInfo(std::vector<uint32_t>& band_2g_,
@@ -123,13 +139,13 @@ class NetlinkUtils {
   // Returns true on success.
   virtual bool GetWiphyIndex(uint32_t* out_wiphy_index);
 
-  // Get wifi interface info from kernel.
+  // Get wifi interfaces info from kernel.
   // |wiphy_index| is the wiphy index we get using GetWiphyIndex().
+  // |interface_info| returns a vector of InterfaceInfo structs with
+  // information about all existing interfaces.
   // Returns true on success.
-  virtual bool GetInterfaceInfo(uint32_t wiphy_index,
-                                std::string* name,
-                                uint32_t* index,
-                                std::vector<uint8_t>* mac_addr);
+  virtual bool GetInterfaces(uint32_t wiphy_index,
+                             std::vector<InterfaceInfo>* interface_info);
 
   // Set the mode of interface.
   // |interface_index| is the interface index.
index 79e270b..e8c56c6 100644 (file)
@@ -103,18 +103,14 @@ Status Server::unregisterRttClient(const sp<IRttClient>& rttClient) {
 }
 
 Status Server::createApInterface(sp<IApInterface>* created_interface) {
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  if (!SetupInterface(&interface_name,
-                             &interface_index,
-                             &interface_mac_addr)) {
+  InterfaceInfo interface;
+  if (!SetupInterface(&interface)) {
     return Status::ok();  // Logging was done internally
   }
 
   unique_ptr<ApInterfaceImpl> ap_interface(new ApInterfaceImpl(
-      interface_name,
-      interface_index,
+      interface.name,
+      interface.index,
       netlink_utils_,
       if_tool_.get(),
       hostapd_manager_.get()));
@@ -126,20 +122,16 @@ Status Server::createApInterface(sp<IApInterface>* created_interface) {
 }
 
 Status Server::createClientInterface(sp<IClientInterface>* created_interface) {
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  if (!SetupInterface(&interface_name,
-                             &interface_index,
-                             &interface_mac_addr)) {
+  InterfaceInfo interface;
+  if (!SetupInterface(&interface)) {
     return Status::ok();  // Logging was done internally
   }
 
   unique_ptr<ClientInterfaceImpl> client_interface(new ClientInterfaceImpl(
       wiphy_index_,
-      interface_name,
-      interface_index,
-      interface_mac_addr,
+      interface.name,
+      interface.index,
+      interface.mac_address,
       if_tool_.get(),
       supplicant_manager_.get(),
       netlink_utils_,
@@ -162,6 +154,8 @@ Status Server::tearDownInterfaces() {
   }
   ap_interfaces_.clear();
 
+  MarkDownAllInterfaces();
+
   netlink_utils_->UnsubscribeRegDomainChange(wiphy_index_);
 
   return Status::ok();
@@ -183,29 +177,24 @@ Status Server::GetApInterfaces(vector<sp<IBinder>>* out_ap_interfaces) {
   return binder::Status::ok();
 }
 
+void Server::MarkDownAllInterfaces() {
+  uint32_t wiphy_index;
+  vector<InterfaceInfo> interfaces;
+  if (netlink_utils_->GetWiphyIndex(&wiphy_index) &&
+      netlink_utils_->GetInterfaces(wiphy_index, &interfaces)) {
+    for (InterfaceInfo& interface : interfaces) {
+      if_tool_->SetUpState(interface.name.c_str(), false);
+    }
+  }
+}
+
 void Server::CleanUpSystemState() {
   supplicant_manager_->StopSupplicant();
   hostapd_manager_->StopHostapd();
-
-  uint32_t phy_index = 0;
-  uint32_t if_index = 0;
-  vector<uint8_t> mac;
-  string if_name;
-  if (netlink_utils_->GetWiphyIndex(&phy_index) &&
-      netlink_utils_->GetInterfaceInfo(phy_index,
-                                       &if_name,
-                                       &if_index,
-                                       &mac)) {
-    // If the kernel knows about a network interface, mark it as down.
-    // This prevents us from beaconing as an AP, or remaining associated
-    // as a client.
-    if_tool_->SetUpState(if_name.c_str(), false);
-  }
+  MarkDownAllInterfaces();
 }
 
-bool Server::SetupInterface(string* interface_name,
-                            uint32_t* interface_index,
-                            vector<uint8_t>* interface_mac_addr) {
+bool Server::SetupInterface(InterfaceInfo* interface) {
   if (!ap_interfaces_.empty() || !client_interfaces_.empty()) {
     // In the future we may support multiple interfaces at once.  However,
     // today, we support just one.
@@ -223,15 +212,24 @@ bool Server::SetupInterface(string* interface_name,
           this,
           _1));
 
-  if (!netlink_utils_->GetInterfaceInfo(wiphy_index_,
-                                        interface_name,
-                                        interface_index,
-                                        interface_mac_addr)) {
-    LOG(ERROR) << "Failed to get interface info from kernel";
+  vector<InterfaceInfo> interfaces;
+  if (!netlink_utils_->GetInterfaces(wiphy_index_, &interfaces)) {
+    LOG(ERROR) << "Failed to get interfaces info from kernel";
     return false;
   }
 
-  return true;
+  for (InterfaceInfo& iface : interfaces) {
+    // Some kernel/driver uses station type for p2p interface.
+    // In that case we can only rely on hard-coded name to exclude
+    // p2p interface from station interfaces.
+    if (iface.name != "p2p0") {
+      *interface = iface;
+      return true;
+    }
+  }
+
+  LOG(ERROR) << "No usable interface found";
+  return false;
 }
 
 bool Server::RefreshWiphyIndex() {
index 5ceca25..a0f5b2c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -40,6 +40,8 @@ class NL80211Packet;
 class NetlinkUtils;
 class ScanUtils;
 
+struct InterfaceInfo;
+
 class Server : public android::net::wifi::BnWificond {
  public:
   Server(std::unique_ptr<wifi_system::InterfaceTool> if_tool,
@@ -91,9 +93,7 @@ class Server : public android::net::wifi::BnWificond {
   // interface on behalf of createApInterace(), it is Hostapd that configure
   // the interface to Ap mode later.
   // Returns true on success, false otherwise.
-  bool SetupInterface(std::string* interface_name,
-                      uint32_t* interface_index,
-                      std::vector<uint8_t>* interface_mac_addr);
+  bool SetupInterface(InterfaceInfo* interface);
   bool RefreshWiphyIndex();
   void LogSupportedBands();
   void OnRegDomainChanged(std::string& country_code);
@@ -105,6 +105,7 @@ class Server : public android::net::wifi::BnWificond {
       android::sp<android::net::wifi::IClientInterface> network_interface);
   void BroadcastApInterfaceTornDown(
       android::sp<android::net::wifi::IApInterface> network_interface);
+  void MarkDownAllInterfaces();
 
   const std::unique_ptr<wifi_system::InterfaceTool> if_tool_;
   const std::unique_ptr<wifi_system::SupplicantManager> supplicant_manager_;
index c0550a3..a8fd63c 100644 (file)
@@ -41,11 +41,9 @@ class MockNetlinkUtils : public NetlinkUtils {
                void(uint32_t wiphy_index,
                     OnRegDomainChangedHandler handler));
 
-  MOCK_METHOD4(GetInterfaceInfo,
+  MOCK_METHOD2(GetInterfaces,
                bool(uint32_t wiphy_index,
-                    std::string* name,
-                    uint32_t* index,
-                    std::vector<uint8_t>* mac_address));
+                    std::vector<InterfaceInfo>* interfaces));
   MOCK_METHOD4(GetWiphyInfo,
                bool(uint32_t wiphy_index,
                     BandInfo* band_info,
index c1a01c2..b1a7939 100644 (file)
@@ -54,7 +54,9 @@ constexpr uint16_t kFakeWiphyIndex = 8;
 constexpr int kFakeErrorCode = EIO;
 const char kFakeInterfaceName[] = "testif0";
 const uint32_t kFakeInterfaceIndex = 34;
+const uint32_t kFakeInterfaceIndex1 = 36;
 const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
 
 // Currently, control messages are only created by the kernel and sent to us.
 // Therefore NL80211Packet doesn't have corresponding constructor.
@@ -158,7 +160,7 @@ TEST_F(NetlinkUtilsTest, CanHandleSetIntrerfaceModeError) {
                                                 NetlinkUtils::STATION_MODE));
 }
 
-TEST_F(NetlinkUtilsTest, CanGetInterfaceInfo) {
+TEST_F(NetlinkUtilsTest, CanGetInterfaces) {
   NL80211Packet new_interface(
       netlink_manager_->GetFamilyId(),
       NL80211_CMD_NEW_INTERFACE,
@@ -184,20 +186,17 @@ TEST_F(NetlinkUtilsTest, CanGetInterfaceInfo) {
   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
       WillOnce(DoAll(MakeupResponse(response), Return(true)));
 
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
-                                               &interface_name,
-                                               &interface_index,
-                                               &interface_mac_addr));
-  EXPECT_EQ(string(kFakeInterfaceName), interface_name);
-  EXPECT_EQ(kFakeInterfaceIndex, interface_index);
-  EXPECT_EQ(if_mac_addr, interface_mac_addr);
+  vector<InterfaceInfo> interfaces;
+  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
+  EXPECT_TRUE(interfaces.size() == 1);
+  EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
+  EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
+  EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
 }
 
-TEST_F(NetlinkUtilsTest, HandlesPseudoDevicesInInterfaceInfoQuery) {
-  // Some kernels will have extra responses ahead of the expected packet.
+TEST_F(NetlinkUtilsTest, SkipsPseudoDevicesWhenGetInterfaces) {
+  // This might be a psuedo p2p interface without any interface index/name
+  // attributes.
   NL80211Packet psuedo_interface(
       netlink_manager_->GetFamilyId(),
       NL80211_CMD_NEW_INTERFACE,
@@ -206,7 +205,7 @@ TEST_F(NetlinkUtilsTest, HandlesPseudoDevicesInInterfaceInfoQuery) {
   psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
       NL80211_ATTR_WDEV, 0));
 
-  // This is the packet we're looking for
+  // This is a regular client interface.
   NL80211Packet expected_interface(
       netlink_manager_->GetFamilyId(),
       NL80211_CMD_NEW_INTERFACE,
@@ -229,17 +228,15 @@ TEST_F(NetlinkUtilsTest, HandlesPseudoDevicesInInterfaceInfoQuery) {
   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
       WillOnce(DoAll(MakeupResponse(response), Return(true)));
 
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(
-      kFakeWiphyIndex, &interface_name, &interface_index, &interface_mac_addr));
-  EXPECT_EQ(string(kFakeInterfaceName), interface_name);
-  EXPECT_EQ(kFakeInterfaceIndex, interface_index);
-  EXPECT_EQ(if_mac_addr, interface_mac_addr);
+  vector<InterfaceInfo> interfaces;
+  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
+  EXPECT_TRUE(interfaces.size() == 1);
+  EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
+  EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
+  EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
 }
 
-TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaceInfo) {
+TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaces) {
   NL80211Packet new_interface(
       netlink_manager_->GetFamilyId(),
       NL80211_CMD_NEW_INTERFACE,
@@ -249,15 +246,14 @@ TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaceInfo) {
   NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
   new_interface.AddAttribute(if_name_attr);
   // Insert interface index attribute.
-  NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
-  new_interface.AddAttribute(if_index_attr);
+  new_interface.AddAttribute(
+      NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
   // Insert mac address attribute.
-  std::vector<uint8_t> if_mac_addr;
-  if_mac_addr.assign(
+  std::vector<uint8_t> if_mac_addr(
       kFakeInterfaceMacAddress,
       kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
-  NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
-  new_interface.AddAttribute(if_mac_attr);
+  new_interface.AddAttribute(
+      NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
 
   // Create a new interface packet for p2p0.
   NL80211Packet new_interface_p2p0(
@@ -265,40 +261,48 @@ TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaceInfo) {
       NL80211_CMD_NEW_INTERFACE,
       netlink_manager_->GetSequenceNumber(),
       getpid());
-  NL80211Attr<string> if_name_attr_p2p0(NL80211_ATTR_IFNAME, "p2p0");
-  new_interface_p2p0.AddAttribute(if_name_attr_p2p0);
+
+  // Insert interface name attribute.
+  new_interface_p2p0.AddAttribute(
+      NL80211Attr<string>(NL80211_ATTR_IFNAME, "p2p0"));
+  // Insert interface index attribute.
+  new_interface_p2p0.AddAttribute(
+      NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
+  // Insert mac address attribute.
+  std::vector<uint8_t> if_mac_addr_p2p(
+      kFakeInterfaceMacAddress1,
+      kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1));
+  new_interface_p2p0.AddAttribute(
+      NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
+
   // Mock response from kernel, including 2 interfaces.
   vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
 
   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
       WillOnce(DoAll(MakeupResponse(response), Return(true)));
 
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
-                                               &interface_name,
-                                               &interface_index,
-                                               &interface_mac_addr));
-  EXPECT_EQ(string(kFakeInterfaceName), interface_name);
-  EXPECT_EQ(kFakeInterfaceIndex, interface_index);
-  EXPECT_EQ(if_mac_addr, interface_mac_addr);
+  vector<InterfaceInfo> interfaces;
+  EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
+  EXPECT_TRUE(interfaces.size() == 2);
+
+  EXPECT_EQ(kFakeInterfaceIndex1, interfaces[0].index);
+  EXPECT_EQ(string("p2p0"), interfaces[0].name);
+  EXPECT_EQ(if_mac_addr_p2p, interfaces[0].mac_address);
+
+  EXPECT_EQ(kFakeInterfaceIndex, interfaces[1].index);
+  EXPECT_EQ(string(kFakeInterfaceName), interfaces[1].name);
+  EXPECT_EQ(if_mac_addr, interfaces[1].mac_address);
 }
 
-TEST_F(NetlinkUtilsTest, CanHandleGetInterfaceInfoError) {
+TEST_F(NetlinkUtilsTest, CanHandleGetInterfacesError) {
   // Mock an error response from kernel.
   vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
 
   EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
       WillOnce(DoAll(MakeupResponse(response), Return(true)));
 
-  string interface_name;
-  uint32_t interface_index;
-  vector<uint8_t> interface_mac_addr;
-  EXPECT_FALSE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
-                                                &interface_name,
-                                                &interface_index,
-                                                &interface_mac_addr));
+  vector<InterfaceInfo> interfaces;
+  EXPECT_FALSE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
 }
 
 TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
index e9d2175..8639934 100644 (file)
@@ -36,22 +36,50 @@ using android::wifi_system::MockInterfaceTool;
 using android::wifi_system::MockSupplicantManager;
 using android::wifi_system::SupplicantManager;
 using std::unique_ptr;
+using std::vector;
+using testing::Invoke;
 using testing::NiceMock;
 using testing::Return;
 using testing::Sequence;
 using testing::_;
 
+using namespace std::placeholders;
+
 namespace android {
 namespace wificond {
 namespace {
 
+const char kFakeInterfaceName[] = "testif0";
+const uint32_t kFakeInterfaceIndex = 34;
+const uint32_t kFakeInterfaceIndex1 = 36;
+const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
+const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
+
+// This is a helper function to mock the behavior of
+// NetlinkUtils::GetInterfaces().
+// |wiphy_index| is mapped to first parameters of GetInterfaces().
+// |response| is mapped to second parameters of GetInterfaces().
+// |mock_response| and |mock_return_value| are additional parameters used
+// for specifying expected results,
+bool MockGetInterfacesResponse(
+    const vector<InterfaceInfo>& mock_response,
+    bool mock_return_value,
+    uint32_t wiphy_index,
+    vector<InterfaceInfo>* response) {
+  for (auto interface : mock_response) {
+    response->emplace_back(interface);
+  }
+  return mock_return_value;
+}
+
 class ServerTest : public ::testing::Test {
  protected:
   void SetUp() override {
     ON_CALL(*if_tool_, SetWifiUpState(_)).WillByDefault(Return(true));
     ON_CALL(*netlink_utils_, GetWiphyIndex(_)).WillByDefault(Return(true));
-    ON_CALL(*netlink_utils_, GetInterfaceInfo(_, _, _, _))
-        .WillByDefault(Return(true));
+    ON_CALL(*netlink_utils_, GetInterfaces(_, _))
+      .WillByDefault(Invoke(bind(
+          MockGetInterfacesResponse, mock_interfaces, true, _1, _2)));
   }
 
   NiceMock<MockInterfaceTool>* if_tool_ = new NiceMock<MockInterfaceTool>;
@@ -67,7 +95,22 @@ class ServerTest : public ::testing::Test {
       new NiceMock<MockNetlinkUtils>(netlink_manager_.get())};
   unique_ptr<NiceMock<MockScanUtils>> scan_utils_{
       new NiceMock<MockScanUtils>(netlink_manager_.get())};
-
+  const vector<InterfaceInfo> mock_interfaces = {
+      // Client interface
+      InterfaceInfo(
+          kFakeInterfaceIndex,
+          std::string(kFakeInterfaceName),
+          vector<uint8_t>(
+              kFakeInterfaceMacAddress,
+              kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress))),
+      // p2p interface
+      InterfaceInfo(
+          kFakeInterfaceIndex1,
+          "p2p0",
+           vector<uint8_t>(
+               kFakeInterfaceMacAddress1,
+               kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1)))
+  };
 
   Server server_{unique_ptr<InterfaceTool>(if_tool_),
                  unique_ptr<SupplicantManager>(supplicant_manager_),
@@ -80,14 +123,7 @@ class ServerTest : public ::testing::Test {
 
 TEST_F(ServerTest, CanSetUpApInterface) {
   sp<IApInterface> ap_if;
-  Sequence sequence;
-  EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_))
-      .InSequence(sequence)
-      .WillOnce(Return(true));
   EXPECT_CALL(*netlink_utils_, SubscribeRegDomainChange(_, _));
-  EXPECT_CALL(*netlink_utils_, GetInterfaceInfo(_, _, _, _))
-      .InSequence(sequence)
-      .WillOnce(Return(true));
 
   EXPECT_TRUE(server_.createApInterface(&ap_if).isOk());
   EXPECT_NE(nullptr, ap_if.get());
@@ -95,8 +131,6 @@ TEST_F(ServerTest, CanSetUpApInterface) {
 
 TEST_F(ServerTest, DoesNotSupportMultipleInterfaces) {
   sp<IApInterface> ap_if;
-  EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_)).Times(1);
-  EXPECT_CALL(*netlink_utils_, GetInterfaceInfo(_, _, _, _)).Times(1);
 
   EXPECT_TRUE(server_.createApInterface(&ap_if).isOk());
   EXPECT_NE(nullptr, ap_if.get());
@@ -110,8 +144,6 @@ TEST_F(ServerTest, DoesNotSupportMultipleInterfaces) {
 
 TEST_F(ServerTest, CanDestroyInterfaces) {
   sp<IApInterface> ap_if;
-  EXPECT_CALL(*netlink_utils_, GetWiphyIndex(_)).Times(2);
-  EXPECT_CALL(*netlink_utils_, GetInterfaceInfo(_, _, _, _)).Times(2);
 
   EXPECT_TRUE(server_.createApInterface(&ap_if).isOk());