mirror of
https://github.com/luscis/openlan.git
synced 2025-09-26 20:41:29 +08:00
240 lines
4.3 KiB
Go
Executable File
240 lines
4.3 KiB
Go
Executable File
package network
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/luscis/openlan/pkg/libol"
|
|
nl "github.com/vishvananda/netlink"
|
|
)
|
|
|
|
func NewBridger(provider, name string, ifMtu int) Bridger {
|
|
return NewLinuxBridge(name, ifMtu)
|
|
}
|
|
|
|
type LinuxBridge struct {
|
|
sts DeviceStats
|
|
address *nl.Addr
|
|
ipMtu int
|
|
name string
|
|
device nl.Link
|
|
ctl *BrCtl
|
|
out *libol.SubLogger
|
|
l3if string
|
|
l2if string
|
|
}
|
|
|
|
func GetPair(name string) (string, string) {
|
|
s0 := ""
|
|
s1 := ""
|
|
if strings.HasPrefix(name, "br-") {
|
|
s0 = strings.Replace(name, "br-", "hi-", 1)
|
|
s1 = strings.Replace(name, "br-", "si-", 1)
|
|
} else {
|
|
s0 = fmt.Sprintf("hi-%s", name)
|
|
s1 = fmt.Sprintf("si-%s", name)
|
|
}
|
|
return GetName(s0), GetName(s1)
|
|
}
|
|
|
|
func NewLinuxBridge(name string, mtu int) *LinuxBridge {
|
|
if mtu == 0 {
|
|
mtu = 1500
|
|
}
|
|
|
|
b := &LinuxBridge{
|
|
name: name,
|
|
ipMtu: mtu,
|
|
ctl: NewBrCtl(name, mtu),
|
|
out: libol.NewSubLogger(name),
|
|
}
|
|
b.l3if, b.l2if = GetPair(name)
|
|
|
|
Bridges.Add(b)
|
|
return b
|
|
}
|
|
|
|
func (b *LinuxBridge) Kernel() string {
|
|
return b.name
|
|
}
|
|
|
|
func (b *LinuxBridge) Open(addr string) {
|
|
b.out.Debug("LinuxBridge.Open")
|
|
link, _ := nl.LinkByName(b.name)
|
|
if link == nil {
|
|
br := &nl.Bridge{
|
|
LinkAttrs: nl.LinkAttrs{
|
|
TxQLen: -1,
|
|
Name: b.name,
|
|
MTU: b.ipMtu,
|
|
},
|
|
}
|
|
err := nl.LinkAdd(br)
|
|
if err != nil {
|
|
b.out.Error("LinuxBridge.Open: %s", err)
|
|
return
|
|
}
|
|
link, err = nl.LinkByName(b.name)
|
|
if link == nil {
|
|
b.out.Error("LinuxBridge.Open: %s", err)
|
|
return
|
|
}
|
|
}
|
|
if err := nl.LinkSetUp(link); err != nil {
|
|
libol.Error("LinuxBridge.Open: %s", err)
|
|
}
|
|
|
|
b.out.Info("LinuxBridge.Open success")
|
|
|
|
if addr != "" {
|
|
ipAddr, err := nl.ParseAddr(addr)
|
|
if err != nil {
|
|
b.out.Error("LinuxBridge.Open: ParseAddr %s", err)
|
|
}
|
|
b.address = ipAddr
|
|
if err := b.Plugin(ipAddr); err != nil {
|
|
libol.Error("LinuxBridge.Open: %s", err)
|
|
}
|
|
}
|
|
b.device = link
|
|
}
|
|
|
|
func (b *LinuxBridge) Close() error {
|
|
var err error
|
|
if b.address != nil {
|
|
b.Unplugin()
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (b *LinuxBridge) AddSlave(name string) error {
|
|
if err := b.ctl.AddPort(name); err != nil {
|
|
b.out.Error("LinuxBridge.AddSlave: %s", name)
|
|
return err
|
|
}
|
|
b.out.Info("LinuxBridge.AddSlave: %s", name)
|
|
return nil
|
|
}
|
|
|
|
func (b *LinuxBridge) DelSlave(name string) error {
|
|
if err := b.ctl.DelPort(name); err != nil {
|
|
b.out.Error("LinuxBridge.DelSlave: %s", name)
|
|
return err
|
|
}
|
|
b.out.Info("LinuxBridge.DelSlave: %s", name)
|
|
return nil
|
|
}
|
|
|
|
func (b *LinuxBridge) ListSlave() <-chan Taper {
|
|
data := make(chan Taper, 32)
|
|
go func() {
|
|
data <- nil
|
|
}()
|
|
b.out.Warn("LinuxBridge.ListSlave: notSupport")
|
|
return data
|
|
}
|
|
|
|
func (b *LinuxBridge) Type() string {
|
|
return ProviderLin
|
|
}
|
|
|
|
func (b *LinuxBridge) String() string {
|
|
return b.name
|
|
}
|
|
|
|
func (b *LinuxBridge) Name() string {
|
|
return b.name
|
|
}
|
|
|
|
func (b *LinuxBridge) Mtu() int {
|
|
return b.ipMtu
|
|
}
|
|
|
|
func (b *LinuxBridge) Stp(enable bool) error {
|
|
return b.ctl.Stp(enable)
|
|
}
|
|
|
|
func (b *LinuxBridge) Delay(value int) error {
|
|
return b.ctl.Delay(value)
|
|
}
|
|
|
|
func (b *LinuxBridge) ListMac() <-chan *MacFdb {
|
|
data := make(chan *MacFdb, 32)
|
|
go func() {
|
|
data <- nil
|
|
}()
|
|
b.out.Warn("LinuxBridge.ListMac: notSupport")
|
|
return data
|
|
}
|
|
|
|
func (b *LinuxBridge) Stats() DeviceStats {
|
|
return b.sts
|
|
}
|
|
|
|
func (b *LinuxBridge) CallIptables(value int) error {
|
|
return b.ctl.CallIptables(value)
|
|
}
|
|
|
|
func (b *LinuxBridge) Plugin(addr *nl.Addr) error {
|
|
if link, _ := nl.LinkByName(b.l2if); link != nil {
|
|
return nil
|
|
}
|
|
|
|
link := &nl.Veth{
|
|
LinkAttrs: nl.LinkAttrs{Name: b.l3if},
|
|
PeerName: b.l2if,
|
|
}
|
|
if err := nl.LinkAdd(link); err != nil {
|
|
return err
|
|
}
|
|
if err := nl.LinkSetUp(link); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := b.AddSlave(b.l2if); err != nil {
|
|
return err
|
|
}
|
|
if err := nl.AddrAdd(link, addr); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *LinuxBridge) Unplugin() error {
|
|
link, _ := nl.LinkByName(b.l2if)
|
|
if link == nil {
|
|
return nil
|
|
}
|
|
|
|
if err := nl.LinkDel(link); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *LinuxBridge) L3Name() string {
|
|
return b.l3if
|
|
}
|
|
|
|
func (b *LinuxBridge) SetMtu(mtu int) error {
|
|
link, _ := nl.LinkByName(b.l3if)
|
|
if link == nil {
|
|
return nil
|
|
}
|
|
if err := nl.LinkSetMTU(link, mtu); err != nil {
|
|
return err
|
|
}
|
|
|
|
link, _ = nl.LinkByName(b.l2if)
|
|
if link == nil {
|
|
return nil
|
|
}
|
|
if err := nl.LinkSetMTU(link, mtu); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|