diff --git a/go.mod b/go.mod index 4378f08ef..4f7e3a251 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( ) require ( + github.com/coreos/go-iptables v0.6.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/google/go-cmp v0.5.9 // indirect golang.org/x/net v0.4.0 // indirect diff --git a/go.sum b/go.sum index e81286d4d..1437f23c0 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= diff --git a/libcni/api.go b/libcni/api.go index 4296f3a3a..90109540b 100644 --- a/libcni/api.go +++ b/libcni/api.go @@ -33,6 +33,7 @@ import ( "github.com/containernetworking/cni/pkg/types/create" "github.com/containernetworking/cni/pkg/utils" "github.com/containernetworking/cni/pkg/version" + "github.com/coreos/go-iptables/iptables" ) var ( @@ -104,6 +105,16 @@ type CNIConfig struct { // CNIConfig implements the CNI interface var _ CNI = &CNIConfig{} +// isNotExist returnst true if the error is from iptables indicating +// that the target does not exist. +func isNotExist(err error) bool { + e, ok := err.(*iptables.Error) + if !ok { + return false + } + return e.IsNotExist() +} + // NewCNIConfig returns a new CNIConfig object that will search for plugins // in the given paths and use the given exec interface to run those plugins, // or if the exec interface is not given, will use a default exec handler. @@ -116,6 +127,22 @@ func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig { // or if the exec interface is not given, will use a default exec handler. // The given cache directory will be used for temporary data storage when needed. func NewCNIConfigWithCacheDir(path []string, cacheDir string, exec invoke.Exec) *CNIConfig { + ip4t, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) + if err != nil { + err := ip4t.AppendUnique("filter", "FORWARD", "-m", "conntrack", "--ctstate", "INVALID", "-j", "DROP", "-m", "comment", "--comment", "cniAPI rule") + if err != nil && !isNotExist(err) { + return nil + } + } + + ip6t, err := iptables.NewWithProtocol(iptables.ProtocolIPv6) + if err != nil { + err := ip6t.AppendUnique("filter", "FORWARD", "-m", "conntrack", "--ctstate", "INVALID", "-j", "DROP", "-m", "comment", "--comment", "cniAPI rule") + if err != nil && !isNotExist(err) { + return nil + } + } + return &CNIConfig{ Path: path, cacheDir: cacheDir,