export input/output nftables counters as well as forwarded
Thus far, we have only had forwarded bytes metrics. Notably, forwarded bytes does not include bytes that were sent by the router itself, e.g. by the webserver or rsync server running on the machine. fixes https://github.com/rtr7/router7/issues/71
This commit is contained in:
parent
8dc93c66c4
commit
593cd8c12d
@ -44,6 +44,8 @@ var (
|
||||
|
||||
func init() {
|
||||
var c nftables.Conn
|
||||
filter4 := &nftables.Table{Family: nftables.TableFamilyIPv4, Name: "filter"}
|
||||
filter6 := &nftables.Table{Family: nftables.TableFamilyIPv6, Name: "filter"}
|
||||
for _, metric := range []struct {
|
||||
name string
|
||||
labels prometheus.Labels
|
||||
@ -53,18 +55,34 @@ func init() {
|
||||
{
|
||||
name: "filter_forward",
|
||||
labels: prometheus.Labels{"family": "ipv4"},
|
||||
obj: &nftables.CounterObj{
|
||||
Table: &nftables.Table{Family: nftables.TableFamilyIPv4, Name: "filter"},
|
||||
Name: "fwded",
|
||||
},
|
||||
obj: &nftables.CounterObj{Table: filter4, Name: "fwded"},
|
||||
},
|
||||
{
|
||||
name: "filter_forward",
|
||||
labels: prometheus.Labels{"family": "ipv6"},
|
||||
obj: &nftables.CounterObj{
|
||||
Table: &nftables.Table{Family: nftables.TableFamilyIPv6, Name: "filter"},
|
||||
Name: "fwded",
|
||||
},
|
||||
obj: &nftables.CounterObj{Table: filter6, Name: "fwded"},
|
||||
},
|
||||
|
||||
{
|
||||
name: "filter_input",
|
||||
labels: prometheus.Labels{"family": "ipv4"},
|
||||
obj: &nftables.CounterObj{Table: filter4, Name: "inputc"},
|
||||
},
|
||||
{
|
||||
name: "filter_input",
|
||||
labels: prometheus.Labels{"family": "ipv6"},
|
||||
obj: &nftables.CounterObj{Table: filter6, Name: "inputc"},
|
||||
},
|
||||
|
||||
{
|
||||
name: "filter_output",
|
||||
labels: prometheus.Labels{"family": "ipv4"},
|
||||
obj: &nftables.CounterObj{Table: filter4, Name: "outputc"},
|
||||
},
|
||||
{
|
||||
name: "filter_output",
|
||||
labels: prometheus.Labels{"family": "ipv6"},
|
||||
obj: &nftables.CounterObj{Table: filter6, Name: "outputc"},
|
||||
},
|
||||
} {
|
||||
metric := metric // copy
|
||||
@ -72,12 +90,11 @@ func init() {
|
||||
updateCounter := func() {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
objs, err := c.GetObjReset(metric.obj)
|
||||
if err != nil ||
|
||||
len(objs) != 1 {
|
||||
obj, err := c.ResetObject(metric.obj)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if co, ok := objs[0].(*nftables.CounterObj); ok {
|
||||
if co, ok := obj.(*nftables.CounterObj); ok {
|
||||
metric.packets += co.Packets
|
||||
metric.bytes += co.Bytes
|
||||
}
|
||||
|
@ -158,14 +158,11 @@ table ip filter {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy accept;
|
||||
oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu
|
||||
counter name "fwded"
|
||||
counter inputc {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
}
|
||||
table ip6 filter {
|
||||
counter fwded {
|
||||
|
||||
counter outputc {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
|
||||
@ -174,6 +171,45 @@ table ip6 filter {
|
||||
oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu
|
||||
counter name "fwded"
|
||||
}
|
||||
|
||||
chain input {
|
||||
type filter hook input priority 0; policy accept;
|
||||
counter name "inputc"
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority 0; policy accept;
|
||||
counter name "outputc"
|
||||
}
|
||||
}
|
||||
table ip6 filter {
|
||||
counter fwded {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
|
||||
counter inputc {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
|
||||
counter outputc {
|
||||
packets 23 bytes 42
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy accept;
|
||||
oifname "uplink0" tcp flags 0x2 tcp option maxseg size set rt mtu
|
||||
counter name "fwded"
|
||||
}
|
||||
|
||||
chain input {
|
||||
type filter hook input priority 0; policy accept;
|
||||
counter name "inputc"
|
||||
}
|
||||
|
||||
chain output {
|
||||
type filter hook output priority 0; policy accept;
|
||||
counter name "outputc"
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
|
@ -648,35 +648,13 @@ func applyPortForwardings(dir, ifname string, c *nftables.Conn, nat *nftables.Ta
|
||||
var DefaultCounterObj = &nftables.CounterObj{}
|
||||
|
||||
func getCounterObj(c *nftables.Conn, o *nftables.CounterObj) *nftables.CounterObj {
|
||||
objs, err := c.GetObj(o)
|
||||
obj, err := c.GetObject(o)
|
||||
if err != nil {
|
||||
o.Bytes = DefaultCounterObj.Bytes
|
||||
o.Packets = DefaultCounterObj.Packets
|
||||
return o
|
||||
}
|
||||
{
|
||||
// TODO: remove this workaround once travis has workers with a newer kernel
|
||||
// than its current Ubuntu trusty kernel (Linux 4.4.0):
|
||||
var filtered []nftables.Obj
|
||||
for _, obj := range objs {
|
||||
co, ok := obj.(*nftables.CounterObj)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if co.Table.Name != o.Table.Name {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, obj)
|
||||
}
|
||||
objs = filtered
|
||||
}
|
||||
if got, want := len(objs), 1; got != want {
|
||||
log.Printf("could not carry counter values: unexpected number of objects in table %v: got %d, want %d", o.Table.Name, got, want)
|
||||
o.Bytes = DefaultCounterObj.Bytes
|
||||
o.Packets = DefaultCounterObj.Packets
|
||||
return o
|
||||
}
|
||||
if co, ok := objs[0].(*nftables.CounterObj); ok {
|
||||
if co, ok := obj.(*nftables.CounterObj); ok {
|
||||
return co
|
||||
}
|
||||
o.Bytes = DefaultCounterObj.Bytes
|
||||
@ -888,6 +866,56 @@ func applyFirewall(dir, ifname string) error {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
input := c.AddChain(&nftables.Chain{
|
||||
Name: "input",
|
||||
Hooknum: nftables.ChainHookInput,
|
||||
Priority: nftables.ChainPriorityFilter,
|
||||
Table: filter,
|
||||
Type: nftables.ChainTypeFilter,
|
||||
})
|
||||
|
||||
counterObj = getCounterObj(c, &nftables.CounterObj{
|
||||
Table: filter,
|
||||
Name: "inputc",
|
||||
})
|
||||
counter = c.AddObj(counterObj).(*nftables.CounterObj)
|
||||
c.AddRule(&nftables.Rule{
|
||||
Table: filter,
|
||||
Chain: input,
|
||||
Exprs: []expr.Any{
|
||||
// [ counter name input ]
|
||||
&expr.Objref{
|
||||
Type: NFT_OBJECT_COUNTER,
|
||||
Name: counter.Name,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
output := c.AddChain(&nftables.Chain{
|
||||
Name: "output",
|
||||
Hooknum: nftables.ChainHookOutput,
|
||||
Priority: nftables.ChainPriorityFilter,
|
||||
Table: filter,
|
||||
Type: nftables.ChainTypeFilter,
|
||||
})
|
||||
|
||||
counterObj = getCounterObj(c, &nftables.CounterObj{
|
||||
Table: filter,
|
||||
Name: "outputc",
|
||||
})
|
||||
counter = c.AddObj(counterObj).(*nftables.CounterObj)
|
||||
c.AddRule(&nftables.Rule{
|
||||
Table: filter,
|
||||
Chain: output,
|
||||
Exprs: []expr.Any{
|
||||
// [ counter name output ]
|
||||
&expr.Objref{
|
||||
Type: NFT_OBJECT_COUNTER,
|
||||
Name: counter.Name,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return c.Flush()
|
||||
|
Loading…
x
Reference in New Issue
Block a user