[fuchsia/tun] Transition to new tun API

Update Fuchsia tun driver to use new API.

This is CL 2/5 of the network tun multiport transition.

Bug: 75528
Change-Id: I9b5b243da12bdba05ddb33e007e3ecf39c096b30
diff --git a/src/inet/TunEndPoint.cpp b/src/inet/TunEndPoint.cpp
index 42e0e02..358cea5 100644
--- a/src/inet/TunEndPoint.cpp
+++ b/src/inet/TunEndPoint.cpp
@@ -55,40 +55,44 @@
 #if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
 
 constexpr uint32_t kDefaultMtu = 1500;
+constexpr uint8_t kTunPortId = 0;
 
 namespace {
 
-fuchsia::net::tun::BaseConfig DefaultBaseConfig() {
-  fuchsia::net::tun::BaseConfig config;
-  std::vector<fuchsia::hardware::network::FrameType> rxFrameTypes;
-  std::vector<fuchsia::hardware::network::FrameTypeSupport> txFrameTypes;
+fuchsia::net::tun::DevicePortConfig DefaultPortConfig() {
+  fuchsia::net::tun::BasePortConfig base;
+  base.set_id(kTunPortId);
 
   // Add both ipv4 and ipv6 for supported rx frame types.
+  std::vector<fuchsia::hardware::network::FrameType> rxFrameTypes;
   rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV4);
   rxFrameTypes.push_back(fuchsia::hardware::network::FrameType::IPV6);
-  config.set_rx_types(rxFrameTypes);
+  base.set_rx_types(std::move(rxFrameTypes));
 
   // Configure default MTU
-  config.set_mtu(kDefaultMtu);
+  base.set_mtu(kDefaultMtu);
 
   // Add both ipv4 and ipv6 for supported tx frame types.
   // FrameType specifies the type of frame(IPv4/IPv6), features specific to
   // the frametype and the supported flags. We set both to 0, as we don't
   // need any specific features or flags.
+  std::vector<fuchsia::hardware::network::FrameTypeSupport> txFrameTypes;
   txFrameTypes.push_back(fuchsia::hardware::network::FrameTypeSupport{
       fuchsia::hardware::network::FrameType::IPV4, 0,
       static_cast<fuchsia::hardware::network::TxFlags>(0)});
   txFrameTypes.push_back(fuchsia::hardware::network::FrameTypeSupport{
       fuchsia::hardware::network::FrameType::IPV6, 0,
       static_cast<fuchsia::hardware::network::TxFlags>(0)});
-  config.set_tx_types(txFrameTypes);
+  base.set_tx_types(std::move(txFrameTypes));
+
+  fuchsia::net::tun::DevicePortConfig config;
+  config.set_base(std::move(base));
 
   return config;
 }
 
-fuchsia::net::tun::DeviceConfig DefaultDeviceConfig() {
-  fuchsia::net::tun::DeviceConfig config;
-  config.set_base(DefaultBaseConfig());
+fuchsia::net::tun::DeviceConfig2 DefaultDeviceConfig() {
+  fuchsia::net::tun::DeviceConfig2 config;
   config.set_blocking(false);
   return config;
 }
@@ -114,12 +118,21 @@
     WeaveLogError(Inet, "tunctl is not bound");
     return INET_ERROR_INTERFACE_INIT_FAILURE;
   }
-  mTunCtl->CreateDevice(std::move(config), mTunDevice.NewRequest());
+  err = mTunCtl->CreateDevice2(std::move(config), mTunDevice.NewRequest());
+  if(err != ZX_OK) {
+    WeaveLogError(Inet, "tunctl failed to create device: %s", zx_status_get_string(err));
+    return INET_ERROR_INTERFACE_INIT_FAILURE;
+  }
+  err = mTunDevice->AddPort(DefaultPortConfig(), mTunPort.NewRequest());
+  if(err != ZX_OK) {
+    WeaveLogError(Inet, "tunctl failed to add device port: %s", zx_status_get_string(err));
+    return INET_ERROR_INTERFACE_INIT_FAILURE;
+  }
   return INET_NO_ERROR;
 }
 
 // Add the tun interface to netstack. If successful the tun interface shows up in "net if list".
