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