diff options
author | derekjchow <derekjchow@chromium.org> | 2015-06-19 19:59:43 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-20 03:00:24 +0000 |
commit | 72407efac2875e2713b7f730eb998ab30f2005d5 (patch) | |
tree | 4ad6d0f3ad9cb1ff621ad5bd84f5f5b9a35f96b1 /net | |
parent | 9d193b1cfe7fed9f5e73dc6ad4e7623671762ea4 (diff) | |
download | chromium_src-72407efac2875e2713b7f730eb998ab30f2005d5.zip chromium_src-72407efac2875e2713b7f730eb998ab30f2005d5.tar.gz chromium_src-72407efac2875e2713b7f730eb998ab30f2005d5.tar.bz2 |
Ignore spurious RTM_NEWLINK wireless messages from rtnetlink.
Netlink will send out spurious RTM_NEWLINK messages. These messages
should not be used to update online_links_. Filter these RTM_NEWLINK
messages if ifi_change is zero and IFLA_WIRELESS.
R=pauljensen@chromium.org,wzhong@chromium.org,icoolidge@chromium.org
BUG=501982
Review URL: https://codereview.chromium.org/1192713003
Cr-Commit-Position: refs/heads/master@{#335425}
Diffstat (limited to 'net')
-rw-r--r-- | net/base/address_tracker_linux.cc | 18 | ||||
-rw-r--r-- | net/base/address_tracker_linux_unittest.cc | 40 |
2 files changed, 58 insertions, 0 deletions
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc index 9d41387..58a122f 100644 --- a/net/base/address_tracker_linux.cc +++ b/net/base/address_tracker_linux.cc @@ -20,6 +20,20 @@ namespace internal { namespace { +// Some kernel functions such as wireless_send_event and rtnetlink_ifinfo_prep +// may send spurious messages over rtnetlink. RTM_NEWLINK messages where +// ifi_change == 0 and rta_type == IFLA_WIRELESS should be ignored. +bool IgnoreWirelessChange(const struct nlmsghdr* header, + const struct ifinfomsg* msg) { + size_t length = IFLA_PAYLOAD(header); + for (const struct rtattr* attr = IFLA_RTA(msg); RTA_OK(attr, length); + attr = RTA_NEXT(attr, length)) { + if (attr->rta_type == IFLA_WIRELESS && msg->ifi_change == 0) + return true; + } + return false; +} + // Retrieves address from NETLINK address message. // Sets |really_deprecated| for IPv6 addresses with preferred lifetimes of 0. bool GetAddress(const struct nlmsghdr* header, @@ -355,6 +369,10 @@ void AddressTrackerLinux::HandleMessage(char* buffer, reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header)); if (IsInterfaceIgnored(msg->ifi_index)) break; + if (IgnoreWirelessChange(header, msg)) { + VLOG(2) << "Ignoring RTM_NEWLINK message"; + break; + } if (!(msg->ifi_flags & IFF_LOOPBACK) && (msg->ifi_flags & IFF_UP) && (msg->ifi_flags & IFF_LOWER_UP) && (msg->ifi_flags & IFF_RUNNING)) { AddressTrackerAutoLock lock(*this, online_links_lock_); diff --git a/net/base/address_tracker_linux_unittest.cc b/net/base/address_tracker_linux_unittest.cc index ad81517..694c091 100644 --- a/net/base/address_tracker_linux_unittest.cc +++ b/net/base/address_tracker_linux_unittest.cc @@ -21,6 +21,7 @@ namespace internal { namespace { const int kTestInterfaceEth = 1; +const int kTestInterfaceWifi = 2; const int kTestInterfaceTun = 123; const int kTestInterfaceAp = 456; @@ -212,6 +213,24 @@ void MakeLinkMessage(uint16_t type, nlmsg.AppendTo(output); } +// Creates a netlink message generated by wireless_send_event. These events +// should be ignored. +void MakeWirelessLinkMessage(uint16_t type, + uint32_t flags, + uint32_t index, + Buffer* output) { + NetlinkMessage nlmsg(type); + struct ifinfomsg msg = {}; + msg.ifi_index = index; + msg.ifi_flags = flags; + msg.ifi_change = 0; + nlmsg.AddPayload(&msg, sizeof(msg)); + char data[8] = {0}; + nlmsg.AddAttribute(IFLA_WIRELESS, data, sizeof(data)); + output->clear(); + nlmsg.AppendTo(output); +} + const unsigned char kAddress0[] = { 127, 0, 0, 1 }; const unsigned char kAddress1[] = { 10, 0, 0, 1 }; const unsigned char kAddress2[] = { 192, 168, 0, 1 }; @@ -469,6 +488,13 @@ TEST_F(AddressTrackerLinuxTest, AddInterface) { EXPECT_EQ(1u, GetOnlineLinks().count(kTestInterfaceEth)); EXPECT_EQ(1u, GetOnlineLinks().size()); + // Ignores messages from wireless_send_event. + MakeWirelessLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, + kTestInterfaceWifi, &buffer); + EXPECT_FALSE(HandleLinkMessage(buffer)); + EXPECT_EQ(0u, GetOnlineLinks().count(kTestInterfaceWifi)); + EXPECT_EQ(1u, GetOnlineLinks().size()); + // Verify adding another online device (e.g. VPN) is considered a change. MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, 2, &buffer); EXPECT_TRUE(HandleLinkMessage(buffer)); @@ -513,6 +539,20 @@ TEST_F(AddressTrackerLinuxTest, RemoveInterface) { kTestInterfaceEth, &buffer); EXPECT_TRUE(HandleLinkMessage(buffer)); EXPECT_TRUE(GetOnlineLinks().empty()); + + // Ignores messages from wireless_send_event. + MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP | IFF_RUNNING, + kTestInterfaceWifi, &buffer); + EXPECT_TRUE(HandleLinkMessage(buffer)); + EXPECT_FALSE(GetOnlineLinks().empty()); + MakeWirelessLinkMessage(RTM_NEWLINK, IFF_UP | IFF_LOWER_UP, + kTestInterfaceWifi, &buffer); + EXPECT_FALSE(HandleLinkMessage(buffer)); + EXPECT_FALSE(GetOnlineLinks().empty()); + MakeLinkMessage(RTM_NEWLINK, IFF_UP | IFF_RUNNING, kTestInterfaceWifi, + &buffer); + EXPECT_TRUE(HandleLinkMessage(buffer)); + EXPECT_TRUE(GetOnlineLinks().empty()); } TEST_F(AddressTrackerLinuxTest, IgnoreInterface) { |