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_test.cc b/patchpanel/net_util_test.cc
index 938fac6..10d03da 100644
--- a/patchpanel/net_util_test.cc
+++ b/patchpanel/net_util_test.cc
@@ -150,6 +150,29 @@
   EXPECT_EQ(ori_cksum, Icmpv6Checksum(ip6, icmp6));
 }
 
+TEST(Ipv6, EUI64Addr) {
+  struct {
+    std::string prefix;
+    MacAddress mac_address;
+    std::string eui64_address;
+  } test_cases[] = {{"::", {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, "::200:ff:fe00:0"},
+                    {"2001:da8:ff:5002::",
+                     {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc},
+                     "2001:da8:ff:5002:1034:56ff:fe78:9abc"},
+                    {"fe80::",
+                     {0xf4, 0x99, 0x9f, 0xf4, 0x4f, 0xe4},
+                     "fe80::f699:9fff:fef4:4fe4"}};
+  in6_addr prefix;
+  in6_addr addr;
+  for (auto const& test_case : test_cases) {
+    inet_pton(AF_INET6, test_case.prefix.c_str(), &prefix);
+    GenerateEUI64Address(&addr, prefix, test_case.mac_address);
+    char eui64_addr_str[INET6_ADDRSTRLEN];
+    inet_ntop(AF_INET6, &addr, eui64_addr_str, INET6_ADDRSTRLEN);
+    EXPECT_EQ(test_case.eui64_address, eui64_addr_str);
+  }
+}
+
 TEST(Ipv4, BroadcastAddr) {
   uint32_t base = Ipv4Addr(100, 115, 92, 0);
   struct {