11package  metrics
22
33import  (
4+ 	"context" 
45	"errors" 
56	"os" 
67	"strconv" 
@@ -45,41 +46,61 @@ var (
4546		Name :      "nftables_masqueraded_bytes_total" ,
4647		Help :      "the number of bytes that are masqueraded by nftables" ,
4748	}, []string {"namespace" , "pod" , "egress" })
49+ 
50+ 	NfTableInvalidPackets  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
51+ 		Namespace : constants .MetricsNS ,
52+ 		Subsystem : "egress" ,
53+ 		Name :      "nftables_invalid_packets_total" ,
54+ 		Help :      "the number of packets that are dropped as invalid packets by nftables" ,
55+ 	}, []string {"namespace" , "pod" , "egress" })
56+ 
57+ 	NfTableInvalidBytes  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
58+ 		Namespace : constants .MetricsNS ,
59+ 		Subsystem : "egress" ,
60+ 		Name :      "nftables_invalid_bytes_total" ,
61+ 		Help :      "the number of bytes that are dropped as invalid packets by nftables" ,
62+ 	}, []string {"namespace" , "pod" , "egress" })
4863)
4964
5065type  egressCollector  struct  {
51- 	conn              * nftables.Conn 
52- 	nfConnctackCount  prometheus.Gauge 
53- 	nfConnctackLimit  prometheus.Gauge 
54- 	nfTablesPackets   prometheus.Gauge 
55- 	nfTablesBytes     prometheus.Gauge 
66+ 	conn                    * nftables.Conn 
67+ 	nfConnctackCount        prometheus.Gauge 
68+ 	nfConnctackLimit        prometheus.Gauge 
69+ 	nfTablesNATPackets      prometheus.Gauge 
70+ 	nfTablesNATBytes        prometheus.Gauge 
71+ 	nfTablesInvalidPackets  prometheus.Gauge 
72+ 	nfTablesInvalidBytes    prometheus.Gauge 
5673}
5774
5875func  NewEgressCollector (ns , pod , egress  string ) (Collector , error ) {
5976	NfConnctackCount .Reset ()
6077	NfConnctackLimit .Reset ()
6178	NfTableMasqueradeBytes .Reset ()
6279	NfTableMasqueradePackets .Reset ()
80+ 	NfTableInvalidPackets .Reset ()
81+ 	NfTableInvalidBytes .Reset ()
6382
6483	c , err  :=  nftables .New ()
6584	if  err  !=  nil  {
6685		return  nil , err 
6786	}
6887
6988	return  & egressCollector {
70- 		conn :             c ,
71- 		nfConnctackCount : NfConnctackCount .WithLabelValues (ns , pod , egress ),
72- 		nfConnctackLimit : NfConnctackLimit .WithLabelValues (ns , pod , egress ),
73- 		nfTablesPackets :  NfTableMasqueradePackets .WithLabelValues (ns , pod , egress ),
74- 		nfTablesBytes :    NfTableMasqueradeBytes .WithLabelValues (ns , pod , egress ),
89+ 		conn :                   c ,
90+ 		nfConnctackCount :       NfConnctackCount .WithLabelValues (ns , pod , egress ),
91+ 		nfConnctackLimit :       NfConnctackLimit .WithLabelValues (ns , pod , egress ),
92+ 		nfTablesNATPackets :     NfTableMasqueradePackets .WithLabelValues (ns , pod , egress ),
93+ 		nfTablesNATBytes :       NfTableMasqueradeBytes .WithLabelValues (ns , pod , egress ),
94+ 		nfTablesInvalidPackets : NfTableInvalidPackets .WithLabelValues (ns , pod , egress ),
95+ 		nfTablesInvalidBytes :   NfTableInvalidBytes .WithLabelValues (ns , pod , egress ),
7596	}, nil 
7697}
7798
7899func  (c  * egressCollector ) Name () string  {
79100	return  "egress-collector" 
80101}
81102
82- func  (c  * egressCollector ) Update () error  {
103+ func  (c  * egressCollector ) Update (ctx  context. Context ) error  {
83104
84105	val , err  :=  readUintFromFile (NF_CONNTRACK_COUNT_PATH )
85106	if  err  !=  nil  {
@@ -93,17 +114,24 @@ func (c *egressCollector) Update() error {
93114	}
94115	c .nfConnctackLimit .Set (float64 (val ))
95116
96- 	packets ,  bytes , err  :=  c .getNfTablesCounter ()
117+ 	natPackets ,  natBytes , err  :=  c .getNfTablesNATCounter ()
97118	if  err  !=  nil  {
98- 		return  nil 
119+ 		return  err 
99120	}
100- 	c .nfTablesPackets .Set (float64 (packets ))
101- 	c .nfTablesBytes .Set (float64 (bytes ))
121+ 	c .nfTablesNATPackets .Set (float64 (natPackets ))
122+ 	c .nfTablesNATBytes .Set (float64 (natBytes ))
123+ 
124+ 	invalidPackets , invalidBytes , err  :=  c .getNfTablesInvalidCounter ()
125+ 	if  err  !=  nil  {
126+ 		return  err 
127+ 	}
128+ 	c .nfTablesInvalidPackets .Set (float64 (invalidPackets ))
129+ 	c .nfTablesInvalidBytes .Set (float64 (invalidBytes ))
102130
103131	return  nil 
104132}
105133
106- func  (c  * egressCollector ) getNfTablesCounter () (uint64 , uint64 , error ) {
134+ func  (c  * egressCollector ) getNfTablesNATCounter () (uint64 , uint64 , error ) {
107135	table  :=  & nftables.Table {Family : nftables .TableFamilyIPv4 , Name : "nat" }
108136	rules , err  :=  c .conn .GetRules (table , & nftables.Chain {
109137		Name :    "POSTROUTING" ,
@@ -125,6 +153,28 @@ func (c *egressCollector) getNfTablesCounter() (uint64, uint64, error) {
125153	return  0 , 0 , errors .New ("a masquerade rule is not found" )
126154}
127155
156+ func  (c  * egressCollector ) getNfTablesInvalidCounter () (uint64 , uint64 , error ) {
157+ 	table  :=  & nftables.Table {Family : nftables .TableFamilyIPv4 , Name : "filter" }
158+ 	rules , err  :=  c .conn .GetRules (table , & nftables.Chain {
159+ 		Name :    "FORWARD" ,
160+ 		Type :    nftables .ChainTypeFilter ,
161+ 		Table :   table ,
162+ 		Hooknum : nftables .ChainHookForward ,
163+ 	})
164+ 	if  err  !=  nil  {
165+ 		return  0 , 0 , err 
166+ 	}
167+ 	for  _ , rule  :=  range  rules  {
168+ 		for  _ , e  :=  range  rule .Exprs  {
169+ 			if  counter , ok  :=  e .(* expr.Counter ); ok  {
170+ 				// A rule in the egress pod must be only one, so we can return by finding a first one. 
171+ 				return  counter .Packets , counter .Bytes , nil 
172+ 			}
173+ 		}
174+ 	}
175+ 	return  0 , 0 , errors .New ("a rule for invalid packets is not found" )
176+ }
177+ 
128178func  readUintFromFile (path  string ) (uint64 , error ) {
129179	data , err  :=  os .ReadFile (path )
130180	if  err  !=  nil  {
0 commit comments