patchpanel: ndproxy: assign public v6 addr to guest-facing ifs
Currently there is no public IPv6 address assigned on the
guest-facing interfaces (arc bridges and taps) when device is on
IPv6 network. This is causing Linux choosing a wrong src address
on packets directly originated from host to guest and drop the
returning traffic.
This patch generates an EUI-64 address based on virtual interface
MAC address upon receiving an RA, and add it to the interface.
BUG=chromium:1069985
TEST=unit;fuzz
TEST=manual(deploy on octopus and verify pinging penguin from host)
Change-Id: Id3ae953df6b3c84411461294bbc8dbd236cef901
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2428652
Tested-by: Taoyu Li <taoyl@chromium.org>
Reviewed-by: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
Commit-Queue: Taoyu Li <taoyl@chromium.org>
diff --git a/patchpanel/net_util.cc b/patchpanel/net_util.cc
index a5a2a60..2fd9e28 100644
--- a/patchpanel/net_util.cc
+++ b/patchpanel/net_util.cc
@@ -121,6 +121,20 @@
return true;
}
+bool GenerateEUI64Address(in6_addr* address,
+ const in6_addr& prefix,
+ const MacAddress& mac) {
+ // RFC 4291, Appendix A: Insert 0xFF and 0xFE to form EUI-64, then flip
+ // universal/local bit
+ memcpy(address, &prefix, sizeof(in6_addr));
+ memcpy(&(address->s6_addr[8]), &(mac[0]), 3);
+ memcpy(&(address->s6_addr[13]), &(mac[3]), 3);
+ address->s6_addr[11] = 0xff;
+ address->s6_addr[12] = 0xfe;
+ address->s6_addr[8] ^= 0x2;
+ return true;
+}
+
void SetSockaddrIn(struct sockaddr* sockaddr, uint32_t addr) {
struct sockaddr_in* sockaddr_in =
reinterpret_cast<struct sockaddr_in*>(sockaddr);