shill: vpn: Create a IPv6 blackhole route for IPv4 L2TP/IPsec VPN.

BUG=chromium-os:34383
TEST=Tested the following:
1. Build and run unit tests.
2. Manually test IPv4 LT2P/IPsec VPN on an network interface with IPv4
   and IPv6 addresses as follows:
   - Before connecting to the VPN, run `ip -6 route` to verify that no
     blackhole route exists. Confirm via http://ipv6test.google.com that
     IPv6 connectivity is available.
   - After connecting to the VPN, run `ip -6 route` to verify that the
     blackhole route is installed. Confirm via
     http://ipv6test.google.com that IPv6 connectivity is not available.
   - After disconnecting from the VPN, run `ip -6 route` to verify that
     no blackhole route exists. Confirm via http://ipv6test.google.com
     that IPv6 connectivity is available.

Change-Id: I7ae4fab5319b5f06a6a3f5a28f439551f2825044
Reviewed-on: https://gerrit.chromium.org/gerrit/34053
Commit-Ready: Ben Chan <benchan@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/routing_table_unittest.cc b/routing_table_unittest.cc
index 52c105e..d78555b 100644
--- a/routing_table_unittest.cc
+++ b/routing_table_unittest.cc
@@ -157,6 +157,29 @@
 
 namespace {
 
+MATCHER_P3(IsBlackholeRoutingPacket, index, family, metric, "") {
+  const RTNLMessage::RouteStatus &status = arg->route_status();
+
+  uint32 oif;
+  uint32 priority;
+
+  return
+      arg->type() == RTNLMessage::kTypeRoute &&
+      arg->family() == family &&
+      arg->flags() == (NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL) &&
+      status.table == RT_TABLE_MAIN &&
+      status.protocol == RTPROT_BOOT &&
+      status.scope == RT_SCOPE_UNIVERSE &&
+      status.type == RTN_BLACKHOLE &&
+      !arg->HasAttribute(RTA_DST) &&
+      !arg->HasAttribute(RTA_SRC) &&
+      !arg->HasAttribute(RTA_GATEWAY) &&
+      arg->GetAttribute(RTA_OIF).ConvertToCPUUInt32(&oif) &&
+      oif == index &&
+      arg->GetAttribute(RTA_PRIORITY).ConvertToCPUUInt32(&priority) &&
+      priority == metric;
+}
+
 MATCHER_P4(IsRoutingPacket, mode, index, entry, flags, "") {
   const RTNLMessage::RouteStatus &status = arg->route_status();
 
@@ -773,6 +796,18 @@
                                 RTPROT_UNSPEC);
 }
 
+TEST_F(RoutingTableTest, CreateBlackholeRoute) {
+  const uint32 kMetric = 2;
+  EXPECT_CALL(rtnl_handler_,
+              SendMessage(IsBlackholeRoutingPacket(kTestDeviceIndex0,
+                                                   IPAddress::kFamilyIPv6,
+                                                   kMetric)))
+      .Times(1);
+  EXPECT_TRUE(routing_table_->CreateBlackholeRoute(kTestDeviceIndex0,
+                                                   IPAddress::kFamilyIPv6,
+                                                   kMetric));
+}
+
 TEST_F(RoutingTableTest, CreateLinkRoute) {
   IPAddress local_address(IPAddress::kFamilyIPv4);
   ASSERT_TRUE(local_address.SetAddressFromString(kTestNetAddress0));