mirror of
https://github.com/nadoo/glider.git
synced 2026-07-17 17:30:11 +08:00
93 lines
2.4 KiB
Go
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,
|
|
}
|