Add nftables backend to portmap
Signed-off-by: Dan Winship <danwinship@redhat.com>
This commit is contained in:

committed by
Casey Callendrello

parent
3d1968c152
commit
01a94e17c7
@ -37,6 +37,7 @@ import (
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containernetworking/plugins/pkg/utils"
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
)
|
||||
|
||||
@ -46,6 +47,12 @@ type PortMapper interface {
|
||||
unforwardPorts(config *PortMapConf) error
|
||||
}
|
||||
|
||||
// These are vars rather than consts so we can "&" them
|
||||
var (
|
||||
iptablesBackend = "iptables"
|
||||
nftablesBackend = "nftables"
|
||||
)
|
||||
|
||||
// PortMapEntry corresponds to a single entry in the port_mappings argument,
|
||||
// see CONVENTIONS.md
|
||||
type PortMapEntry struct {
|
||||
@ -61,6 +68,7 @@ type PortMapConf struct {
|
||||
mapper PortMapper
|
||||
|
||||
// Generic config
|
||||
Backend *string `json:"backend,omitempty"`
|
||||
SNAT *bool `json:"snat,omitempty"`
|
||||
ConditionsV4 *[]string `json:"conditionsV4"`
|
||||
ConditionsV6 *[]string `json:"conditionsV6"`
|
||||
@ -240,6 +248,21 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
|
||||
return nil, nil, fmt.Errorf("MasqMarkBit must be between 0 and 31")
|
||||
}
|
||||
|
||||
err := ensureBackend(&conf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
switch *conf.Backend {
|
||||
case iptablesBackend:
|
||||
conf.mapper = &portMapperIPTables{}
|
||||
|
||||
case nftablesBackend:
|
||||
conf.mapper = &portMapperNFTables{}
|
||||
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unrecognized backend %q", *conf.Backend)
|
||||
}
|
||||
|
||||
// Reject invalid port numbers
|
||||
for _, pm := range conf.RuntimeConfig.PortMaps {
|
||||
if pm.ContainerPort <= 0 {
|
||||
@ -279,3 +302,58 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
|
||||
|
||||
return &conf, result, nil
|
||||
}
|
||||
|
||||
// ensureBackend validates and/or sets conf.Backend
|
||||
func ensureBackend(conf *PortMapConf) error {
|
||||
backendConfig := make(map[string][]string)
|
||||
|
||||
if conf.ExternalSetMarkChain != nil {
|
||||
backendConfig[iptablesBackend] = append(backendConfig[iptablesBackend], "externalSetMarkChain")
|
||||
}
|
||||
if conditionsBackend := detectBackendOfConditions(conf.ConditionsV4); conditionsBackend != "" {
|
||||
backendConfig[conditionsBackend] = append(backendConfig[conditionsBackend], "conditionsV4")
|
||||
}
|
||||
if conditionsBackend := detectBackendOfConditions(conf.ConditionsV6); conditionsBackend != "" {
|
||||
backendConfig[conditionsBackend] = append(backendConfig[conditionsBackend], "conditionsV6")
|
||||
}
|
||||
|
||||
// If backend wasn't requested explicitly, default to iptables, unless it is not
|
||||
// available (and nftables is). FIXME: flip this default at some point.
|
||||
if conf.Backend == nil {
|
||||
if !utils.SupportsIPTables() && utils.SupportsNFTables() {
|
||||
conf.Backend = &nftablesBackend
|
||||
} else {
|
||||
conf.Backend = &iptablesBackend
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we dont have config for the wrong backend
|
||||
var wrongBackend string
|
||||
if *conf.Backend == iptablesBackend {
|
||||
wrongBackend = nftablesBackend
|
||||
} else {
|
||||
wrongBackend = iptablesBackend
|
||||
}
|
||||
if len(backendConfig[wrongBackend]) > 0 {
|
||||
return fmt.Errorf("%s backend was requested but configuration contains %s-specific options %v", *conf.Backend, wrongBackend, backendConfig[wrongBackend])
|
||||
}
|
||||
|
||||
// OK
|
||||
return nil
|
||||
}
|
||||
|
||||
// detectBackendOfConditions returns "iptables" if conditions contains iptables
|
||||
// conditions, "nftables" if it contains nftables conditions, and "" if it is empty.
|
||||
func detectBackendOfConditions(conditions *[]string) string {
|
||||
if conditions == nil || len(*conditions) == 0 || (*conditions)[0] == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// The first token of any iptables condition would start with a hyphen (e.g. "-d",
|
||||
// "--sport", "-m"). No nftables condition would start that way. (An nftables
|
||||
// condition might include a negative number, but not as the first token.)
|
||||
if (*conditions)[0][0] == '-' {
|
||||
return iptablesBackend
|
||||
}
|
||||
return nftablesBackend
|
||||
}
|
||||
|
Reference in New Issue
Block a user