@@ -3,6 +3,7 @@ package metrics
33import (
44 "context"
55 "errors"
6+ "fmt"
67 "os"
78 "strconv"
89 "strings"
@@ -24,55 +25,68 @@ var (
2425 Subsystem : "egress" ,
2526 Name : "nf_conntrack_entries_count" ,
2627 Help : "the number of entries in the nf_conntrack table" ,
27- }, []string {"namespace" , "pod" , "egress" })
28+ }, []string {"namespace" , "pod" , "egress" , "protocol" })
2829
2930 NfConnctackLimit = prometheus .NewGaugeVec (prometheus.GaugeOpts {
3031 Namespace : constants .MetricsNS ,
3132 Subsystem : "egress" ,
3233 Name : "nf_conntrack_entries_limit" ,
3334 Help : "the limit of the nf_conntrack table" ,
34- }, []string {"namespace" , "pod" , "egress" })
35+ }, []string {"namespace" , "pod" , "egress" , "protocol" })
3536
3637 NfTableMasqueradePackets = prometheus .NewGaugeVec (prometheus.GaugeOpts {
3738 Namespace : constants .MetricsNS ,
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
67+ conn * nftables.Conn
68+ nfConnctackCount prometheus.Gauge
69+ nfConnctackLimit prometheus.Gauge
70+ perProtocol map [string ]* nfTablesPerProtocolMetrics
71+ }
72+
73+ type nfTablesPerProtocolMetrics struct {
6974 nfTablesNATPackets prometheus.Gauge
7075 nfTablesNATBytes prometheus.Gauge
7176 nfTablesInvalidPackets prometheus.Gauge
7277 nfTablesInvalidBytes prometheus.Gauge
7378}
7479
75- func NewEgressCollector (ns , pod , egress string ) (Collector , error ) {
80+ func newNfTablesPerProtocolMetrics (ns , pod , egress , protocol string ) * nfTablesPerProtocolMetrics {
81+ return & nfTablesPerProtocolMetrics {
82+ nfTablesNATPackets : NfTableMasqueradePackets .WithLabelValues (ns , pod , egress , protocol ),
83+ nfTablesNATBytes : NfTableMasqueradeBytes .WithLabelValues (ns , pod , egress , protocol ),
84+ nfTablesInvalidPackets : NfTableInvalidPackets .WithLabelValues (ns , pod , egress , protocol ),
85+ nfTablesInvalidBytes : NfTableInvalidBytes .WithLabelValues (ns , pod , egress , protocol ),
86+ }
87+ }
88+
89+ func NewEgressCollector (ns , pod , egress string , protocols []string ) (Collector , error ) {
7690 NfConnctackCount .Reset ()
7791 NfConnctackLimit .Reset ()
7892 NfTableMasqueradeBytes .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+ nfConnctackCount : NfConnctackCount .WithLabelValues (ns , pod , egress ),
110+ nfConnctackLimit : NfConnctackLimit .WithLabelValues (ns , pod , egress ),
111+ perProtocol : perProtocols ,
96112 }, nil
97113}
98114
@@ -114,25 +130,32 @@ func (c *egressCollector) Update(ctx context.Context) error {
114130 }
115131 c .nfConnctackLimit .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 .nfTablesNATPackets .Set (float64 (natPackets ))
139+ nfTablesMetrics .nfTablesNATBytes .Set (float64 (natBytes ))
140+
141+ invalidPackets , invalidBytes , err := c .getNfTablesInvalidCounter (protocol )
142+ if err != nil {
143+ return err
144+ }
145+ nfTablesMetrics .nfTablesInvalidPackets .Set (float64 (invalidPackets ))
146+ nfTablesMetrics .nfTablesInvalidBytes .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 strings .ToLower (protocol ) {
219+ case "ipv4" :
220+ return nftables .TableFamilyIPv4 , nil
221+ case "ipv6" :
222+ return nftables .TableFamilyIPv6 , nil
223+ default :
224+ return nftables .TableFamilyUnspecified , fmt .Errorf ("unsupported family type: %s" , protocol )
225+ }
226+ }
0 commit comments