diff --git a/cmd/netconfigd/netconfigd.go b/cmd/netconfigd/netconfigd.go index fbffd31..d9f9fbd 100644 --- a/cmd/netconfigd/netconfigd.go +++ b/cmd/netconfigd/netconfigd.go @@ -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 } diff --git a/integration/netconfig/netconfig_test.go b/integration/netconfig/netconfig_test.go index 9237360..7e8ac40 100644 --- a/integration/netconfig/netconfig_test.go +++ b/integration/netconfig/netconfig_test.go @@ -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" + } }` } diff --git a/internal/netconfig/netconfig.go b/internal/netconfig/netconfig.go index f13fd01..0b250f1 100644 --- a/internal/netconfig/netconfig.go +++ b/internal/netconfig/netconfig.go @@ -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()