diff --git a/service/Android.bp b/service/Android.bp
index c4e2ef0..8b469e4 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -161,6 +161,7 @@
     ],
     libs: [
         "framework-annotations-lib",
+        "framework-bluetooth.stubs.module_lib",
         "framework-configinfrastructure.stubs.module_lib",
         "framework-connectivity-pre-jarjar",
         // The framework-connectivity-t library is only available on T+ platforms
diff --git a/service/src/com/android/server/net/L2capPacketForwarder.java b/service/src/com/android/server/net/L2capPacketForwarder.java
new file mode 100644
index 0000000..cef351c
--- /dev/null
+++ b/service/src/com/android/server/net/L2capPacketForwarder.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2025 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 com.android.server.net;
+
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Forwards packets from a BluetoothSocket of type L2CAP to a tun fd and vice versa.
+ *
+ * The forwarding logic operates on raw IP packets and there are no ethernet headers.
+ * Therefore, L3 MTU = L2 MTU.
+ */
+public class L2capPacketForwarder {
+    private static final String TAG = "L2capPacketForwarder";
+
+    // DCT specifies an MTU of 1500.
+    // TODO: Set /proc/sys/net/ipv6/conf/${iface}/mtu to 1280 and the link MTU to 1528 to accept
+    // slightly larger packets on ingress (i.e. packets passing through a NAT64 gateway).
+    // MTU determines the value of the read buffers, so use the larger of the two.
+    @VisibleForTesting
+    public static final int MTU = 1528;
+    private final Handler mHandler;
+    private final IReadWriteFd mTunFd;
+    private final IReadWriteFd mL2capFd;
+    private final L2capThread mIngressThread;
+    private final L2capThread mEgressThread;
+    private final ICallback mCallback;
+
+    public interface ICallback {
+        /** Called when an error is encountered; should tear down forwarding. */
+        void onError();
+    }
+
+    private interface IReadWriteFd {
+        /**
+         * Read up to len bytes into bytes[off] and return bytes actually read.
+         *
+         * bytes[] must be of size >= off + len.
+         */
+        int read(byte[] bytes, int off, int len) throws IOException;
+        /**
+         * Write len bytes starting from bytes[off]
+         *
+         * bytes[] must be of size >= off + len.
+         */
+        void write(byte[] bytes, int off, int len) throws IOException;
+        /** Disallow further receptions, shutdown(fd, SHUT_RD) */
+        void shutdownRead();
+        /** Disallow further transmissions, shutdown(fd, SHUT_WR) */
+        void shutdownWrite();
+        /** Close the fd */
+        void close();
+    }
+
+    @VisibleForTesting
+    public static class BluetoothSocketWrapper implements IReadWriteFd {
+        private final BluetoothSocket mSocket;
+        private final InputStream mInputStream;
+        private final OutputStream mOutputStream;
+
+        public BluetoothSocketWrapper(BluetoothSocket socket) {
+            // TODO: assert that MTU can fit within Bluetooth L2CAP SDU (maximum size of an L2CAP
+            // packet). The L2CAP SDU is 65535 by default, but can be less when using hardware
+            // offload.
+            mSocket = socket;
+            try {
+                mInputStream = socket.getInputStream();
+                mOutputStream = socket.getOutputStream();
+            } catch (IOException e) {
+                // Per the API docs, this should not actually be possible.
+                Log.wtf(TAG, "Failed to get Input/OutputStream", e);
+                // Fail hard.
+                throw new IllegalStateException("Failed to get Input/OutputStream");
+            }
+        }
+
+        /** Read from the BluetoothSocket. */
+        @Override
+        public int read(byte[] bytes, int off, int len) throws IOException {
+            // Note: EINTR is handled internally and automatically triggers a retry loop.
+            int bytesRead = mInputStream.read(bytes, off, len);
+            if (bytesRead > MTU) {
+                // Don't try to recover, just trigger network teardown. This might indicate a bug in
+                // the Bluetooth stack.
+                throw new IOException("Packet exceeds MTU");
+            }
+            return bytesRead;
+        }
+
+        /** Write to the BluetoothSocket. */
+        @Override
+        public void write(byte[] bytes, int off, int len) throws IOException {
+            // Note: EINTR is handled internally and automatically triggers a retry loop.
+            mOutputStream.write(bytes, off, len);
+        }
+
+        @Override
+        public void shutdownRead() {
+            // BluetoothSocket does not expose methods to shutdown read / write individually;
+            // however, BluetoothSocket#close() shuts down both read and write and is safe to be
+            // called multiple times from any thread.
+            try {
+                mSocket.close();
+            } catch (IOException e) {
+                Log.w(TAG, "shutdownRead: Failed to close BluetoothSocket", e);
+            }
+        }
+
+        @Override
+        public void shutdownWrite() {
+            // BluetoothSocket does not expose methods to shutdown read / write individually;
+            // however, BluetoothSocket#close() shuts down both read and write and is safe to be
+            // called multiple times from any thread.
+            try {
+                mSocket.close();
+            } catch (IOException e) {
+                Log.w(TAG, "shutdownWrite: Failed to close BluetoothSocket", e);
+            }
+        }
+
+        @Override
+        public void close() {
+            // BluetoothSocket#close() is safe to be called multiple times.
+            try {
+                mSocket.close();
+            } catch (IOException e) {
+                Log.w(TAG, "close: Failed to close BluetoothSocket", e);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    public static class FdWrapper implements IReadWriteFd {
+        private final ParcelFileDescriptor mFd;
+
+        public FdWrapper(ParcelFileDescriptor fd) {
+            mFd = fd;
+        }
+
+        @Override
+        public int read(byte[] bytes, int off, int len) throws IOException {
+            try {
+                // Note: EINTR is handled internally and automatically triggers a retry loop.
+                return Os.read(mFd.getFileDescriptor(), bytes, off, len);
+            } catch (ErrnoException e) {
+                throw new IOException(e);
+            }
+        }
+
+        /**
+         * Write to BluetoothSocket.
+         */
+        @Override
+        public void write(byte[] bytes, int off, int len) throws IOException {
+            try {
+                // Note: EINTR is handled internally and automatically triggers a retry loop.
+                Os.write(mFd.getFileDescriptor(), bytes, off, len);
+            } catch (ErrnoException e) {
+                throw new IOException(e);
+            }
+        }
+
+        @Override
+        public void shutdownRead() {
+            try {
+                Os.shutdown(mFd.getFileDescriptor(), OsConstants.SHUT_RD);
+            } catch (ErrnoException e) {
+                Log.w(TAG, "shutdownRead: Failed to shutdown(fd, SHUT_RD)", e);
+            }
+        }
+
+        @Override
+        public void shutdownWrite() {
+            try {
+                Os.shutdown(mFd.getFileDescriptor(), OsConstants.SHUT_WR);
+            } catch (ErrnoException e) {
+                Log.w(TAG, "shutdownWrite: Failed to shutdown(fd, SHUT_WR)", e);
+            }
+        }
+
+        @Override
+        public void close() {
+            try {
+                // Safe to call multiple times. Both Os.close(FileDescriptor) and
+                // ParcelFileDescriptor#close() offer protection against double-closing an fd.
+                mFd.close();
+            } catch (IOException e) {
+                Log.w(TAG, "close: Failed to close fd", e);
+            }
+        }
+    }
+
+    private class L2capThread extends Thread {
+        // Set mBuffer length to MTU + 1 to catch read() overflows.
+        private final byte[] mBuffer = new byte[MTU + 1];
+        private volatile boolean mIsRunning = true;
+
+        private final String mLogTag;
+        private IReadWriteFd mReadFd;
+        private IReadWriteFd mWriteFd;
+
+        L2capThread(String logTag, IReadWriteFd readFd, IReadWriteFd writeFd) {
+            mLogTag = logTag;
+            mReadFd = readFd;
+            mWriteFd = writeFd;
+        }
+
+        private void postOnError() {
+            mHandler.post(() -> {
+                // All callbacks must be called on handler thread.
+                mCallback.onError();
+            });
+        }
+
+        @Override
+        public void run() {
+            while (mIsRunning) {
+                try {
+                    final int readBytes = mReadFd.read(mBuffer, 0 /*off*/, mBuffer.length);
+                    // No bytes to write, continue.
+                    if (readBytes <= 0) {
+                        Log.w(mLogTag, "Zero-byte read encountered: " + readBytes);
+                        continue;
+                    }
+
+                    // If the packet exceeds MTU, drop it.
+                    // Note that a large read on BluetoothSocket throws an IOException to tear down
+                    // the network.
+                    if (readBytes > MTU) continue;
+
+                    mWriteFd.write(mBuffer, 0 /*off*/, readBytes);
+                } catch (IOException e) {
+                    Log.e(mLogTag, "L2capThread exception", e);
+                    // Tear down the network on any error.
+                    mIsRunning = false;
+                    // Notify provider that forwarding has stopped.
+                    postOnError();
+                }
+            }
+        }
+
+        public void tearDown() {
+            mIsRunning = false;
+            mReadFd.shutdownRead();
+            mWriteFd.shutdownWrite();
+        }
+    }
+
+    public L2capPacketForwarder(Handler handler, ParcelFileDescriptor tunFd, BluetoothSocket socket,
+            ICallback cb) {
+        this(handler, new FdWrapper(tunFd), new BluetoothSocketWrapper(socket), cb);
+    }
+
+    @VisibleForTesting
+    L2capPacketForwarder(Handler handler, IReadWriteFd tunFd, IReadWriteFd l2capFd, ICallback cb) {
+        mHandler = handler;
+        mTunFd = tunFd;
+        mL2capFd = l2capFd;
+        mCallback = cb;
+
+        mIngressThread = new L2capThread("L2capThread-Ingress", l2capFd, tunFd);
+        mEgressThread = new L2capThread("L2capThread-Egress", tunFd, l2capFd);
+
+        mIngressThread.start();
+        mEgressThread.start();
+    }
+
+    /**
+     * Tear down the L2capPacketForwarder.
+     *
+     * This operation closes both the passed tun fd and BluetoothSocket.
+     **/
+    public void tearDown() {
+        // Destroying both threads first guarantees that both read and write side of FD have been
+        // shutdown.
+        mIngressThread.tearDown();
+        mEgressThread.tearDown();
+
+        // In order to interrupt a blocking read on the BluetoothSocket, the BluetoothSocket must be
+        // closed (which triggers shutdown()). This means, the BluetoothSocket must be closed inside
+        // L2capPacketForwarder. Tear down the tun fd alongside it for consistency.
+        mTunFd.close();
+        mL2capFd.close();
+
+        try {
+            mIngressThread.join();
+        } catch (InterruptedException e) {
+            // join() interrupted in tearDown path, do nothing.
+        }
+        try {
+            mEgressThread.join();
+        } catch (InterruptedException e) {
+            // join() interrupted in tearDown path, do nothing.
+        }
+    }
+}
diff --git a/tests/unit/java/com/android/server/net/L2capPacketForwarderTest.kt b/tests/unit/java/com/android/server/net/L2capPacketForwarderTest.kt
new file mode 100644
index 0000000..b3095ee
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/L2capPacketForwarderTest.kt
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2025 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 com.android.server.net
+
+import android.bluetooth.BluetoothSocket
+import android.os.Build
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.ParcelFileDescriptor
+import android.system.Os
+import android.system.OsConstants.AF_UNIX
+import android.system.OsConstants.SHUT_RD
+import android.system.OsConstants.SHUT_WR
+import android.system.OsConstants.SOCK_SEQPACKET
+import android.system.OsConstants.SOL_SOCKET
+import android.system.OsConstants.SO_RCVTIMEO
+import android.system.OsConstants.SO_SNDTIMEO
+import android.system.StructTimeval
+import com.android.server.net.L2capPacketForwarder.BluetoothSocketWrapper
+import com.android.server.net.L2capPacketForwarder.FdWrapper
+import com.android.testutils.ConnectivityModuleTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import com.google.common.truth.Truth.assertThat
+import java.io.FileDescriptor
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+import java.nio.ByteBuffer
+import kotlin.arrayOf
+import kotlin.random.Random
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.timeout
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+private const val TIMEOUT = 1000L
+
+@ConnectivityModuleTest
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+class L2capPacketForwarderTest {
+    private lateinit var forwarder: L2capPacketForwarder
+    private val tunFds = arrayOf(FileDescriptor(), FileDescriptor())
+    private val l2capFds = arrayOf(FileDescriptor(), FileDescriptor())
+    private lateinit var l2capInputStream: BluetoothL2capInputStream
+    private lateinit var l2capOutputStream: BluetoothL2capOutputStream
+    @Mock private lateinit var bluetoothSocket: BluetoothSocket
+    @Mock private lateinit var callback: L2capPacketForwarder.ICallback
+
+    private val handlerThread = HandlerThread("L2capPacketForwarderTest thread").apply { start() }
+    private val handler = Handler(handlerThread.looper)
+
+    /** Imitates the behavior of an L2CAP BluetoothSocket */
+    private class BluetoothL2capInputStream(
+        val fd: FileDescriptor,
+    ) : InputStream() {
+        val l2capBuffer = ByteBuffer.wrap(ByteArray(0xffff)).apply {
+            limit(0)
+        }
+
+        override fun read(): Int {
+            throw NotImplementedError("b/391623333: not implemented correctly for L2cap sockets")
+        }
+
+        /** See BluetoothSocket#read(buf, off, len) */
+        override fun read(b: ByteArray, off: Int, len: Int): Int {
+            // If no more bytes are remaining, read from the fd into the intermediate buffer.
+            if (l2capBuffer.remaining() == 0) {
+                // fillL2capRxBuffer()
+                // refill buffer and return - 1
+                val backingArray = l2capBuffer.array()
+                var bytesRead = 0
+                try {
+                    bytesRead = Os.read(fd, backingArray, 0 /*off*/, backingArray.size)
+                } catch (e: Exception) {
+                    // read failed, timed out, or was interrupted
+                    // InputStream throws IOException
+                    throw IOException(e)
+                }
+                l2capBuffer.rewind()
+                l2capBuffer.limit(bytesRead)
+            }
+
+            val bytesToRead = if (len > l2capBuffer.remaining()) l2capBuffer.remaining() else len
+            l2capBuffer.get(b, off, bytesToRead)
+            return bytesToRead
+        }
+
+        override fun available(): Int {
+            throw NotImplementedError("b/391623333: not implemented correctly for L2cap sockets")
+        }
+
+        override fun close() {
+            try {
+                Os.shutdown(fd, SHUT_RD)
+            } catch (e: Exception) {
+                // InputStream throws IOException
+                throw IOException(e)
+            }
+        }
+    }
+
+    /** Imitates the behavior of an L2CAP BluetoothSocket */
+    private class BluetoothL2capOutputStream(
+        val fd: FileDescriptor,
+    ) : OutputStream() {
+
+        override fun write(b: Int) {
+            throw NotImplementedError("This method does not maintain packet boundaries, do not use")
+        }
+
+        /** See BluetoothSocket#write(buf, off, len) */
+        override fun write(b: ByteArray, off: Int, len: Int) {
+            try {
+                Os.write(fd, b, off, len)
+            } catch (e: Exception) {
+                // OutputStream throws IOException
+                throw IOException(e)
+            }
+        }
+
+        override fun close() {
+            try {
+                Os.shutdown(fd, SHUT_WR)
+            } catch (e: Exception) {
+                // OutputStream throws IOException
+                throw IOException(e)
+            }
+        }
+    }
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        Os.socketpair(AF_UNIX, SOCK_SEQPACKET, 0, tunFds[0], tunFds[1])
+        Os.socketpair(AF_UNIX, SOCK_SEQPACKET, 0, l2capFds[0], l2capFds[1])
+
+        // Set socket i/o timeout for test end.
+        Os.setsockoptTimeval(tunFds[1], SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(5000))
+        Os.setsockoptTimeval(tunFds[1], SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(5000))
+        Os.setsockoptTimeval(l2capFds[1], SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(5000))
+        Os.setsockoptTimeval(l2capFds[1], SOL_SOCKET, SO_SNDTIMEO, StructTimeval.fromMillis(5000))
+
+        l2capInputStream = BluetoothL2capInputStream(l2capFds[0])
+        l2capOutputStream = BluetoothL2capOutputStream(l2capFds[0])
+        doReturn(l2capInputStream).`when`(bluetoothSocket).getInputStream()
+        doReturn(l2capOutputStream).`when`(bluetoothSocket).getOutputStream()
+        doAnswer({
+            l2capInputStream.close()
+            l2capOutputStream.close()
+            try {
+                // libcore's Linux_close properly invalidates the FileDescriptor, so it is safe to
+                // close multiple times.
+                Os.close(l2capFds[0])
+            } catch (e: Exception) {
+                // BluetoothSocket#close can be called multiple times. Catch EBADF on subsequent
+                // invocations.
+            }
+        }).`when`(bluetoothSocket).close()
+
+        forwarder = L2capPacketForwarder(
+                handler,
+                FdWrapper(ParcelFileDescriptor(tunFds[0])),
+                BluetoothSocketWrapper(bluetoothSocket),
+                callback
+        )
+    }
+
+    @After
+    fun tearDown() {
+        if (::forwarder.isInitialized) {
+            // forwarder closes tunFds[0] and l2capFds[0]
+            forwarder.tearDown()
+        } else {
+            Os.close(tunFds[0])
+            Os.close(l2capFds[0])
+        }
+        Os.close(tunFds[1])
+        Os.close(l2capFds[1])
+
+        handlerThread.quitSafely()
+        handlerThread.join()
+    }
+
+    fun sendPacket(fd: FileDescriptor, size: Int = 1280): ByteArray {
+        val packet = ByteArray(size)
+        Random.nextBytes(packet)
+        Os.write(fd, packet, 0 /*off*/, packet.size)
+        return packet
+    }
+
+    fun assertPacketReceived(fd: FileDescriptor, expected: ByteArray) {
+        val readBuffer = ByteArray(expected.size)
+        Os.read(fd, readBuffer, 0 /*off*/, readBuffer.size)
+        assertThat(readBuffer).isEqualTo(expected)
+    }
+
+    @Test
+    fun testForwarding_withoutHeaderCompression() {
+        var packet = sendPacket(l2capFds[1])
+        var packet2 = sendPacket(l2capFds[1])
+        assertPacketReceived(tunFds[1], packet)
+        assertPacketReceived(tunFds[1], packet2)
+
+        packet = sendPacket(tunFds[1])
+        packet2 = sendPacket(tunFds[1])
+        assertPacketReceived(l2capFds[1], packet)
+        assertPacketReceived(l2capFds[1], packet2)
+    }
+
+    @Test
+    fun testForwarding_packetExceedsMtu() {
+        // Reading from tun drops packets that exceed MTU.
+        // drop
+        sendPacket(tunFds[1], L2capPacketForwarder.MTU + 1)
+        // drop
+        sendPacket(tunFds[1], L2capPacketForwarder.MTU + 42)
+        var packet = sendPacket(l2capFds[1], 1280)
+        assertPacketReceived(tunFds[1], packet)
+
+        // On the BluetoothSocket side, reads that exceed MTU stop forwarding.
+        sendPacket(l2capFds[1], L2capPacketForwarder.MTU + 1)
+        verify(callback, timeout(TIMEOUT)).onError()
+    }
+}
