feat: netlink queueNum/table config options

This commit is contained in:
Keith Petkus 2024-08-08 13:24:49 -04:00
parent 1de95ed53e
commit d3f1785ac9
2 changed files with 38 additions and 22 deletions

View File

@ -174,6 +174,8 @@ type cliConfig struct {
type cliConfigIO struct { type cliConfigIO struct {
QueueSize uint32 `mapstructure:"queueSize"` QueueSize uint32 `mapstructure:"queueSize"`
QueueNum uint16 `mapstructure:"queueNum"`
Table string `mapstructure:"table"`
ReadBuffer int `mapstructure:"rcvBuf"` ReadBuffer int `mapstructure:"rcvBuf"`
WriteBuffer int `mapstructure:"sndBuf"` WriteBuffer int `mapstructure:"sndBuf"`
Local bool `mapstructure:"local"` Local bool `mapstructure:"local"`
@ -221,6 +223,8 @@ func (c *cliConfig) fillIO(config *engine.Config) error {
WriteBuffer: c.IO.WriteBuffer, WriteBuffer: c.IO.WriteBuffer,
Local: c.IO.Local, Local: c.IO.Local,
RST: c.IO.RST, RST: c.IO.RST,
QueueNum: c.IO.QueueNum,
Table: c.IO.Table,
}) })
} }

View File

