glider/netset/config.go
nadoo 43552b60c9
Some checks failed
Build / Build (push) Has been cancelled
netset: add nftables set support
2026-07-15 23:41:21 +08:00

93 lines
2.4 KiB
Go

package netset
import (
"fmt"
"strings"
libnetset "github.com/nadoo/netset"
)
const (
defaultNFTFamily = "inet"
defaultNFTTable = "glider"
maxNFTNameLength = 256
)
type nftSetConfig struct {
family libnetset.Family
familyName string
table string
name string
}
func parseNFTSetConfig(value string) (nftSetConfig, error) {
parts := strings.Split(strings.TrimSpace(value), "/")
for i := range parts {
parts[i] = strings.TrimSpace(parts[i])
}
config := nftSetConfig{
family: libnetset.FamilyINet,
familyName: defaultNFTFamily,
table: defaultNFTTable,
}
switch len(parts) {
case 1:
config.name = parts[0]
case 2:
config.table = parts[0]
config.name = parts[1]
case 3:
config.familyName = parts[0]
config.table = parts[1]
config.name = parts[2]
default:
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: expected [[FAMILY/]TABLE/]NAME", value)
}
if config.familyName == "" || config.table == "" || config.name == "" {
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: family, table, and set name must not be empty", value)
}
family, ok := nftFamilies[strings.ToLower(config.familyName)]
if !ok {
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: unsupported family %q", value, config.familyName)
}
config.family = family
config.familyName = strings.ToLower(config.familyName)
if err := validateNFTName("table", config.table); err != nil {
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: %w", value, err)
}
if err := validateNFTName("set", config.name); err != nil {
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: %w", value, err)
}
if err := validateNFTName("IPv6 set", config.name+"6"); err != nil {
return nftSetConfig{}, fmt.Errorf("invalid nftset %q: %w", value, err)
}
return config, nil
}
func validateNFTName(kind, name string) error {
if strings.IndexByte(name, 0) >= 0 {
return fmt.Errorf("%s name must not contain NUL", kind)
}
if len(name) >= maxNFTNameLength {
return fmt.Errorf("%s name is too long", kind)
}
return nil
}
func (c nftSetConfig) key() string {
return c.familyName + "/" + c.table + "/" + c.name
}
var nftFamilies = map[string]libnetset.Family{
"inet": libnetset.FamilyINet,
"ip": libnetset.FamilyIPv4,
"ip6": libnetset.FamilyIPv6,
"arp": libnetset.FamilyARP,
"netdev": libnetset.FamilyNetdev,
"bridge": libnetset.FamilyBridge,
}