Skip to content

Commit 67480c5

Browse files
committed
repalce to jsimonetti/rtnetlink
Signed-off-by: kamijin_fanta <kamijin@live.jp>
1 parent 1f58989 commit 67480c5

3 files changed

Lines changed: 85 additions & 40 deletions

File tree

collector/network_route_linux.go

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ package collector
1717

1818
import (
1919
"fmt"
20+
"golang.org/x/sys/unix"
2021
"net"
2122
"strconv"
2223

2324
"github.com/go-kit/kit/log"
25+
"github.com/jsimonetti/rtnetlink"
2426
"github.com/prometheus/client_golang/prometheus"
25-
"github.com/vishvananda/netlink"
2627
)
2728

2829
type networkRouteCollector struct {
@@ -58,46 +59,68 @@ func NewNetworkRouteCollector(logger log.Logger) (Collector, error) {
5859
func (n networkRouteCollector) Update(ch chan<- prometheus.Metric) error {
5960
deviceRoutes := make(map[string]int)
6061

61-
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
62+
conn, err := rtnetlink.Dial(nil)
6263
if err != nil {
63-
return fmt.Errorf("couldn't get route list: %w", err)
64+
return fmt.Errorf("couldn't connect rtnetlink: %w", err)
65+
}
66+
defer conn.Close()
67+
68+
links, err := conn.Link.List()
69+
if err != nil {
70+
return fmt.Errorf("couldn't get links: %w", err)
71+
}
72+
73+
routes, err := conn.Route.List()
74+
if err != nil {
75+
return fmt.Errorf("couldn't get routes: %w", err)
6476
}
6577

6678
for _, route := range routes {
67-
if len(route.MultiPath) != 0 { // route has multipath
68-
for _, nexthop := range route.MultiPath {
69-
link, err := netlink.LinkByIndex(nexthop.LinkIndex)
70-
if err != nil {
71-
return fmt.Errorf("couldn't get link by index: %w", err)
79+
if route.Type != unix.RTA_DST {
80+
continue
81+
}
82+
if len(route.Attributes.Multipath) != 0 {
83+
for _, nextHop := range route.Attributes.Multipath {
84+
ifName := ""
85+
for _, link := range links {
86+
if link.Index == nextHop.Hop.IfIndex {
87+
ifName = link.Attributes.Name
88+
break
89+
}
7290
}
91+
7392
labels := []string{
74-
link.Attrs().Name, // if
75-
networkRouteIPToString(route.Src), // src
76-
networkRouteIPNetToString(route.Dst), // dest
77-
networkRouteIPToString(nexthop.Gw), // gw
78-
strconv.Itoa(route.Priority), // priority(metrics)
79-
networkRouteProtocolToString(route.Protocol), // proto
80-
strconv.Itoa(nexthop.Hops + 1), // weight
93+
ifName, // if
94+
networkRouteIPToString(route.Attributes.Src), // src
95+
networkRouteIPWithPrefixToString(route.Attributes.Dst, route.DstLength), // dest
96+
networkRouteIPToString(nextHop.Gateway), // gw
97+
strconv.FormatUint(uint64(route.Attributes.Priority), 10), // priority(metrics)
98+
networkRouteProtocolToString(route.Protocol), // proto
99+
strconv.Itoa(int(nextHop.Hop.Hops) + 1), // weight
81100
}
82101
ch <- prometheus.MustNewConstMetric(n.routeDesc, prometheus.GaugeValue, 1, labels...)
83-
deviceRoutes[link.Attrs().Name]++
102+
deviceRoutes[ifName]++
84103
}
85104
} else {
86-
link, err := netlink.LinkByIndex(route.LinkIndex)
87-
if err != nil {
88-
return fmt.Errorf("couldn't get link by index: %w", err)
105+
ifName := ""
106+
for _, link := range links {
107+
if link.Index == route.Attributes.OutIface {
108+
ifName = link.Attributes.Name
109+
break
110+
}
89111
}
112+
90113
labels := []string{
91-
link.Attrs().Name, // if
92-
networkRouteIPToString(route.Src), // src
93-
networkRouteIPNetToString(route.Dst), // dest
94-
networkRouteIPToString(route.Gw), // gw
95-
strconv.Itoa(route.Priority), // priority(metrics)
96-
networkRouteProtocolToString(route.Protocol), // proto
114+
ifName, // if
115+
networkRouteIPToString(route.Attributes.Src), // src
116+
networkRouteIPWithPrefixToString(route.Attributes.Dst, route.DstLength), // dest
117+
networkRouteIPToString(route.Attributes.Gateway), // gw
118+
strconv.FormatUint(uint64(route.Attributes.Priority), 10), // priority(metrics)
119+
networkRouteProtocolToString(route.Protocol), // proto
97120
"", // weight
98121
}
99122
ch <- prometheus.MustNewConstMetric(n.routeDesc, prometheus.GaugeValue, 1, labels...)
100-
deviceRoutes[link.Attrs().Name]++
123+
deviceRoutes[ifName]++
101124
}
102125
}
103126

@@ -108,11 +131,19 @@ func (n networkRouteCollector) Update(ch chan<- prometheus.Metric) error {
108131
return nil
109132
}
110133

111-
func networkRouteIPNetToString(ip *net.IPNet) string {
112-
if ip == nil {
134+
func networkRouteIPWithPrefixToString(ip net.IP, len uint8) string {
135+
if len == 0 {
113136
return "default"
114137
}
115-
return ip.String()
138+
iplen := net.IPv4len
139+
if ip.To4() == nil {
140+
iplen = net.IPv6len
141+
}
142+
network := &net.IPNet{
143+
IP: ip,
144+
Mask: net.CIDRMask(int(len), iplen*8),
145+
}
146+
return network.String()
116147
}
117148

118149
func networkRouteIPToString(ip net.IP) string {
@@ -122,7 +153,7 @@ func networkRouteIPToString(ip net.IP) string {
122153
return ip.String()
123154
}
124155

125-
func networkRouteProtocolToString(protocol int) string {
156+
func networkRouteProtocolToString(protocol uint8) string {
126157
// from linux kernel 'include/uapi/linux/rtnetlink.h'
127158
switch protocol {
128159
case 0:

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ require (
77
github.com/go-kit/kit v0.10.0
88
github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968
99
github.com/hodgesds/perf-utils v0.0.8
10+
github.com/jsimonetti/rtnetlink v0.0.0-20201125080424-8bebea019a6c
1011
github.com/lufia/iostat v1.1.0
1112
github.com/mattn/go-xmlrpc v0.0.3
1213
github.com/mdlayher/genetlink v1.0.0 // indirect
13-
github.com/mdlayher/netlink v1.1.0 // indirect
1414
github.com/mdlayher/wifi v0.0.0-20200527114002-84f0b9457fdd
1515
github.com/pkg/errors v0.9.1
1616
github.com/prometheus/client_golang v1.7.1
@@ -19,12 +19,12 @@ require (
1919
github.com/prometheus/procfs v0.2.0
2020
github.com/siebenmann/go-kstat v0.0.0-20200303194639-4e8294f9e9d5
2121
github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a
22-
github.com/vishvananda/netlink v1.1.0
2322
go.uber.org/multierr v1.5.0 // indirect
2423
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
2524
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
25+
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect
2626
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
27-
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860
27+
golang.org/x/sys v0.0.0-20201202213521-69691e467435
2828
golang.org/x/tools v0.0.0-20200513201620-d5fe73897c97 // indirect
2929
gopkg.in/alecthomas/kingpin.v2 v2.2.6
3030
gopkg.in/yaml.v2 v2.3.0

go.sum

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
116116
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
117117
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
118118
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
119+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
120+
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
121+
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
119122
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
120123
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
121124
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -162,6 +165,9 @@ github.com/jsimonetti/rtnetlink v0.0.0-20190830100107-3784a6c7c552 h1:Ve/e6edHdA
162165
github.com/jsimonetti/rtnetlink v0.0.0-20190830100107-3784a6c7c552/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
163166
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4 h1:nwOc1YaOrYJ37sEBrtWZrdqzK22hiJs3GpDmP3sR2Yw=
164167
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
168+
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
169+
github.com/jsimonetti/rtnetlink v0.0.0-20201125080424-8bebea019a6c h1:SIKkaHgrNzRnHEB3QtUR3VUwy9+QpnTwhZ9GYBC0QyU=
170+
github.com/jsimonetti/rtnetlink v0.0.0-20201125080424-8bebea019a6c/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
165171
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
166172
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
167173
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -203,6 +209,8 @@ github.com/mdlayher/netlink v1.0.0 h1:vySPY5Oxnn/8lxAPn2cK6kAzcZzYJl3KriSLO46OT1
203209
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
204210
github.com/mdlayher/netlink v1.1.0 h1:mpdLgm+brq10nI9zM1BpX1kpDbh3NLl3RSnVq6ZSkfg=
205211
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
212+
github.com/mdlayher/netlink v1.1.1 h1:VqG+Voq9V4uZ+04vjIrcSCWDpf91B1xxbP4QBUmUJE8=
213+
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
206214
github.com/mdlayher/wifi v0.0.0-20200527114002-84f0b9457fdd h1:50p1vPNK43pzCVX10+5MmiOerbBzC1vR6+sLB3FZewE=
207215
github.com/mdlayher/wifi v0.0.0-20200527114002-84f0b9457fdd/go.mod h1:Evt/EIne46u9PtQbeTx2NTcqURpr5K4SvKtGmBuDPN8=
208216
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@@ -329,10 +337,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
329337
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
330338
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
331339
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
332-
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
333-
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
334-
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
335-
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
336340
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
337341
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
338342
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -404,6 +408,11 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
404408
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
405409
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
406410
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
411+
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
412+
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
413+
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
414+
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
415+
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
407416
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
408417
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
409418
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -431,7 +440,6 @@ golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7w
431440
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
432441
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
433442
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
434-
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
435443
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
436444
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
437445
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4=
@@ -445,11 +453,17 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
445453
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
446454
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
447455
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
448-
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 h1:YEu4SMq7D0cmT7CBbXfcH0NZeuChAXwsHe/9XueUO6o=
449-
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
456+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
457+
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5vs5/gRy+XWFtZFu7NBM=
458+
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
459+
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
460+
golang.org/x/sys v0.0.0-20201202213521-69691e467435 h1:25AvDqqB9PrNqj1FLf2/70I4W0L19qqoaFq3gjNwbKk=
461+
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
450462
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
451463
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
452464
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
465+
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
466+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
453467
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
454468
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
455469
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

0 commit comments

Comments
 (0)