@ -19,18 +19,18 @@ import (
) )
const ( const (
nfqueueNum = 100 nfqueueDefaultQueueNum = 100
nfqueueMaxPacketLen = 0xFFFF nfqueueMaxPacketLen = 0xFFFF
nfqueueDefaultQueueSize = 128 nfqueueDefaultQueueSize = 128
nfqueueConnMarkAccept = 1001 nfqueueConnMarkAccept = 1001
nfqueueConnMarkDrop = 1002 nfqueueConnMarkDrop = 1002
nftFamily = "inet" nftFamily = "inet"
nftTable = "opengfw" nftDefaultTable = "opengfw"
) )
func generateNftRules(local, rst bool) (*nftTableSpec, error) { func generateNftRules(local, rst bool, nfqueueNum int, nftTable string) (*nftTableSpec, error) {
if local && rst { if local && rst {
return nil, errors.New("tcp rst is not supported in local mode") return nil, errors.New("tcp rst is not supported in local mode")
} }
@ -64,7 +64,7 @@ func generateNftRules(local, rst bool) (*nftTableSpec, error) {
return table, nil return table, nil
} }
func generateIptRules(local, rst bool) ([]iptRule, error) { func generateIptRules(local, rst bool, nfqueueNum int) ([]iptRule, error) {
if local && rst { if local && rst {
return nil, errors.New("tcp rst is not supported in local mode") return nil, errors.New("tcp rst is not supported in local mode")
} }
@ -94,10 +94,12 @@ var _ PacketIO = (*nfqueuePacketIO)(nil)
var errNotNFQueuePacket = errors.New("not an NFQueue packet") var errNotNFQueuePacket = errors.New("not an NFQueue packet")
type nfqueuePacketIO struct { type nfqueuePacketIO struct {
n *nfqueue.Nfqueue n *nfqueue.Nfqueue
local bool local bool
rst bool rst bool
rSet bool // whether the nftables/iptables rules have been set rSet bool // whether the nftables/iptables rules have been set
queueNum int
table string // nftable name
// iptables not nil = use iptables instead of nftables // iptables not nil = use iptables instead of nftables
ipt4 *iptables.IPTables ipt4 *iptables.IPTables
@ -108,6 +110,8 @@ type nfqueuePacketIO struct {
type NFQueuePacketIOConfig struct { type NFQueuePacketIOConfig struct {
QueueSize uint32 QueueSize uint32
QueueNum uint16
Table string
ReadBuffer int ReadBuffer int
WriteBuffer int WriteBuffer int
Local bool Local bool
@ -118,6 +122,12 @@ func NewNFQueuePacketIO(config NFQueuePacketIOConfig) (PacketIO, error) {
if config.QueueSize == 0 { if config.QueueSize == 0 {
config.QueueSize = nfqueueDefaultQueueSize config.QueueSize = nfqueueDefaultQueueSize
} }
if config.QueueNum == 0 {
config.QueueNum = nfqueueDefaultQueueNum
}
if config.Table == "" {
config.Table = nftDefaultTable
}
var ipt4, ipt6 *iptables.IPTables var ipt4, ipt6 *iptables.IPTables
var err error var err error
if nftCheck() != nil { if nftCheck() != nil {
@ -132,7 +142,7 @@ func NewNFQueuePacketIO(config NFQueuePacketIOConfig) (PacketIO, error) {
} }
} }
n, err := nfqueue.Open(&nfqueue.Config{ n, err := nfqueue.Open(&nfqueue.Config{
NfQueue: nfqueueNum, NfQueue: config.QueueNum,
MaxPacketLen: nfqueueMaxPacketLen, MaxPacketLen: nfqueueMaxPacketLen,
MaxQueueLen: config.QueueSize, MaxQueueLen: config.QueueSize,
Copymode: nfqueue.NfQnlCopyPacket, Copymode: nfqueue.NfQnlCopyPacket,
@ -156,11 +166,13 @@ func NewNFQueuePacketIO(config NFQueuePacketIOConfig) (PacketIO, error) {
} }
} }
return &nfqueuePacketIO{ return &nfqueuePacketIO{
n: n, n: n,
local: config.Local, local: config.Local,
rst: config.RST, rst: config.RST,
ipt4: ipt4, queueNum: int(config.QueueNum),
ipt6: ipt6, table: config.Table,
ipt4: ipt4,
ipt6: ipt6,
protectedDialer: &net.Dialer{ protectedDialer: &net.Dialer{
Control: func(network, address string, c syscall.RawConn) error { Control: func(network, address string, c syscall.RawConn) error {
var err error var err error
@ -214,7 +226,7 @@ func (n *nfqueuePacketIO) Register(ctx context.Context, cb PacketCallback) error
if n.ipt4 != nil { if n.ipt4 != nil {
err = n.setupIpt(n.local, n.rst, false) err = n.setupIpt(n.local, n.rst, false)
} else { } else {
err = n.setupNft(n.local, n.rst, false) err = n.setupNft(n.local, n.rst, false, n.queueNum)
} }
if err != nil { if err != nil {
return err return err
@ -274,7 +286,7 @@ func (n *nfqueuePacketIO) Close() error {
if n.ipt4 != nil { if n.ipt4 != nil {
_ = n.setupIpt(n.local, n.rst, true) _ = n.setupIpt(n.local, n.rst, true)
} else { } else {
_ = n.setupNft(n.local, n.rst, true) _ = n.setupNft(n.local, n.rst, true, n.queueNum)
} }
n.rSet = false n.rSet = false
} }
@ -286,17 +298,17 @@ func (n *nfqueuePacketIO) SetCancelFunc(cancelFunc context.CancelFunc) error {
return nil return nil
} }
func (n *nfqueuePacketIO) setupNft(local, rst, remove bool) error { func (n *nfqueuePacketIO) setupNft(local, rst, remove bool, nfqueueNum int) error {
rules, err := generateNftRules(local, rst) rules, err := generateNftRules(local, rst, nfqueueNum, n.table)
if err != nil { if err != nil {
return err return err
} }
rulesText := rules.String() rulesText := rules.String()
if remove { if remove {
err = nftDelete(nftFamily, nftTable) err = nftDelete(nftFamily, n.table)
} else { } else {
// Delete first to make sure no leftover rules // Delete first to make sure no leftover rules
_ = nftDelete(nftFamily, nftTable) _ = nftDelete(nftFamily, n.table)
err = nftAdd(rulesText) err = nftAdd(rulesText)
} }
if err != nil { if err != nil {
@ -306,7 +318,7 @@ func (n *nfqueuePacketIO) setupNft(local, rst, remove bool) error {
} }
func (n *nfqueuePacketIO) setupIpt(local, rst, remove bool) error { func (n *nfqueuePacketIO) setupIpt(local, rst, remove bool) error {
rules, err := generateIptRules(local, rst) rules, err := generateIptRules(local, rst, n.queueNum)
if err != nil { if err != nil {
return err return err
} }