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("couldn't parse %q line %q", file.Name(), s.Text())
116		}
117
118		name := fields[0]
119		value, err := strconv.Atoi(fields[1])
120		if err != nil {
121			return XfrmStat{}, err
122		}
123
124		switch name {
125		case "XfrmInError":
126			x.XfrmInError = value
127		case "XfrmInBufferError":
128			x.XfrmInBufferError = value
129		case "XfrmInHdrError":
130			x.XfrmInHdrError = value
131		case "XfrmInNoStates":
132			x.XfrmInNoStates = value
133		case "XfrmInStateProtoError":
134			x.XfrmInStateProtoError = value
135		case "XfrmInStateModeError":
136			x.XfrmInStateModeError = value
137		case "XfrmInStateSeqError":
138			x.XfrmInStateSeqError = value
139		case "XfrmInStateExpired":
140			x.XfrmInStateExpired = value
141		case "XfrmInStateInvalid":
142			x.XfrmInStateInvalid = value
143		case "XfrmInTmplMismatch":
144			x.XfrmInTmplMismatch = value
145		case "XfrmInNoPols":
146			x.XfrmInNoPols = value
147		case "XfrmInPolBlock":
148			x.XfrmInPolBlock = value
149		case "XfrmInPolError":
150			x.XfrmInPolError = value
151		case "XfrmOutError":
152			x.XfrmOutError = value
153		case "XfrmInStateMismatch":
154			x.XfrmInStateMismatch = value
155		case "XfrmOutBundleGenError":
156			x.XfrmOutBundleGenError = value
157		case "XfrmOutBundleCheckError":
158			x.XfrmOutBundleCheckError = value
159		case "XfrmOutNoStates":
160			x.XfrmOutNoStates = value
161		case "XfrmOutStateProtoError":
162			x.XfrmOutStateProtoError = value
163		case "XfrmOutStateModeError":
164			x.XfrmOutStateModeError = value
165		case "XfrmOutStateSeqError":
166			x.XfrmOutStateSeqError = value
167		case "XfrmOutStateExpired":
168			x.XfrmOutStateExpired = value
169		case "XfrmOutPolBlock":
170			x.XfrmOutPolBlock = value
171		case "XfrmOutPolDead":
172			x.XfrmOutPolDead = value
173		case "XfrmOutPolError":
174			x.XfrmOutPolError = value
175		case "XfrmFwdHdrError":
176			x.XfrmFwdHdrError = value
177		case "XfrmOutStateInvalid":
178			x.XfrmOutStateInvalid = value
179		case "XfrmAcquireError":
180			x.XfrmAcquireError = value
181		}
182
183	}
184
185	return x, s.Err()
186}
187