diff --git a/device/send.go b/device/send.go
index e07df1b..a4f07e4 100644
--- a/device/send.go
+++ b/device/send.go
@@ -8,7 +8,9 @@ package device
 import (
 	"bytes"
 	"encoding/binary"
+	"errors"
 	"net"
+	"os"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -227,7 +229,9 @@ func (device *Device) RoutineReadFromTUN() {
 
 		if err != nil {
 			if !device.isClosed() {
-				device.log.Errorf("Failed to read packet from TUN device: %v", err)
+				if !errors.Is(err, os.ErrClosed) {
+					device.log.Errorf("Failed to read packet from TUN device: %v", err)
+				}
 				go device.Close()
 			}
 			device.PutMessageBuffer(elem.buffer)
diff --git a/tun/tun_linux.go b/tun/tun_linux.go
index 46eb171..466a805 100644
--- a/tun/tun_linux.go
+++ b/tun/tun_linux.go
@@ -10,6 +10,7 @@ package tun
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
 	"os"
 	"sync"
@@ -329,32 +330,30 @@ func (tun *NativeTun) nameSlow() (string, error) {
 	return string(name), nil
 }
 
-func (tun *NativeTun) Write(buff []byte, offset int) (int, error) {
-
+func (tun *NativeTun) Write(buf []byte, offset int) (int, error) {
 	if tun.nopi {
-		buff = buff[offset:]
+		buf = buf[offset:]
 	} else {
 		// reserve space for header
-
-		buff = buff[offset-4:]
+		buf = buf[offset-4:]
 
 		// add packet information header
-
-		buff[0] = 0x00
-		buff[1] = 0x00
-
-		if buff[4]>>4 == ipv6.Version {
-			buff[2] = 0x86
-			buff[3] = 0xdd
+		buf[0] = 0x00
+		buf[1] = 0x00
+		if buf[4]>>4 == ipv6.Version {
+			buf[2] = 0x86
+			buf[3] = 0xdd
 		} else {
-			buff[2] = 0x08
-			buff[3] = 0x00
+			buf[2] = 0x08
+			buf[3] = 0x00
 		}
 	}
 
-	// write
-
-	return tun.tunFile.Write(buff)
+	n, err := tun.tunFile.Write(buf)
+	if errors.Is(err, syscall.EBADFD) {
+		err = os.ErrClosed
+	}
+	return n, err
 }
 
 func (tun *NativeTun) Flush() error {
@@ -362,22 +361,26 @@ func (tun *NativeTun) Flush() error {
 	return nil
 }
 
-func (tun *NativeTun) Read(buff []byte, offset int) (int, error) {
+func (tun *NativeTun) Read(buf []byte, offset int) (n int, err error) {
 	select {
-	case err := <-tun.errors:
-		return 0, err
+	case err = <-tun.errors:
 	default:
 		if tun.nopi {
-			return tun.tunFile.Read(buff[offset:])
+			n, err = tun.tunFile.Read(buf[offset:])
 		} else {
-			buff := buff[offset-4:]
-			n, err := tun.tunFile.Read(buff[:])
-			if n < 4 {
-				return 0, err
+			buff := buf[offset-4:]
+			n, err = tun.tunFile.Read(buff[:])
+			if errors.Is(err, syscall.EBADFD) {
+				err = os.ErrClosed
+			}
+			if n < 4 {
+				n = 0
+			} else {
+				n -= 4
 			}
-			return n - 4, err
 		}
 	}
+	return
 }
 
 func (tun *NativeTun) Events() chan Event {