Skeleton for IVmTethering service
Bug: 340376953
Test: adb shell /apex/com.android.virt/bin/vm run-microdroid --network-supported
Change-Id: Idab701f3c684e62629bfe02b7a6ad7904d311f14
diff --git a/java/service/Android.bp b/java/service/Android.bp
index 8bac7be..814445c 100644
--- a/java/service/Android.bp
+++ b/java/service/Android.bp
@@ -31,6 +31,7 @@
],
static_libs: [
"android.system.virtualizationmaintenance-java",
+ "android.system.vmtethering-java",
],
sdk_version: "core_platform",
apex_available: ["com.android.virt"],
diff --git a/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java b/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java
index 2461755..4903b1c 100644
--- a/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java
+++ b/java/service/src/com/android/system/virtualmachine/VirtualizationSystemService.java
@@ -26,6 +26,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.system.virtualizationmaintenance.IVirtualizationMaintenance;
+import android.system.vmtethering.IVmTethering;
import android.util.Log;
import com.android.internal.os.BackgroundThread;
@@ -40,17 +41,19 @@
*/
public class VirtualizationSystemService extends SystemService {
private static final String TAG = VirtualizationSystemService.class.getName();
- private static final String SERVICE_NAME = "android.system.virtualizationmaintenance";
+ private static final String MAINTENANCE_SERVICE_NAME =
+ "android.system.virtualizationmaintenance";
private Handler mHandler;
+ private final TetheringService mTetheringService;
public VirtualizationSystemService(Context context) {
super(context);
+ mTetheringService = new TetheringService();
}
@Override
public void onStart() {
- // Nothing needed here - we don't expose any binder service. The binder service we use is
- // exposed as a lazy service by the virtualizationservice native binary.
+ publishBinderService(IVmTethering.DESCRIPTOR, mTetheringService);
}
@Override
@@ -82,11 +85,11 @@
}
static IVirtualizationMaintenance connectToMaintenanceService() {
- IBinder binder = ServiceManager.waitForService(SERVICE_NAME);
+ IBinder binder = ServiceManager.waitForService(MAINTENANCE_SERVICE_NAME);
IVirtualizationMaintenance maintenance =
IVirtualizationMaintenance.Stub.asInterface(binder);
if (maintenance == null) {
- throw new IllegalStateException("Failed to connect to " + SERVICE_NAME);
+ throw new IllegalStateException("Failed to connect to " + MAINTENANCE_SERVICE_NAME);
}
return maintenance;
}
@@ -136,4 +139,11 @@
}
}
}
+
+ private static final class TetheringService extends IVmTethering.Stub {
+ @Override
+ public void enableVmTethering() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("VM tethering is not supported yet");
+ }
+ }
}
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index 0c39501..f9034af 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -30,6 +30,7 @@
"android.system.virtualizationservice-rust",
"android.system.virtualizationservice_internal-rust",
"android.system.virtualmachineservice-rust",
+ "android.system.vmtethering-rust",
"android.os.permissions_aidl-rust",
"libandroid_logger",
"libanyhow",
diff --git a/virtualizationservice/aidl/Android.bp b/virtualizationservice/aidl/Android.bp
index fb89772..bca4512 100644
--- a/virtualizationservice/aidl/Android.bp
+++ b/virtualizationservice/aidl/Android.bp
@@ -86,6 +86,26 @@
}
aidl_interface {
+ name: "android.system.vmtethering",
+ srcs: ["android/system/vmtethering/**/*.aidl"],
+ unstable: true,
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
+ rust: {
+ enabled: true,
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
+ },
+}
+
+aidl_interface {
name: "android.system.virtualmachineservice",
srcs: ["android/system/virtualmachineservice/**/*.aidl"],
imports: [
diff --git a/virtualizationservice/aidl/android/system/vmtethering/IVmTethering.aidl b/virtualizationservice/aidl/android/system/vmtethering/IVmTethering.aidl
new file mode 100644
index 0000000..732a515
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/vmtethering/IVmTethering.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.vmtethering;
+
+interface IVmTethering {
+ /**
+ * Start VM tethering to provide external network to VM.
+ */
+ void enableVmTethering();
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 241baa5..833c535 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -25,6 +25,7 @@
use android_system_virtualizationservice::aidl::android::system::virtualizationservice;
use android_system_virtualizationservice_internal as android_vs_internal;
use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice;
+use android_system_vmtethering::aidl::android::system::vmtethering;
use android_vs_internal::aidl::android::system::virtualizationservice_internal;
use anyhow::{anyhow, ensure, Context, Result};
use avflog::LogResult;
@@ -73,6 +74,7 @@
IVmnic::{BpVmnic, IVmnic},
};
use virtualmachineservice::IVirtualMachineService::VM_TOMBSTONES_SERVICE_PORT;
+use vmtethering::IVmTethering::{BpVmTethering, IVmTethering};
use vsock::{VsockListener, VsockStream};
/// The unique ID of a VM used (together with a port number) for vsock communication.
@@ -163,6 +165,9 @@
static ref NETWORK_SERVICE: Strong<dyn IVmnic> =
wait_for_interface(<BpVmnic as IVmnic>::get_descriptor())
.expect("Could not connect to Vmnic");
+ static ref TETHERING_SERVICE: Strong<dyn IVmTethering> =
+ wait_for_interface(<BpVmTethering as IVmTethering>::get_descriptor())
+ .expect("Could not connect to VmTethering");
}
fn is_valid_guest_cid(cid: Cid) -> bool {
@@ -519,7 +524,19 @@
))
.with_log();
}
- NETWORK_SERVICE.createTapInterface(iface_name_suffix)
+ let tap_fd = NETWORK_SERVICE.createTapInterface(iface_name_suffix)?;
+
+ // TODO(340377643): Enabling tethering should be for bridge interface, not TAP interface.
+ let ret = TETHERING_SERVICE.enableVmTethering();
+ if let Err(e) = ret {
+ if e.exception_code() == ExceptionCode::UNSUPPORTED_OPERATION {
+ warn!("{}", e.get_description());
+ } else {
+ return Err(e);
+ }
+ }
+
+ Ok(tap_fd)
}
fn deleteTapInterface(&self, tap_fd: &ParcelFileDescriptor) -> binder::Result<()> {