func NewNamedPortManager(datapath Datapath) (*NamedPortManager, error) { self := &NamedPortManager{ datapath: datapath, ports: make(map[uint32]*NamedPort), lock: &sync.Mutex{}, } if ghub, err := nlgo.NewGenlHub(); err != nil { return nil, err } else if hub, err := nlgo.NewRtHub(); err != nil { ghub.Close() return nil, err } else if rhub, err := nlgo.NewRtHub(); err != nil { ghub.Close() hub.Close() return nil, err } else { self.hub = hub self.ghub = ghub self.rhub = rhub if err := hub.Add(syscall.RTNLGRP_LINK, self); err != nil { hub.Close() ghub.Close() return nil, err } } return self, nil }
func (self NamedPort) SetConfig(mods []PortConfig) { self.lock.Lock() defer self.lock.Unlock() var config []PortConfig for _, mod := range mods { switch m := mod.(type) { case PortConfigPortDown: if hub, err := nlgo.NewRtHub(); err != nil { log.Print(err) } else { defer hub.Close() ifinfo := &syscall.IfInfomsg{ Index: int32(self.ifIndex), } if !bool(m) { ifinfo.Flags |= syscall.IFF_UP } ifinfo.Change |= syscall.IFF_UP // xxx:should add error check? hub.Request(syscall.RTM_NEWLINK, 0, (*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(ifinfo))[:], nil) } default: config = append(config, mod) } } self.config = config self.monitor <- true }
func (self NamedPort) SetConfig(mods []PortConfig) { self.lock.Lock() defer self.lock.Unlock() var config []PortConfig for _, mod := range mods { switch m := mod.(type) { case PortConfigPortDown: if hub, err := nlgo.NewRtHub(); err != nil { log.Print(err) } else { defer hub.Close() ifinfo := syscall.IfInfomsg{ Index: int32(self.ifIndex), } if !bool(m) { ifinfo.Flags |= syscall.IFF_UP } ifinfo.Change |= syscall.IFF_UP // xxx:should add error check? req := syscall.NetlinkMessage{ Header: syscall.NlMsghdr{ Type: syscall.RTM_SETLINK, }, } (*nlgo.IfInfoMessage)(&req).Set(ifinfo, nil) hub.Async(req, nil) } default: config = append(config, mod) } } self.config = config self.monitor <- true }
func TestLo(t *testing.T) { if hub, err := nlgo.NewRtHub(); err != nil { t.Error(err) } else if info, err := GetByName(hub, "lo"); err != nil { t.Error(err) } else { t.Log(info) } }
func TestIdx(t *testing.T) { if hub, err := nlgo.NewRtHub(); err != nil { t.Error(err) } else if name, err := GetNameByIndex(hub, 1); err != nil { t.Error(err) } else { t.Log(name) } }
func (self NamedPort) Stats() (PortStats, error) { ifinfo := syscall.IfInfomsg{ Index: int32(self.ifIndex), } if hub, err := nlgo.NewRtHub(); err != nil { return PortStats{}, err } else { defer hub.Close() req := syscall.NetlinkMessage{ Header: syscall.NlMsghdr{ Type: syscall.RTM_GETLINK, Flags: syscall.NLM_F_DUMP, }, } (*nlgo.IfInfoMessage)(&req).Set(ifinfo, nil) if res, err := hub.Sync(req); err != nil { return PortStats{}, err } else { for _, r := range res { switch r.Header.Type { case syscall.RTM_NEWLINK: msg := nlgo.IfInfoMessage(r) if msg.IfInfo().Index != int32(self.ifIndex) { // pass } else if attrs, err := msg.Attrs(); err != nil { return PortStats{}, err } else if blk := attrs.(nlgo.AttrMap).Get(nlgo.IFLA_STATS64); blk != nil { stat := []byte(blk.(nlgo.Binary)) s := (*nlgo.RtnlLinkStats64)(unsafe.Pointer(&stat[0])) ret := PortStats{ RxPackets: s.RxPackets, TxPackets: s.TxPackets, RxBytes: s.RxBytes, TxBytes: s.TxBytes, RxDropped: s.RxDropped, TxDropped: s.TxDropped, RxErrors: s.RxErrors, TxErrors: s.TxErrors, } if self.hatype == syscall.ARPHRD_ETHER { ret.Ethernet = &PortStatsEthernet{ RxFrameErr: s.RxFrameErrors, RxOverErr: s.RxOverErrors, RxCrcErr: s.RxCrcErrors, Collisions: s.Collisions, } } return ret, nil } } } } } return PortStats{}, fmt.Errorf("rtnetlink query failed") }
func (self NamedPort) Stats() (PortStats, error) { ifinfo := (*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(&syscall.IfInfomsg{ Index: int32(self.ifIndex), }))[:] if hub, err := nlgo.NewRtHub(); err != nil { return PortStats{}, err } else { defer hub.Close() if res, err := hub.Request(syscall.RTM_GETLINK, syscall.NLM_F_DUMP, ifinfo, nil); err != nil { return PortStats{}, err } else { for _, r := range res { rIfinfo := (*syscall.IfInfomsg)(unsafe.Pointer(&r.Message.Data[0])) if rIfinfo.Index != int32(self.ifIndex) { continue } switch r.Message.Header.Type { case syscall.RTM_NEWLINK: if attrs, err := nlgo.RouteLinkPolicy.Parse(r.Message.Data[nlgo.NLMSG_ALIGN(syscall.SizeofIfInfomsg):]); err != nil { return PortStats{}, err } else if blk := attrs.(nlgo.AttrMap).Get(nlgo.IFLA_STATS64); blk != nil { stat := []byte(blk.(nlgo.Binary)) s := (*nlgo.RtnlLinkStats64)(unsafe.Pointer(&stat[0])) ret := PortStats{ RxPackets: s.RxPackets, TxPackets: s.TxPackets, RxBytes: s.RxBytes, TxBytes: s.TxBytes, RxDropped: s.RxDropped, TxDropped: s.TxDropped, RxErrors: s.RxErrors, TxErrors: s.TxErrors, } if self.hatype == syscall.ARPHRD_ETHER { ret.Ethernet = &PortStatsEthernet{ RxFrameErr: s.RxFrameErrors, RxOverErr: s.RxOverErrors, RxCrcErr: s.RxCrcErrors, Collisions: s.Collisions, } } return ret, nil } } } } } return PortStats{}, fmt.Errorf("rtnetlink query failed") }