switch to github.com/mdlayher/netlink
this gives us access to the socket receive buffer size and it saves 2mb binary size.
This commit is contained in:
parent
8f0e46f37f
commit
05bff7f5ad
92
main.go
92
main.go
|
@ -15,7 +15,8 @@ import (
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/jsimonetti/rtnetlink"
|
||||||
|
"github.com/mdlayher/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -65,25 +66,31 @@ func newRouteStats() *routeStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *routeStats) update(ru netlink.RouteUpdate) {
|
func DstIPNet(rm rtnetlink.RouteMessage) *net.IPNet {
|
||||||
rs.Lock()
|
var zeros int
|
||||||
defer rs.Unlock()
|
switch rm.Family {
|
||||||
|
case unix.AF_INET:
|
||||||
switch ru.Type {
|
zeros = 32
|
||||||
case unix.RTM_NEWROUTE:
|
case unix.AF_INET6:
|
||||||
rs.add(ru)
|
zeros = 128
|
||||||
case unix.RTM_DELROUTE:
|
|
||||||
rs.del(ru)
|
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "Unknown route type %d\n", ru.Type)
|
fmt.Fprintf(os.Stderr, "unexpected family %q", rm.Family)
|
||||||
|
}
|
||||||
|
return &net.IPNet{
|
||||||
|
IP: rm.Attributes.Dst,
|
||||||
|
Mask: net.CIDRMask(int(rm.DstLength), zeros),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *routeStats) add(ru netlink.RouteUpdate) {
|
func (rs *routeStats) add(rm rtnetlink.RouteMessage) {
|
||||||
key := ru.Route.Dst.String()
|
rs.Lock()
|
||||||
|
defer rs.Unlock()
|
||||||
|
|
||||||
|
dst := DstIPNet(rm)
|
||||||
|
key := dst.String()
|
||||||
r := rs.stats[key]
|
r := rs.stats[key]
|
||||||
if r == nil {
|
if r == nil {
|
||||||
r = &route{Dst: ru.Route.Dst}
|
r = &route{Dst: dst}
|
||||||
}
|
}
|
||||||
r.Counter++
|
r.Counter++
|
||||||
if r.UnreachableSince == nil {
|
if r.UnreachableSince == nil {
|
||||||
|
@ -93,11 +100,15 @@ func (rs *routeStats) add(ru netlink.RouteUpdate) {
|
||||||
rs.stats[key] = r
|
rs.stats[key] = r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *routeStats) del(ru netlink.RouteUpdate) {
|
func (rs *routeStats) del(rm rtnetlink.RouteMessage) {
|
||||||
key := ru.Route.Dst.String()
|
rs.Lock()
|
||||||
|
defer rs.Unlock()
|
||||||
|
|
||||||
|
dst := DstIPNet(rm)
|
||||||
|
key := dst.String()
|
||||||
r := rs.stats[key]
|
r := rs.stats[key]
|
||||||
if r == nil {
|
if r == nil {
|
||||||
r = &route{Dst: ru.Route.Dst}
|
r = &route{Dst: dst}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.UnreachableDuration += time.Since(*r.UnreachableSince)
|
r.UnreachableDuration += time.Since(*r.UnreachableSince)
|
||||||
|
@ -129,25 +140,44 @@ func (rs *routeStats) getLongest() []route {
|
||||||
}
|
}
|
||||||
|
|
||||||
func monitor(done <-chan struct{}, rs *routeStats) {
|
func monitor(done <-chan struct{}, rs *routeStats) {
|
||||||
rups := make(chan netlink.RouteUpdate, 64)
|
c, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{
|
||||||
opts := netlink.RouteSubscribeOptions{
|
Groups: 1<<(unix.RTNLGRP_IPV4_ROUTE-1) | 1<<(unix.RTNLGRP_IPV6_ROUTE-1),
|
||||||
ErrorCallback: func(err error) {
|
})
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err, err)
|
if err != nil {
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := netlink.RouteSubscribeWithOptions(rups, done, opts); err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ru := range rups {
|
go func() {
|
||||||
if ru.Route.Type != unix.RTN_UNREACHABLE {
|
<-done
|
||||||
continue
|
c.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err = c.SetReadBuffer(16 * 1048576); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
ms, err := c.Receive()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
}
|
}
|
||||||
// show unly babel routes
|
|
||||||
if ru.Route.Protocol != 42 {
|
for _, m := range ms {
|
||||||
continue
|
rm := rtnetlink.RouteMessage{}
|
||||||
|
if err = rm.UnmarshalBinary(m.Data); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if rm.Type != unix.RTN_UNREACHABLE ||
|
||||||
|
rm.Protocol != 42 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch m.Header.Type {
|
||||||
|
case unix.RTM_NEWROUTE:
|
||||||
|
rs.add(rm)
|
||||||
|
case unix.RTM_DELROUTE:
|
||||||
|
rs.del(rm)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rs.update(ru)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue