Configure gateway for QBONE routes when adding/updating routes. This simplifies neighbor discovery for TAP devices, now only needing to respond to solicitations for the device's link-local gateway address. PiperOrigin-RevId: 398333869
diff --git a/quic/qbone/bonnet/tun_device_packet_exchanger.cc b/quic/qbone/bonnet/tun_device_packet_exchanger.cc index ecb4f5d..3381cd2 100644 --- a/quic/qbone/bonnet/tun_device_packet_exchanger.cc +++ b/quic/qbone/bonnet/tun_device_packet_exchanger.cc
@@ -12,6 +12,7 @@ #include "absl/strings/str_cat.h" #include "quic/qbone/platform/icmp_packet.h" #include "quic/qbone/platform/netlink_interface.h" +#include "quic/qbone/qbone_constants.h" namespace quic { @@ -167,6 +168,13 @@ // respond with and write it back to the local interface. auto* icmp6_payload = l2_packet.data() + kIcmp6PrefixLen; + QuicIpAddress target_address( + *reinterpret_cast<const in6_addr*>(icmp6_payload)); + if (target_address != *QboneConstants::GatewayAddress()) { + // Only respond to solicitations for our gateway address + return nullptr; + } + // Neighbor Advertisement crafted per: // https://datatracker.ietf.org/doc/html/rfc4861#section-4.4 //
diff --git a/quic/qbone/platform/netlink.cc b/quic/qbone/platform/netlink.cc index 985632a..2f4bbe2 100644 --- a/quic/qbone/platform/netlink.cc +++ b/quic/qbone/platform/netlink.cc
@@ -5,6 +5,7 @@ #include "quic/qbone/platform/netlink.h" #include <linux/fib_rules.h> + #include <utility> #include "absl/base/attributes.h" @@ -13,6 +14,7 @@ #include "quic/platform/api/quic_ip_address.h" #include "quic/platform/api/quic_logging.h" #include "quic/qbone/platform/rtnetlink_message.h" +#include "quic/qbone/qbone_constants.h" namespace quic { @@ -570,10 +572,17 @@ // This is the source address to use in the IP packet should this routing rule // is used. if (preferred_source.IsInitialized()) { + auto src_str = preferred_source.ToPackedString(); message.AppendAttribute(RTA_PREFSRC, - reinterpret_cast<const void*>( - preferred_source.ToPackedString().c_str()), - preferred_source.ToPackedString().size()); + reinterpret_cast<const void*>(src_str.c_str()), + src_str.size()); + } + + if (verb != Verb::kRemove) { + auto gateway_str = QboneConstants::GatewayAddress()->ToPackedString(); + message.AppendAttribute(RTA_GATEWAY, + reinterpret_cast<const void*>(gateway_str.c_str()), + gateway_str.size()); } if (!Send(message.BuildIoVec().get(), message.IoVecSize())) {
diff --git a/quic/qbone/platform/netlink_test.cc b/quic/qbone/platform/netlink_test.cc index 16d2a19..f6fe7cd 100644 --- a/quic/qbone/platform/netlink_test.cc +++ b/quic/qbone/platform/netlink_test.cc
@@ -564,6 +564,15 @@ EXPECT_EQ(preferred_ip, address); break; } + case RTA_GATEWAY: { + const auto* raw_address = + reinterpret_cast<const char*>(RTA_DATA(rta)); + ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta)); + QuicIpAddress address; + address.FromPackedString(raw_address, RTA_PAYLOAD(rta)); + EXPECT_EQ(*QboneConstants::GatewayAddress(), address); + break; + } case RTA_OIF: { ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta)); const auto* interface_index = @@ -591,7 +600,7 @@ } ++num_rta; } - EXPECT_EQ(4, num_rta); + EXPECT_EQ(5, num_rta); }); EXPECT_TRUE(netlink->ChangeRoute( Netlink::Verb::kAdd, QboneConstants::kQboneRouteTableId, subnet, @@ -728,6 +737,15 @@ EXPECT_EQ(preferred_ip, address); break; } + case RTA_GATEWAY: { + const auto* raw_address = + reinterpret_cast<const char*>(RTA_DATA(rta)); + ASSERT_EQ(sizeof(struct in6_addr), RTA_PAYLOAD(rta)); + QuicIpAddress address; + address.FromPackedString(raw_address, RTA_PAYLOAD(rta)); + EXPECT_EQ(*QboneConstants::GatewayAddress(), address); + break; + } case RTA_OIF: { ASSERT_EQ(sizeof(int), RTA_PAYLOAD(rta)); const auto* interface_index = @@ -755,7 +773,7 @@ } ++num_rta; } - EXPECT_EQ(4, num_rta); + EXPECT_EQ(5, num_rta); }); EXPECT_TRUE(netlink->ChangeRoute( Netlink::Verb::kReplace, QboneConstants::kQboneRouteTableId, subnet,
diff --git a/quic/qbone/qbone_constants.cc b/quic/qbone/qbone_constants.cc index fb92af7..f54ebc3 100644 --- a/quic/qbone/qbone_constants.cc +++ b/quic/qbone/qbone_constants.cc
@@ -19,7 +19,7 @@ const QuicIpAddress* QboneConstants::TerminatorLocalAddress() { static auto* terminator_address = []() { - QuicIpAddress* address = new QuicIpAddress; + auto* address = new QuicIpAddress; // 0x71 0x62 0x6f 0x6e 0x65 is 'qbone' in ascii. address->FromString("fe80::71:626f:6e65"); return address; @@ -33,4 +33,13 @@ return range; } +const QuicIpAddress* QboneConstants::GatewayAddress() { + static auto* gateway_address = []() { + auto* address = new QuicIpAddress; + address->FromString("fe80::1"); + return address; + }(); + return gateway_address; +} + } // namespace quic
diff --git a/quic/qbone/qbone_constants.h b/quic/qbone/qbone_constants.h index 8053013..141bb6c 100644 --- a/quic/qbone/qbone_constants.h +++ b/quic/qbone/qbone_constants.h
@@ -25,6 +25,9 @@ static const QuicIpAddress* TerminatorLocalAddress(); // The IPRange containing the TerminatorLocalAddress static const IpRange* TerminatorLocalAddressRange(); + // The gateway address to provide when configuring routes to the QBONE + // interface + static const QuicIpAddress* GatewayAddress(); }; } // namespace quic