-INET_ERROR TunEndPoint::AddInterfaceToNetstack(fuchsia::hardware::network::DeviceSyncPtr& device, const char *intfName) {
+INET_ERROR TunEndPoint::AddInterfaceToNetstack(fuchsia::hardware::network::DeviceHandle & device, const char *intfName) {
   zx_status_t err;
   fuchsia::net::stack::DeviceDefinition deviceDefinition;
   fuchsia::net::stack::InterfaceConfig config;
@@ -132,14 +145,14 @@
   }
   err = platformData->ctx->svc()->Connect(mStackPtr.NewRequest());
   if (err != ZX_OK) {
-    WeaveLogError(Inet,"connect to stack fidl failed\n");
+    WeaveLogError(Inet,"connect to stack fidl failed");
     return err;
   }
 
   fuchsia::net::stack::Stack_AddInterface_Result result;
   err = mStackPtr->AddInterface(std::move(config), std::move(deviceDefinition), &result);
   if (err != ZX_OK || result.is_err()) {
-    WeaveLogError(Inet,"AddInterface failed %d:%s\n", err, zx_status_get_string(err));
+    WeaveLogError(Inet,"AddInterface failed %d:%s", err, zx_status_get_string(err));
     return err;
   }
 
@@ -148,10 +161,8 @@
 }
 
 INET_ERROR TunEndPoint::CreateHostDevice(const char *intfName) {
-  fuchsia::hardware::network::DeviceSyncPtr device;
-  fuchsia::net::tun::Protocols protos;
-  protos.set_network_device(device.NewRequest());
-  mTunDevice->ConnectProtocols(std::move(protos));
+  fuchsia::hardware::network::DeviceHandle device;
+  mTunDevice->GetDevice(device.NewRequest());
   return AddInterfaceToNetstack(device, intfName);
 }
 
@@ -165,7 +176,7 @@
 
   zx_status_t status = mTunDevice->GetSignals(&events);
   if (status != 0) {
-    WeaveLogError(Inet, "Failed to get signals from Tun: %s\n", zx_status_get_string(status));
+    WeaveLogError(Inet, "Failed to get signals from Tun: %s", zx_status_get_string(status));
     return status;
   }
 
@@ -230,7 +241,7 @@
     err = TunDevOpen(intfName);
     SuccessOrExit(err);
 
-    WeaveLogProgress(Inet, "Opened tunnel device: %s\n", intfName);
+    WeaveLogProgress(Inet, "Opened tunnel device: %s", intfName);
 
 #endif // WEAVE_SYSTEM_CONFIG_USE_SOCKETS
 
@@ -425,9 +436,13 @@
 #endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
 
 #if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
-    // Set tun device to online
+    // Set tun device to online.
     fuchsia::net::stack::Stack_EnableInterface_Result result;
-    mTunDevice->SetOnline(true);
+    err = mTunPort->SetOnline(true);
+    if (err != ZX_OK) {
+      WeaveLogError(Inet, "InterfaceUp failed due to SetOnline error: %s", zx_status_get_string(err));
+      ExitNow();
+    }
     if (!mStackPtr.is_bound()) {
       ExitNow(err = ZX_ERR_BAD_STATE);
     }
@@ -513,15 +528,19 @@
 #if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
     fuchsia::net::stack::Stack_DisableInterface_Result result;
     if (!mStackPtr.is_bound()) {
-      WeaveLogError(Inet, "InterfaceDown failed as mStackPtr is not bound\n");
+      WeaveLogError(Inet, "InterfaceDown failed as mStackPtr is not bound");
       ExitNow(err = ZX_ERR_BAD_STATE);
     }
     // Set offline and disable the interface.
-    mTunDevice->SetOnline(false);
+    err = mTunPort->SetOnline(false);
+    if (err != ZX_OK) {
+      WeaveLogError(Inet, "InterfaceDown failed due to SetOnline error: %s", zx_status_get_string(err));
+      ExitNow();
+    }
 
     err = mStackPtr->DisableInterface(mInterfaceId, &result);
     if (err != ZX_OK) {
-      WeaveLogError(Inet, "DisableInterface failed: %s\n", zx_status_get_string(err));
+      WeaveLogError(Inet, "DisableInterface failed: %s", zx_status_get_string(err));
       return err;
     }
 
@@ -616,7 +635,7 @@
 
     if ((err = tcpip_input(p, &mTunNetIf)) != ERR_OK)
     {
-        LWIP_DEBUGF(NETIF_DEBUG, ("tunNetif_input: IP input error\n"));
+        LWIP_DEBUGF(NETIF_DEBUG, ("tunNetif_input: IP input error"));
         ExitNow(ret = Weave::System::MapErrorLwIP(err));
     }
 
