mirror of
https://github.com/luscis/openlan.git
synced 2025-10-05 16:47:11 +08:00
143 lines
2.7 KiB
Go
Executable File
143 lines
2.7 KiB
Go
Executable File
package network
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/luscis/openlan/pkg/libol"
|
|
"github.com/vishvananda/netlink"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type BrCtl struct {
|
|
Name string
|
|
Path string
|
|
Mtu int
|
|
}
|
|
|
|
func NewBrCtl(name string, mtu int) (b *BrCtl) {
|
|
if mtu == 0 {
|
|
mtu = 1500
|
|
}
|
|
return &BrCtl{
|
|
Name: name,
|
|
Mtu: mtu,
|
|
}
|
|
}
|
|
|
|
func (b *BrCtl) Has() bool {
|
|
if _, err := netlink.LinkByName(b.Name); err == nil {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *BrCtl) SysPath(fun string) string {
|
|
if b.Path == "" {
|
|
b.Path = fmt.Sprintf("/sys/devices/virtual/net/%s/bridge", b.Name)
|
|
}
|
|
return fmt.Sprintf("%s/%s", b.Path, fun)
|
|
}
|
|
|
|
func (b *BrCtl) Stp(on bool) error {
|
|
file := b.SysPath("stp_state")
|
|
fp, err := os.OpenFile(file, os.O_RDWR, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
if on {
|
|
if _, err := fp.Write([]byte("1")); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if _, err := fp.Write([]byte("0")); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *BrCtl) Delay(delay int) error { // by second
|
|
file := b.SysPath("forward_delay")
|
|
fp, err := os.OpenFile(file, os.O_RDWR, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
if _, err := fp.Write([]byte(strconv.Itoa(delay * 100))); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *BrCtl) AddPort(port string) error {
|
|
link, err := netlink.LinkByName(port)
|
|
if err != nil {
|
|
return libol.NewErr("LinkByName " + err.Error())
|
|
}
|
|
if err := netlink.LinkSetUp(link); err != nil {
|
|
return libol.NewErr("LinkSetUp " + err.Error())
|
|
}
|
|
la := netlink.LinkAttrs{TxQLen: -1, Name: b.Name}
|
|
bridge := &netlink.Bridge{LinkAttrs: la}
|
|
if err := netlink.LinkSetMaster(link, bridge); err != nil {
|
|
return libol.NewErr("LinkSetMaster " + err.Error())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *BrCtl) DelPort(port string) error {
|
|
link, err := netlink.LinkByName(port)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := netlink.LinkSetNoMaster(link); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *BrCtl) CallIptables(value int) error {
|
|
file := b.SysPath("nf_call_iptables")
|
|
fp, err := os.OpenFile(file, os.O_RDWR, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
if _, err := fp.Write([]byte(strconv.Itoa(value))); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type BrPort struct {
|
|
Name string
|
|
Path string
|
|
}
|
|
|
|
func NewBrPort(name string) (p *BrPort) {
|
|
return &BrPort{
|
|
Name: name,
|
|
}
|
|
}
|
|
|
|
func (p *BrPort) SysPath(fun string) string {
|
|
if p.Path == "" {
|
|
p.Path = fmt.Sprintf("/sys/devices/virtual/net/%s/brport/", p.Name)
|
|
}
|
|
return fmt.Sprintf("%s/%s", p.Path, fun)
|
|
}
|
|
|
|
func (p *BrPort) Cost(cost int) error {
|
|
file := p.SysPath("path_cost")
|
|
fp, err := os.OpenFile(file, os.O_RDWR, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fp.Close()
|
|
if _, err := fp.Write([]byte(strconv.Itoa(cost))); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|