Skip to content

Commit b985e6f

Browse files
add netfilter queue support
1 parent 54b2b56 commit b985e6f

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

Diff for: nfnetlink_queue.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright 2019 The Prometheus Authors
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+
14+
package procfs
15+
16+
import (
17+
"bufio"
18+
"bytes"
19+
"fmt"
20+
21+
"github.com/prometheus/procfs/internal/util"
22+
)
23+
24+
const nfNetLinkQueueFormat = "%d %d %d %d %d %d %d %d %d"
25+
26+
// NFNetLinkQueue contains general information about netfilter queues found in /proc/net/netfilter/nfnetlink_queue.
27+
type NFNetLinkQueue struct {
28+
// id of the queue
29+
QueueID uint
30+
// pid of process handling the queue
31+
PeerPID uint
32+
// number of packets waiting for a decision
33+
QueueTotal uint
34+
// indicate how userspace receive packets
35+
CopyMode uint
36+
// size of copy
37+
CopyRange uint
38+
// number of items dropped by the kernel because too many packets were waiting a decision.
39+
// It queue_total is superior to queue_max_len (1024 per default) the packets are dropped.
40+
QueueDropped uint
41+
// number of packets dropped by userspace (due to kernel send failure on the netlink socket)
42+
QueueUserDropped uint
43+
// sequence number of packets queued. It gives a correct approximation of the number of queued packets.
44+
SequenceID uint
45+
// internal value (number of entity using the queue)
46+
Use uint
47+
}
48+
49+
// NFNetLinkQueue returns information about current state of netfilter queues.
50+
func (fs FS) NFNetLinkQueue() ([]NFNetLinkQueue, error) {
51+
data, err := util.ReadFileNoStat(fs.proc.Path("net/netfilter/nfnetlink_queue"))
52+
if err != nil {
53+
return nil, err
54+
}
55+
56+
queue := []NFNetLinkQueue{}
57+
if len(data) == 0 {
58+
return queue, nil
59+
}
60+
61+
scanner := bufio.NewScanner(bytes.NewReader(data))
62+
for scanner.Scan() {
63+
line := scanner.Text()
64+
nFNetLinkQueue, err := parseNFNetLinkQueueLine(line)
65+
if err != nil {
66+
return nil, err
67+
}
68+
queue = append(queue, *nFNetLinkQueue)
69+
}
70+
return queue, nil
71+
}
72+
73+
// parseNFNetLinkQueueLine parses each line of the /proc/net/netfilter/nfnetlink_queue file.
74+
func parseNFNetLinkQueueLine(line string) (*NFNetLinkQueue, error) {
75+
nFNetLinkQueue := NFNetLinkQueue{}
76+
_, err := fmt.Sscanf(
77+
line, nfNetLinkQueueFormat,
78+
&nFNetLinkQueue.QueueID, &nFNetLinkQueue.PeerPID, &nFNetLinkQueue.QueueTotal, &nFNetLinkQueue.CopyMode,
79+
&nFNetLinkQueue.CopyRange, &nFNetLinkQueue.QueueDropped, &nFNetLinkQueue.QueueUserDropped, &nFNetLinkQueue.SequenceID, &nFNetLinkQueue.Use,
80+
)
81+
if err != nil {
82+
return nil, err
83+
}
84+
return &nFNetLinkQueue, nil
85+
}

Diff for: nfnetlink_queue_test.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2020 The Prometheus Authors
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+
14+
package procfs
15+
16+
import (
17+
"reflect"
18+
"testing"
19+
)
20+
21+
func TestParseNFNetLinkQueueLine(t *testing.T) {
22+
tests := []struct {
23+
name string
24+
s string
25+
shouldErr bool
26+
nfNetLinkQueue *NFNetLinkQueue
27+
}{
28+
{
29+
name: "nf_net_link_queue simple line",
30+
s: " 230 44306 1 2 65531 3 4 5 6",
31+
shouldErr: false,
32+
nfNetLinkQueue: &NFNetLinkQueue{
33+
QueueID: 230,
34+
PeerPID: 44306,
35+
QueueTotal: 1,
36+
CopyMode: 2,
37+
CopyRange: 65531,
38+
QueueDropped: 3,
39+
QueueUserDropped: 4,
40+
SequenceID: 5,
41+
Use: 6,
42+
},
43+
},
44+
{
45+
name: "empty line",
46+
s: "",
47+
shouldErr: true,
48+
nfNetLinkQueue: nil,
49+
},
50+
{
51+
name: "incorrect parameters count in line",
52+
s: " 1 2 3 4 55555 ",
53+
shouldErr: true,
54+
nfNetLinkQueue: nil,
55+
},
56+
}
57+
58+
for i, test := range tests {
59+
t.Logf("[%02d] test %q", i, test.name)
60+
61+
nfNetLinkQueue, err := parseNFNetLinkQueueLine(test.s)
62+
63+
if test.shouldErr && err == nil {
64+
t.Errorf("%s: expected an error, but none occurred", test.name)
65+
}
66+
if !test.shouldErr && err != nil {
67+
t.Errorf("%s: unexpected error: %v", test.name, err)
68+
}
69+
70+
if want, have := test.nfNetLinkQueue, nfNetLinkQueue; !reflect.DeepEqual(want, have) {
71+
t.Errorf("nfNetLinkQueue:\nwant:\n%+v\nhave:\n%+v", want, have)
72+
}
73+
}
74+
75+
}

0 commit comments

Comments
 (0)