mirror of
https://github.com/luscis/openlan.git
synced 2025-10-05 16:47:11 +08:00
151 lines
2.1 KiB
Go
151 lines
2.1 KiB
Go
package network
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/luscis/openlan/pkg/libol"
|
|
"github.com/vishvananda/netlink"
|
|
nl "github.com/vishvananda/netlink"
|
|
)
|
|
|
|
type VRF struct {
|
|
name string
|
|
table int
|
|
link nl.Link
|
|
out *libol.SubLogger
|
|
}
|
|
|
|
var tableId = 1000
|
|
|
|
func GenTable() int {
|
|
tableId += 1
|
|
return tableId
|
|
}
|
|
|
|
type VRFs struct {
|
|
vrfs map[string]*VRF
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
func (s *VRFs) Get(name string) *VRF {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
obj, _ := s.vrfs[name]
|
|
return obj
|
|
}
|
|
|
|
func (s *VRFs) Add(name string, obj *VRF) {
|
|
s.lock.Lock()
|
|
defer s.lock.Unlock()
|
|
s.vrfs[name] = obj
|
|
}
|
|
|
|
var vrfs = VRFs{
|
|
vrfs: make(map[string]*VRF, 1024),
|
|
}
|
|
|
|
func NewVRF(name string, table int) *VRF {
|
|
if obj := vrfs.Get(name); obj != nil {
|
|
return obj
|
|
}
|
|
|
|
if table == 0 {
|
|
table = GenTable()
|
|
}
|
|
obj := &VRF{
|
|
name: name,
|
|
table: table,
|
|
out: libol.NewSubLogger(name),
|
|
}
|
|
vrfs.Add(name, obj)
|
|
|
|
return obj
|
|
}
|
|
|
|
func (v *VRF) Up() error {
|
|
if link, _ := nl.LinkByName(v.name); link != nil {
|
|
v.link = link
|
|
return nil
|
|
}
|
|
|
|
link := &nl.Vrf{
|
|
LinkAttrs: nl.LinkAttrs{
|
|
Name: v.name,
|
|
},
|
|
Table: uint32(v.table),
|
|
}
|
|
|
|
if err := nl.LinkAdd(link); err != nil {
|
|
return err
|
|
}
|
|
if err := nl.LinkSetUp(link); err != nil {
|
|
return err
|
|
}
|
|
|
|
v.link = link
|
|
v.out.Info("VRF.Up %s", v.name)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *VRF) Down() error {
|
|
if v.link == nil {
|
|
return nil
|
|
}
|
|
|
|
if err := nl.LinkDel(v.link); err != nil {
|
|
return err
|
|
}
|
|
|
|
v.link = nil
|
|
v.out.Info("VRF.Down %s", v.name)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *VRF) AddSlave(name string) error {
|
|
if v.link == nil {
|
|
return libol.NewErr("VRF %s not up", v.name)
|
|
}
|
|
|
|
link, err := netlink.LinkByName(name)
|
|
if link == nil {
|
|
return err
|
|
}
|
|
|
|
if err := nl.LinkSetMaster(link, v.link); err != nil {
|
|
return nil
|
|
}
|
|
|
|
v.out.Info("VRF.AddSlave %s", name)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *VRF) DelSlave(name string) error {
|
|
link, _ := netlink.LinkByName(name)
|
|
if link == nil {
|
|
return nil
|
|
}
|
|
|
|
if err := nl.LinkSetNoMaster(link); err != nil {
|
|
return nil
|
|
}
|
|
|
|
v.out.Info("VRF.DelSlave %s", name)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (v *VRF) Table() int {
|
|
return v.table
|
|
}
|
|
|
|
func (v *VRF) Name() string {
|
|
return v.name
|
|
}
|
|
|
|
func (v *VRF) Link() nl.Link {
|
|
return v.link
|
|
}
|