@@ -3,6 +3,7 @@ package metrics
33import  (
44	"context" 
55	"errors" 
6+ 	"fmt" 
67	"os" 
78	"strconv" 
89	"strings" 
@@ -19,14 +20,14 @@ const (
1920)
2021
2122var  (
22- 	NfConnctackCount  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
23+ 	NfConntrackCount  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
2324		Namespace : constants .MetricsNS ,
2425		Subsystem : "egress" ,
2526		Name :      "nf_conntrack_entries_count" ,
2627		Help :      "the number of entries in the nf_conntrack table" ,
2728	}, []string {"namespace" , "pod" , "egress" })
2829
29- 	NfConnctackLimit  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
30+ 	NfConntrackLimit  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
3031		Namespace : constants .MetricsNS ,
3132		Subsystem : "egress" ,
3233		Name :      "nf_conntrack_entries_limit" ,
@@ -38,43 +39,56 @@ var (
3839		Subsystem : "egress" ,
3940		Name :      "nftables_masqueraded_packets_total" ,
4041		Help :      "the number of packets that are masqueraded by nftables" ,
41- 	}, []string {"namespace" , "pod" , "egress" })
42+ 	}, []string {"namespace" , "pod" , "egress" ,  "protocol" })
4243
4344	NfTableMasqueradeBytes  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
4445		Namespace : constants .MetricsNS ,
4546		Subsystem : "egress" ,
4647		Name :      "nftables_masqueraded_bytes_total" ,
4748		Help :      "the number of bytes that are masqueraded by nftables" ,
48- 	}, []string {"namespace" , "pod" , "egress" })
49+ 	}, []string {"namespace" , "pod" , "egress" ,  "protocol" })
4950
5051	NfTableInvalidPackets  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
5152		Namespace : constants .MetricsNS ,
5253		Subsystem : "egress" ,
5354		Name :      "nftables_invalid_packets_total" ,
5455		Help :      "the number of packets that are dropped as invalid packets by nftables" ,
55- 	}, []string {"namespace" , "pod" , "egress" })
56+ 	}, []string {"namespace" , "pod" , "egress" ,  "protocol" })
5657
5758	NfTableInvalidBytes  =  prometheus .NewGaugeVec (prometheus.GaugeOpts {
5859		Namespace : constants .MetricsNS ,
5960		Subsystem : "egress" ,
6061		Name :      "nftables_invalid_bytes_total" ,
6162		Help :      "the number of bytes that are dropped as invalid packets by nftables" ,
62- 	}, []string {"namespace" , "pod" , "egress" })
63+ 	}, []string {"namespace" , "pod" , "egress" ,  "protocol" })
6364)
6465
6566type  egressCollector  struct  {
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 
67+ 	conn              * nftables.Conn 
68+ 	nfConntrackCount  prometheus.Gauge 
69+ 	nfConntrackLimit  prometheus.Gauge 
70+ 	perProtocol       map [string ]* nfTablesPerProtocolMetrics 
71+ }
72+ 
73+ type  nfTablesPerProtocolMetrics  struct  {
74+ 	NATPackets      prometheus.Gauge 
75+ 	NATBytes        prometheus.Gauge 
76+ 	InvalidPackets  prometheus.Gauge 
77+ 	InvalidBytes    prometheus.Gauge 
78+ }
79+ 
80+ func  newNfTablesPerProtocolMetrics (ns , pod , egress , protocol  string ) * nfTablesPerProtocolMetrics  {
81+ 	return  & nfTablesPerProtocolMetrics {
82+ 		NATPackets :     NfTableMasqueradePackets .WithLabelValues (ns , pod , egress , protocol ),
83+ 		NATBytes :       NfTableMasqueradeBytes .WithLabelValues (ns , pod , egress , protocol ),
84+ 		InvalidPackets : NfTableInvalidPackets .WithLabelValues (ns , pod , egress , protocol ),
85+ 		InvalidBytes :   NfTableInvalidBytes .WithLabelValues (ns , pod , egress , protocol ),
86+ 	}
7387}
7488
75- func  NewEgressCollector (ns , pod , egress  string ) (Collector , error ) {
76- 	NfConnctackCount .Reset ()
77- 	NfConnctackLimit .Reset ()
89+ func  NewEgressCollector (ns , pod , egress  string ,  protocols  [] string ) (Collector , error ) {
90+ 	NfConntrackCount .Reset ()
91+ 	NfConntrackLimit .Reset ()
7892	NfTableMasqueradeBytes .Reset ()
7993	NfTableMasqueradePackets .Reset ()
8094	NfTableInvalidPackets .Reset ()
@@ -85,14 +99,16 @@ func NewEgressCollector(ns, pod, egress string) (Collector, error) {
8599		return  nil , err 
86100	}
87101
102+ 	perProtocols  :=  make (map [string ]* nfTablesPerProtocolMetrics )
103+ 	for  _ , protocol  :=  range  protocols  {
104+ 		perProtocols [protocol ] =  newNfTablesPerProtocolMetrics (ns , pod , egress , protocol )
105+ 	}
106+ 
88107	return  & egressCollector {
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 ),
108+ 		conn :             c ,
109+ 		nfConntrackCount : NfConntrackCount .WithLabelValues (ns , pod , egress ),
110+ 		nfConntrackLimit : NfConntrackLimit .WithLabelValues (ns , pod , egress ),
111+ 		perProtocol :      perProtocols ,
96112	}, nil 
97113}
98114
@@ -106,33 +122,40 @@ func (c *egressCollector) Update(ctx context.Context) error {
106122	if  err  !=  nil  {
107123		return  err 
108124	}
109- 	c .nfConnctackCount .Set (float64 (val ))
125+ 	c .nfConntrackCount .Set (float64 (val ))
110126
111127	val , err  =  readUintFromFile (NF_CONNTRACK_LIMIT_PATH )
112128	if  err  !=  nil  {
113129		return  err 
114130	}
115- 	c .nfConnctackLimit .Set (float64 (val ))
131+ 	c .nfConntrackLimit .Set (float64 (val ))
116132
117- 	natPackets , natBytes , err  :=  c .getNfTablesNATCounter ()
118- 	if  err  !=  nil  {
119- 		return  err 
120- 	}
121- 	c .nfTablesNATPackets .Set (float64 (natPackets ))
122- 	c .nfTablesNATBytes .Set (float64 (natBytes ))
133+ 	for  protocol , nfTablesMetrics  :=  range  c .perProtocol  {
134+ 		natPackets , natBytes , err  :=  c .getNfTablesNATCounter (protocol )
135+ 		if  err  !=  nil  {
136+ 			return  err 
137+ 		}
138+ 		nfTablesMetrics .NATPackets .Set (float64 (natPackets ))
139+ 		nfTablesMetrics .NATBytes .Set (float64 (natBytes ))
140+ 
141+ 		invalidPackets , invalidBytes , err  :=  c .getNfTablesInvalidCounter (protocol )
142+ 		if  err  !=  nil  {
143+ 			return  err 
144+ 		}
145+ 		nfTablesMetrics .InvalidPackets .Set (float64 (invalidPackets ))
146+ 		nfTablesMetrics .InvalidBytes .Set (float64 (invalidBytes ))
123147
124- 	invalidPackets , invalidBytes , err  :=  c .getNfTablesInvalidCounter ()
125- 	if  err  !=  nil  {
126- 		return  err 
127148	}
128- 	c .nfTablesInvalidPackets .Set (float64 (invalidPackets ))
129- 	c .nfTablesInvalidBytes .Set (float64 (invalidBytes ))
130149
131150	return  nil 
132151}
133152
134- func  (c  * egressCollector ) getNfTablesNATCounter () (uint64 , uint64 , error ) {
135- 	table  :=  & nftables.Table {Family : nftables .TableFamilyIPv4 , Name : "nat" }
153+ func  (c  * egressCollector ) getNfTablesNATCounter (protocol  string ) (uint64 , uint64 , error ) {
154+ 	family , err  :=  stringToTableFamily (protocol )
155+ 	if  err  !=  nil  {
156+ 		return  0 , 0 , err 
157+ 	}
158+ 	table  :=  & nftables.Table {Family : family , Name : "nat" }
136159	rules , err  :=  c .conn .GetRules (table , & nftables.Chain {
137160		Name :    "POSTROUTING" ,
138161		Type :    nftables .ChainTypeNAT ,
@@ -153,8 +176,12 @@ func (c *egressCollector) getNfTablesNATCounter() (uint64, uint64, error) {
153176	return  0 , 0 , errors .New ("a masquerade rule is not found" )
154177}
155178
156- func  (c  * egressCollector ) getNfTablesInvalidCounter () (uint64 , uint64 , error ) {
157- 	table  :=  & nftables.Table {Family : nftables .TableFamilyIPv4 , Name : "filter" }
179+ func  (c  * egressCollector ) getNfTablesInvalidCounter (protocol  string ) (uint64 , uint64 , error ) {
180+ 	family , err  :=  stringToTableFamily (protocol )
181+ 	if  err  !=  nil  {
182+ 		return  0 , 0 , err 
183+ 	}
184+ 	table  :=  & nftables.Table {Family : family , Name : "filter" }
158185	rules , err  :=  c .conn .GetRules (table , & nftables.Chain {
159186		Name :    "FORWARD" ,
160187		Type :    nftables .ChainTypeFilter ,
@@ -186,3 +213,14 @@ func readUintFromFile(path string) (uint64, error) {
186213	}
187214	return  val , nil 
188215}
216+ 
217+ func  stringToTableFamily (protocol  string ) (nftables.TableFamily , error ) {
218+ 	switch  protocol  {
219+ 	case  constants .FamilyIPv4 :
220+ 		return  nftables .TableFamilyIPv4 , nil 
221+ 	case  constants .FamilyIPv6 :
222+ 		return  nftables .TableFamilyIPv6 , nil 
223+ 	default :
224+ 		return  nftables .TableFamilyUnspecified , fmt .Errorf ("unsupported family type: %s" , protocol )
225+ 	}
226+ }
0 commit comments