@@ -634,17 +653,18 @@
 
 #if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
     fuchsia::net::tun::Frame frame;
-    fuchsia::net::tun::Device_WriteFrame_Result result;
+    fuchsia::net::tun::Device2_WriteFrame_Result result;
     if (msg == NULL) {
       return INET_ERROR_BAD_ARGS;
     }
     p = msg->Start();
     std::vector<uint8_t> data(p, p + msg->DataLength());
     if (!mTunCtl.is_bound()) {
-      WeaveLogError(Inet, "send failed as tunctl is not bound\n");
+      WeaveLogError(Inet, "send failed as tunctl is not bound");
       return ZX_ERR_BAD_STATE;
     }
 
+    frame.set_port(kTunPortId);
     frame.set_frame_type(fuchsia::hardware::network::FrameType::IPV6);
     frame.set_data(data);
     ret = mTunDevice->WriteFrame(std::move(frame), &result);
@@ -861,13 +881,13 @@
     //Create the tunnel device
     ret = CreateTunDevice();
     if (ret != 0) {
-      WeaveLogError(Inet, "CreateTunDevice failed %d\n", ret);
+      WeaveLogError(Inet, "CreateTunDevice failed %d", ret);
       return ret;
     }
 
     ret = CreateHostDevice(intfName);
     if (ret != 0) {
-      WeaveLogError(Inet, "CreateHostDevice failed %d\n", ret);
+      WeaveLogError(Inet, "CreateHostDevice failed %d", ret);
       return ret;
     }
     return ret;
@@ -933,12 +953,12 @@
   INET_ERROR err = INET_NO_ERROR;
   fuchsia::net::stack::Stack_DelEthernetInterface_Result result;
   if (!mStackPtr.is_bound()) {
-    WeaveLogError(Inet, "TunDevClose failed as mStackPtr is not bound to service\n");
+    WeaveLogError(Inet, "TunDevClose failed as mStackPtr is not bound to service");
     return;
   }
   err = mStackPtr->DelEthernetInterface(mInterfaceId, &result);
   if (err != ZX_OK) {
-    WeaveLogError(Inet, "DelInterface failed %d: %s\n", err, zx_status_get_string(err));
+    WeaveLogError(Inet, "DelInterface failed %d: %s", err, zx_status_get_string(err));
   }
   mInterfaceId = 0;
 #else
@@ -966,9 +986,9 @@
     p = msg->Start();
 
 #ifdef WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
-    fuchsia::net::tun::Device_ReadFrame_Result result;
+    fuchsia::net::tun::Device2_ReadFrame_Result result;
     if (!mTunCtl.is_bound()) {
-      WeaveLogError(Inet, "Can't read as mTunCtl is not bound\n");
+      WeaveLogError(Inet, "Can't read as mTunCtl is not bound");
       ExitNow(err = ZX_ERR_BAD_STATE);
     }
     err = mTunDevice->ReadFrame(&result);
diff --git a/src/inet/TunEndPoint.h b/src/inet/TunEndPoint.h
index f8c0433..f54ce7a 100644
--- a/src/inet/TunEndPoint.h
+++ b/src/inet/TunEndPoint.h
@@ -205,7 +205,8 @@
 
 #if WEAVE_SYSTEM_CONFIG_USE_FUCHSIA_TUN
     fuchsia::net::tun::ControlSyncPtr mTunCtl;
-    fuchsia::net::tun::DeviceSyncPtr mTunDevice;
+    fuchsia::net::tun::Device2SyncPtr mTunDevice;
+    fuchsia::net::tun::PortSyncPtr mTunPort;
     fuchsia::net::stack::StackSyncPtr mStackPtr;
     uint64_t mInterfaceId;
 
@@ -216,11 +217,11 @@
      *  Add the tun interface to netstack, so that the
      *  tun endpoint can send/receive frames.
      *
-     * @param[in] device       pointer to host end of tun device.
+     * @param[in] device       handle to host end of tun device.
      * @param[in] intfName     interface name provided by WeaveTunnelAgent, defaults to TUN_DEFAULT_INTF_NAME.
      * @return                 INET_OK on success and INET_ERROR on failure.
      */
-    INET_ERROR AddInterfaceToNetstack(fuchsia::hardware::network::DeviceSyncPtr& device, const char *intfName);
+    INET_ERROR AddInterfaceToNetstack(fuchsia::hardware::network::DeviceHandle& device, const char *intfName);
 
     /**
      * @brief   Create tun device.