summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorderekjchow <derekjchow@chromium.org>2015-06-19 19:59:43 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-20 03:00:24 +0000
commit72407efac2875e2713b7f730eb998ab30f2005d5 (patch)
tree4ad6d0f3ad9cb1ff621ad5bd84f5f5b9a35f96b1 /net
parent9d193b1cfe7fed9f5e73dc6ad4e7623671762ea4 (diff)
downloadchromium_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.cc18
-rw-r--r--net/base/address_tracker_linux_unittest.cc40
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) {