mirror of
https://github.com/luscis/openlan.git
synced 2025-10-21 16:10:05 +08:00
clone from danieldin95
This commit is contained in:
154
pkg/network/tap_kernel.go
Executable file
154
pkg/network/tap_kernel.go
Executable file
@@ -0,0 +1,154 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/luscis/openlan/pkg/libol"
|
||||
"github.com/songgao/water"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type KernelTap struct {
|
||||
lock sync.Mutex
|
||||
device *water.Interface
|
||||
master Bridger
|
||||
tenant string
|
||||
name string
|
||||
config TapConfig
|
||||
ipMtu int
|
||||
}
|
||||
|
||||
func NewKernelTap(tenant string, c TapConfig) (*KernelTap, error) {
|
||||
if c.Mtu == 0 {
|
||||
c.Mtu = 1500
|
||||
}
|
||||
if c.Name == "auto" {
|
||||
c.Name = Taps.GenName()
|
||||
}
|
||||
device, err := WaterNew(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tap := &KernelTap{
|
||||
tenant: tenant,
|
||||
device: device,
|
||||
name: device.Name(),
|
||||
config: c,
|
||||
ipMtu: c.Mtu,
|
||||
}
|
||||
Taps.Add(tap)
|
||||
return tap, nil
|
||||
}
|
||||
|
||||
func (t *KernelTap) Has(v uint) bool {
|
||||
if v == UsClose {
|
||||
return t.device == nil
|
||||
} else if v == UsUp {
|
||||
return t.device != nil
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *KernelTap) Type() string {
|
||||
return ProviderKer
|
||||
}
|
||||
|
||||
func (t *KernelTap) Tenant() string {
|
||||
return t.tenant
|
||||
}
|
||||
|
||||
func (t *KernelTap) IsTun() bool {
|
||||
return t.config.Type == TUN
|
||||
}
|
||||
|
||||
func (t *KernelTap) Name() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *KernelTap) Read(p []byte) (int, error) {
|
||||
t.lock.Lock()
|
||||
if t.device == nil {
|
||||
t.lock.Unlock()
|
||||
return 0, libol.NewErr("Closed")
|
||||
}
|
||||
t.lock.Unlock()
|
||||
if n, err := t.device.Read(p); err == nil {
|
||||
return n, nil
|
||||
} else {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
func (t *KernelTap) Write(p []byte) (int, error) {
|
||||
t.lock.Lock()
|
||||
if t.device == nil {
|
||||
t.lock.Unlock()
|
||||
return 0, libol.NewErr("Closed")
|
||||
}
|
||||
t.lock.Unlock()
|
||||
return t.device.Write(p)
|
||||
}
|
||||
|
||||
func (t *KernelTap) Recv(p []byte) (int, error) {
|
||||
return t.Read(p)
|
||||
}
|
||||
|
||||
func (t *KernelTap) Send(p []byte) (int, error) {
|
||||
return t.Write(p)
|
||||
}
|
||||
|
||||
func (t *KernelTap) Close() error {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
libol.Debug("KernelTap.Close %s", t.name)
|
||||
if t.device == nil {
|
||||
return nil
|
||||
}
|
||||
if t.master != nil {
|
||||
_ = t.master.DelSlave(t.name)
|
||||
t.master = nil
|
||||
}
|
||||
err := t.device.Close()
|
||||
Taps.Del(t.name)
|
||||
t.device = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *KernelTap) Master() Bridger {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
return t.master
|
||||
}
|
||||
|
||||
func (t *KernelTap) SetMaster(dev Bridger) error {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
if t.master == nil {
|
||||
t.master = dev
|
||||
}
|
||||
return libol.NewErr("already to %s", t.master)
|
||||
}
|
||||
|
||||
func (t *KernelTap) Up() {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
libol.Debug("KernelTap.Up %s", t.name)
|
||||
if _, err := libol.IpLinkUp(t.name); err != nil {
|
||||
libol.Warn("KernelTap.Up %s: %s", t.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *KernelTap) Down() {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
libol.Debug("KernelTap.Down %s", t.name)
|
||||
if _, err := libol.IpLinkDown(t.name); err != nil {
|
||||
libol.Warn("KernelTap.Down %s: %s", t.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *KernelTap) String() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *KernelTap) Mtu() int {
|
||||
return t.ipMtu
|
||||
}
|
Reference in New Issue
Block a user