Skip to content

Commit

Permalink
add netfilter queue support
Browse files Browse the repository at this point in the history
  • Loading branch information
KonstantinKuklin committed Oct 17, 2024
1 parent 54b2b56 commit b985e6f
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 0 deletions.
85 changes: 85 additions & 0 deletions nfnetlink_queue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package procfs

import (
"bufio"
"bytes"
"fmt"

"github.com/prometheus/procfs/internal/util"
)

const nfNetLinkQueueFormat = "%d %d %d %d %d %d %d %d %d"

// NFNetLinkQueue contains general information about netfilter queues found in /proc/net/netfilter/nfnetlink_queue.
type NFNetLinkQueue struct {
// id of the queue
QueueID uint
// pid of process handling the queue
PeerPID uint
// number of packets waiting for a decision
QueueTotal uint
// indicate how userspace receive packets
CopyMode uint
// size of copy
CopyRange uint
// number of items dropped by the kernel because too many packets were waiting a decision.
// It queue_total is superior to queue_max_len (1024 per default) the packets are dropped.
QueueDropped uint
// number of packets dropped by userspace (due to kernel send failure on the netlink socket)
QueueUserDropped uint
// sequence number of packets queued. It gives a correct approximation of the number of queued packets.
SequenceID uint
// internal value (number of entity using the queue)
Use uint
}

// NFNetLinkQueue returns information about current state of netfilter queues.
func (fs FS) NFNetLinkQueue() ([]NFNetLinkQueue, error) {
data, err := util.ReadFileNoStat(fs.proc.Path("net/netfilter/nfnetlink_queue"))
if err != nil {
return nil, err
}

queue := []NFNetLinkQueue{}
if len(data) == 0 {
return queue, nil
}

scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
line := scanner.Text()
nFNetLinkQueue, err := parseNFNetLinkQueueLine(line)
if err != nil {
return nil, err
}
queue = append(queue, *nFNetLinkQueue)
}
return queue, nil
}

// parseNFNetLinkQueueLine parses each line of the /proc/net/netfilter/nfnetlink_queue file.
func parseNFNetLinkQueueLine(line string) (*NFNetLinkQueue, error) {
nFNetLinkQueue := NFNetLinkQueue{}
_, err := fmt.Sscanf(
line, nfNetLinkQueueFormat,
&nFNetLinkQueue.QueueID, &nFNetLinkQueue.PeerPID, &nFNetLinkQueue.QueueTotal, &nFNetLinkQueue.CopyMode,
&nFNetLinkQueue.CopyRange, &nFNetLinkQueue.QueueDropped, &nFNetLinkQueue.QueueUserDropped, &nFNetLinkQueue.SequenceID, &nFNetLinkQueue.Use,
)
if err != nil {
return nil, err
}
return &nFNetLinkQueue, nil
}
75 changes: 75 additions & 0 deletions nfnetlink_queue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2020 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package procfs

import (
"reflect"
"testing"
)

func TestParseNFNetLinkQueueLine(t *testing.T) {
tests := []struct {
name string
s string
shouldErr bool
nfNetLinkQueue *NFNetLinkQueue
}{
{
name: "nf_net_link_queue simple line",
s: " 230 44306 1 2 65531 3 4 5 6",
shouldErr: false,
nfNetLinkQueue: &NFNetLinkQueue{
QueueID: 230,
PeerPID: 44306,
QueueTotal: 1,
CopyMode: 2,
CopyRange: 65531,
QueueDropped: 3,
QueueUserDropped: 4,
SequenceID: 5,
Use: 6,
},
},
{
name: "empty line",
s: "",
shouldErr: true,
nfNetLinkQueue: nil,
},
{
name: "incorrect parameters count in line",
s: " 1 2 3 4 55555 ",
shouldErr: true,
nfNetLinkQueue: nil,
},
}

for i, test := range tests {
t.Logf("[%02d] test %q", i, test.name)

nfNetLinkQueue, err := parseNFNetLinkQueueLine(test.s)

if test.shouldErr && err == nil {
t.Errorf("%s: expected an error, but none occurred", test.name)
}
if !test.shouldErr && err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err)
}

if want, have := test.nfNetLinkQueue, nfNetLinkQueue; !reflect.DeepEqual(want, have) {
t.Errorf("nfNetLinkQueue:\nwant:\n%+v\nhave:\n%+v", want, have)
}
}

}

0 comments on commit b985e6f

Please sign in to comment.