1// Copyright 2017 Prometheus Team
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package procfs
15
16import (
17	"bufio"
18	"fmt"
19	"os"
20	"strconv"
21	"strings"
22)
23
24// XfrmStat models the contents of /proc/net/xfrm_stat.
25type XfrmStat struct {
26	// All errors which are not matched by other
27	XfrmInError int
28	// No buffer is left
29	XfrmInBufferError int
30	// Header Error
31	XfrmInHdrError int
32	// No state found
33	// i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong
34	XfrmInNoStates int
35	// Transformation protocol specific error
36	// e.g. SA Key is wrong
37	XfrmInStateProtoError int
38	// Transformation mode specific error
39	XfrmInStateModeError int
40	// Sequence error
41	// e.g. sequence number is out of window
42	XfrmInStateSeqError int
43	// State is expired
44	XfrmInStateExpired int
45	// State has mismatch option
46	// e.g. UDP encapsulation type is mismatched
47	XfrmInStateMismatch int
48	// State is invalid
49	XfrmInStateInvalid int
50	// No matching template for states
51	// e.g. Inbound SAs are correct but SP rule is wrong
52	XfrmInTmplMismatch int
53	// No policy is found for states
54	// e.g. Inbound SAs are correct but no SP is found
55	XfrmInNoPols int
56	// Policy discards
57	XfrmInPolBlock int
58	// Policy error
59	XfrmInPolError int
60	// All errors which are not matched by others
61	XfrmOutError int
62	// Bundle generation error
63	XfrmOutBundleGenError int
64	// Bundle check error
65	XfrmOutBundleCheckError int
66	// No state was found
67	XfrmOutNoStates int
68	// Transformation protocol specific error
69	XfrmOutStateProtoError int
70	// Transportation mode specific error
71	XfrmOutStateModeError int
72	// Sequence error
73	// i.e sequence number overflow
74	XfrmOutStateSeqError int
75	// State is expired
76	XfrmOutStateExpired int
77	// Policy discads
78	XfrmOutPolBlock int
79	// Policy is dead
80	XfrmOutPolDead int
81	// Policy Error
82	XfrmOutPolError     int
83	XfrmFwdHdrError     int
84	XfrmOutStateInvalid int
85	XfrmAcquireError    int
86}
87
88// NewXfrmStat reads the xfrm_stat statistics.
89func NewXfrmStat() (XfrmStat, error) {
90	fs, err := NewFS(DefaultMountPoint)
91	if err != nil {
92		return XfrmStat{}, err
93	}
94
95	return fs.NewXfrmStat()
96}
97
98// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
99func (fs FS) NewXfrmStat() (XfrmStat, error) {
100	file, err := os.Open(fs.proc.Path("net/xfrm_stat"))
101	if err != nil {
102		return XfrmStat{}, err
103	}
104	defer file.Close()
105
106	var (
107		x = XfrmStat{}
108		s = bufio.NewScanner(file)
109	)
110
111	for s.Scan() {
112		fields := strings.Fields(s.Text())
113
114		if len(fields) != 2 {
115			return XfrmStat{}, fmt.Errorf(
116				"couldn't parse %s line %s", file.Name(), s.Text())
117		}
118
119		name := fields[0]
120		value, err := strconv.Atoi(fields[1])
121		if err != nil {
122			return XfrmStat{}, err
123		}
124
125		switch name {
126		case "XfrmInError":
127			x.XfrmInError = value
128		case "XfrmInBufferError":
129			x.XfrmInBufferError = value
130		case "XfrmInHdrError":
131			x.XfrmInHdrError = value
132		case "XfrmInNoStates":
133			x.XfrmInNoStates = value
134		case "XfrmInStateProtoError":
135			x.XfrmInStateProtoError = value
136		case "XfrmInStateModeError":
137			x.XfrmInStateModeError = value
138		case "XfrmInStateSeqError":
139			x.XfrmInStateSeqError = value
140		case "XfrmInStateExpired":
141			x.XfrmInStateExpired = value
142		case "XfrmInStateInvalid":
143			x.XfrmInStateInvalid = value
144		case "XfrmInTmplMismatch":
145			x.XfrmInTmplMismatch = value
146		case "XfrmInNoPols":
147			x.XfrmInNoPols = value
148		case "XfrmInPolBlock":
149			x.XfrmInPolBlock = value
150		case "XfrmInPolError":
151			x.XfrmInPolError = value
152		case "XfrmOutError":
153			x.XfrmOutError = value
154		case "XfrmInStateMismatch":
155			x.XfrmInStateMismatch = value
156		case "XfrmOutBundleGenError":
157			x.XfrmOutBundleGenError = value
158		case "XfrmOutBundleCheckError":
159			x.XfrmOutBundleCheckError = value
160		case "XfrmOutNoStates":
161			x.XfrmOutNoStates = value
162		case "XfrmOutStateProtoError":
163			x.XfrmOutStateProtoError = value
164		case "XfrmOutStateModeError":
165			x.XfrmOutStateModeError = value
166		case "XfrmOutStateSeqError":
167			x.XfrmOutStateSeqError = value
168		case "XfrmOutStateExpired":
169			x.XfrmOutStateExpired = value
170		case "XfrmOutPolBlock":
171			x.XfrmOutPolBlock = value
172		case "XfrmOutPolDead":
173			x.XfrmOutPolDead = value
174		case "XfrmOutPolError":
175			x.XfrmOutPolError = value
176		case "XfrmFwdHdrError":
177			x.XfrmFwdHdrError = value
178		case "XfrmOutStateInvalid":
179			x.XfrmOutStateInvalid = value
180		case "XfrmAcquireError":
181			x.XfrmAcquireError = value
182		}
183
184	}
185
186	return x, s.Err()
187}
188