mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
- Add iptables-nft test runner and integration test target. - Makefile to run the tests; will add buildkite later. PiperOrigin-RevId: 966434729
632 lines
15 KiB
Go
632 lines
15 KiB
Go
// Copyright 2019 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package iptables
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"net"
|
|
"slices"
|
|
"sync"
|
|
"testing"
|
|
|
|
"gvisor.dev/gvisor/pkg/log"
|
|
"gvisor.dev/gvisor/pkg/test/dockerutil"
|
|
"gvisor.dev/gvisor/pkg/test/testutil"
|
|
"gvisor.dev/gvisor/test/netutils"
|
|
)
|
|
|
|
var iptablesNFT = flag.Bool("iptables-nft", false, "run tests using iptables-nft instead of iptables-legacy")
|
|
|
|
func isNFTMode() bool {
|
|
return *iptablesNFT
|
|
}
|
|
|
|
// TODO: b/542649081 - Fix and remove skipIfNFTMode.
|
|
func skipIfNFTMode(test TestCase, ipv6 bool) (reason string, skip bool) {
|
|
if ipv6 {
|
|
return "IPv6 is not tested in nftables currently", true
|
|
}
|
|
switch test.Name() {
|
|
case
|
|
// REJECT tests
|
|
"FilterInputRejectDefault",
|
|
"FilterInputRejectDefaultUnmatched",
|
|
"FilterInputRejectTCPReset",
|
|
"FilterInputRejectTCPResetUnmatched":
|
|
|
|
return "REJECT target is not supported in nftables compat yet", true
|
|
|
|
case
|
|
// REDIRECT tests
|
|
"NATPreRedirectUDPPort",
|
|
"NATPreRedirectTCPPort",
|
|
"NATPreRedirectTCPOutgoing",
|
|
"NATOutRedirectTCPIncoming",
|
|
"NATOutRedirectUDPPort",
|
|
"NATOutRedirectTCPPort",
|
|
"NATDropUDP",
|
|
"NATPreRedirectIP",
|
|
"NATPreDontRedirectIP",
|
|
"NATPreRedirectInvert",
|
|
"NATOutRedirectIP",
|
|
"NATOutDontRedirectIP",
|
|
"NATOutRedirectInvert",
|
|
"NATRedirectRequiresProtocol",
|
|
"NATLoopbackSkipsPrerouting",
|
|
"NATPreOriginalDst",
|
|
"NATOutOriginalDst",
|
|
"NATPreRECVORIGDSTADDR",
|
|
"NATOutRECVORIGDSTADDR":
|
|
|
|
return "REDIRECT target is not supported in nftables compat yet", true
|
|
|
|
case
|
|
// Range Operation tests
|
|
"FilterInputDropTCPSrcPort",
|
|
"FilterInputDropTCPDestPort",
|
|
"FilterOutputDropTCPDestPort":
|
|
|
|
return "Range Operation not supported in nftables yet", true
|
|
|
|
case
|
|
// Multiport Match tests
|
|
"FilterInputDropAllSrcPorts",
|
|
"FilterInputDropAllExceptOneDstPort",
|
|
"FilterOutputAcceptInvertSrcPorts",
|
|
"FilterOutputDropSrcPorts",
|
|
"FilterOutputAcceptInvertPorts":
|
|
|
|
return "multiport match is not supported in nftables compat yet", true
|
|
|
|
case
|
|
// Owner Match tests
|
|
"FilterOutputAcceptTCPOwner",
|
|
"FilterOutputDropTCPOwner",
|
|
"FilterOutputAcceptUDPOwner",
|
|
"FilterOutputDropUDPOwner",
|
|
"FilterOutputOwnerFail",
|
|
"FilterOutputAcceptGIDOwner",
|
|
"FilterOutputDropGIDOwner",
|
|
"FilterOutputInvertGIDOwner",
|
|
"FilterOutputInvertUIDOwner",
|
|
"FilterOutputInvertUIDAndGIDOwner",
|
|
"FilterOutputOwnerNilAccept":
|
|
|
|
return "owner match is not supported in nftables compat yet", true
|
|
|
|
default:
|
|
return "", false
|
|
}
|
|
}
|
|
|
|
// singleTest runs a TestCase. Each test follows a pattern:
|
|
// - Create a container.
|
|
// - Get the container's IP.
|
|
// - Send the container our IP.
|
|
// - Start a new goroutine running the local action of the test.
|
|
// - Wait for both the container and local actions to finish.
|
|
//
|
|
// Container output is logged to $TEST_UNDECLARED_OUTPUTS_DIR if it exists, or
|
|
// to stderr.
|
|
func singleTest(t *testing.T, test TestCase) {
|
|
for _, tc := range []bool{false, true} {
|
|
subtest := "IPv4"
|
|
if tc {
|
|
subtest = "IPv6"
|
|
}
|
|
t.Run(subtest, func(t *testing.T) {
|
|
if isNFTMode() {
|
|
reason, skip := skipIfNFTMode(test, tc)
|
|
if skip {
|
|
t.Skip(reason)
|
|
}
|
|
}
|
|
iptablesTest(t, test, tc)
|
|
})
|
|
}
|
|
}
|
|
|
|
func iptablesTest(t *testing.T, test TestCase, ipv6 bool) {
|
|
if _, ok := Tests[test.Name()]; !ok {
|
|
log.Infof("no test found with name %q. Has it been registered?", test.Name())
|
|
t.FailNow()
|
|
}
|
|
|
|
// Wait for the local and container goroutines to finish.
|
|
var wg sync.WaitGroup
|
|
defer wg.Wait()
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), TestTimeout)
|
|
defer cancel()
|
|
|
|
d := dockerutil.MakeContainer(ctx, t)
|
|
defer func() {
|
|
if logs, err := d.Logs(context.Background()); err != nil {
|
|
log.Infof("Failed to retrieve container logs.")
|
|
} else {
|
|
log.Infof("=== Container logs: ===\n%s", logs)
|
|
}
|
|
// Use a new context, as cleanup should run even when we
|
|
// timeout.
|
|
d.CleanUp(context.Background())
|
|
}()
|
|
|
|
// Create and start the container.
|
|
opts := dockerutil.RunOpts{
|
|
Image: "iptables",
|
|
CapAdd: []string{"NET_ADMIN"},
|
|
}
|
|
d.CopyFiles(&opts, "/runner", "test/iptables/runner/runner")
|
|
args := []string{"/runner/runner", "-name", test.Name()}
|
|
if ipv6 {
|
|
args = append(args, "-ipv6")
|
|
}
|
|
if isNFTMode() {
|
|
args = append(args, "-nft")
|
|
}
|
|
if err := d.Spawn(ctx, opts, args...); err != nil {
|
|
log.Infof("docker run failed: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Get the container IP.
|
|
ip, err := d.FindIP(ctx, ipv6)
|
|
if err != nil {
|
|
// If ipv6 is not configured, don't fail.
|
|
if ipv6 && err == dockerutil.ErrNoIP {
|
|
log.Infof("No ipv6 address is available.")
|
|
t.Skip()
|
|
}
|
|
log.Infof("failed to get container IP: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Give the container our IP.
|
|
if err := sendIP(ip); err != nil {
|
|
log.Infof("failed to send IP to container: %v", err)
|
|
t.FailNow()
|
|
}
|
|
|
|
// Run our side of the test.
|
|
errCh := make(chan error, 2)
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
if err := test.LocalAction(ctx, ip, ipv6); err != nil && !errors.Is(err, context.Canceled) {
|
|
errCh <- fmt.Errorf("LocalAction failed: %v", err)
|
|
} else {
|
|
errCh <- nil
|
|
}
|
|
if test.LocalSufficient() {
|
|
errCh <- nil
|
|
}
|
|
}()
|
|
|
|
// Run the container side.
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
// Wait for the final statement. This structure has the side
|
|
// effect that all container logs will appear within the
|
|
// individual test context.
|
|
if _, err := d.WaitForOutput(ctx, TerminalStatement, TestTimeout); err != nil && !errors.Is(err, context.Canceled) {
|
|
errCh <- fmt.Errorf("ContainerAction failed: %v", err)
|
|
} else {
|
|
errCh <- nil
|
|
}
|
|
if test.ContainerSufficient() {
|
|
errCh <- nil
|
|
}
|
|
}()
|
|
|
|
for i := 0; i < 2; i++ {
|
|
if err := <-errCh; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func sendIP(ip net.IP) error {
|
|
contAddr := net.TCPAddr{
|
|
IP: ip,
|
|
Port: IPExchangePort,
|
|
}
|
|
var conn *net.TCPConn
|
|
// The container may not be listening when we first connect, so retry
|
|
// upon error.
|
|
cb := func() error {
|
|
c, err := net.DialTCP("tcp", nil, &contAddr)
|
|
conn = c
|
|
return err
|
|
}
|
|
if err := testutil.Poll(cb, TestTimeout); err != nil {
|
|
return fmt.Errorf("timed out waiting to send IP, most recent error: %v", err)
|
|
}
|
|
if _, err := conn.Write([]byte{0}); err != nil {
|
|
return fmt.Errorf("error writing to container: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestFilterInputDropUDP(t *testing.T) {
|
|
singleTest(t, &FilterInputDropUDP{})
|
|
}
|
|
|
|
func TestFilterInputDropUDPPort(t *testing.T) {
|
|
singleTest(t, &FilterInputDropUDPPort{})
|
|
}
|
|
|
|
func TestFilterInputDropDifferentUDPPort(t *testing.T) {
|
|
singleTest(t, &FilterInputDropDifferentUDPPort{})
|
|
}
|
|
|
|
func TestFilterInputDropAll(t *testing.T) {
|
|
singleTest(t, &FilterInputDropAll{})
|
|
}
|
|
|
|
func TestFilterInputDropOnlyUDP(t *testing.T) {
|
|
singleTest(t, &FilterInputDropOnlyUDP{})
|
|
}
|
|
|
|
func TestFilterInputDropTCPDestPort(t *testing.T) {
|
|
singleTest(t, &FilterInputDropTCPDestPort{})
|
|
}
|
|
|
|
func TestFilterInputDropTCPSrcPort(t *testing.T) {
|
|
singleTest(t, &FilterInputDropTCPSrcPort{})
|
|
}
|
|
|
|
func TestFilterInputCreateUserChain(t *testing.T) {
|
|
singleTest(t, &FilterInputCreateUserChain{})
|
|
}
|
|
|
|
func TestFilterInputDefaultPolicyAccept(t *testing.T) {
|
|
singleTest(t, &FilterInputDefaultPolicyAccept{})
|
|
}
|
|
|
|
func TestFilterInputDefaultPolicyDrop(t *testing.T) {
|
|
singleTest(t, &FilterInputDefaultPolicyDrop{})
|
|
}
|
|
|
|
func TestFilterInputReturnUnderflow(t *testing.T) {
|
|
singleTest(t, &FilterInputReturnUnderflow{})
|
|
}
|
|
|
|
func TestFilterOutputDropTCPDestPort(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropTCPDestPort{})
|
|
}
|
|
|
|
func TestFilterOutputDropTCPSrcPort(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropTCPSrcPort{})
|
|
}
|
|
|
|
func TestFilterOutputAcceptTCPOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputAcceptTCPOwner{})
|
|
}
|
|
|
|
func TestFilterOutputDropTCPOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropTCPOwner{})
|
|
}
|
|
|
|
func TestFilterOutputAcceptUDPOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputAcceptUDPOwner{})
|
|
}
|
|
|
|
func TestFilterOutputDropUDPOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropUDPOwner{})
|
|
}
|
|
|
|
func TestFilterOutputOwnerFail(t *testing.T) {
|
|
singleTest(t, &FilterOutputOwnerFail{})
|
|
}
|
|
|
|
func TestFilterOutputAcceptGIDOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputAcceptGIDOwner{})
|
|
}
|
|
|
|
func TestFilterOutputDropGIDOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropGIDOwner{})
|
|
}
|
|
|
|
func TestFilterOutputInvertGIDOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertGIDOwner{})
|
|
}
|
|
|
|
func TestFilterOutputInvertUIDOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertUIDOwner{})
|
|
}
|
|
|
|
func TestFilterOutputInvertUIDAndGIDOwner(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertUIDAndGIDOwner{})
|
|
}
|
|
|
|
func TestFilterOutputOwnerNilAccept(t *testing.T) {
|
|
singleTest(t, &FilterOutputOwnerNilAccept{})
|
|
}
|
|
|
|
func TestFilterOutputInterfaceAccept(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterfaceAccept{})
|
|
}
|
|
|
|
func TestFilterOutputInterfaceDrop(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterfaceDrop{})
|
|
}
|
|
|
|
func TestFilterOutputInterface(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterface{})
|
|
}
|
|
|
|
func TestFilterOutputInterfaceBeginsWith(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterfaceBeginsWith{})
|
|
}
|
|
|
|
func TestFilterOutputInterfaceInvertDrop(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterfaceInvertDrop{})
|
|
}
|
|
|
|
func TestFilterOutputInterfaceInvertAccept(t *testing.T) {
|
|
singleTest(t, &FilterOutputInterfaceInvertAccept{})
|
|
}
|
|
|
|
func TestFilterOutputInvertSportAccept(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertSportAccept{})
|
|
}
|
|
|
|
func TestFilterOutputInvertSportDrop(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertSportDrop{})
|
|
}
|
|
|
|
func TestJumpSerialize(t *testing.T) {
|
|
singleTest(t, &FilterInputSerializeJump{})
|
|
}
|
|
|
|
func TestJumpBasic(t *testing.T) {
|
|
singleTest(t, &FilterInputJumpBasic{})
|
|
}
|
|
|
|
func TestJumpReturn(t *testing.T) {
|
|
singleTest(t, &FilterInputJumpReturn{})
|
|
}
|
|
|
|
func TestJumpReturnDrop(t *testing.T) {
|
|
singleTest(t, &FilterInputJumpReturnDrop{})
|
|
}
|
|
|
|
func TestJumpBuiltin(t *testing.T) {
|
|
singleTest(t, &FilterInputJumpBuiltin{})
|
|
}
|
|
|
|
func TestJumpTwice(t *testing.T) {
|
|
singleTest(t, &FilterInputJumpTwice{})
|
|
}
|
|
|
|
func TestInputDestination(t *testing.T) {
|
|
singleTest(t, &FilterInputDestination{})
|
|
}
|
|
|
|
func TestInputInvertDestination(t *testing.T) {
|
|
singleTest(t, &FilterInputInvertDestination{})
|
|
}
|
|
|
|
func TestFilterOutputDestination(t *testing.T) {
|
|
singleTest(t, &FilterOutputDestination{})
|
|
}
|
|
|
|
func TestFilterOutputInvertDestination(t *testing.T) {
|
|
singleTest(t, &FilterOutputInvertDestination{})
|
|
}
|
|
|
|
func TestNATPreRedirectUDPPort(t *testing.T) {
|
|
singleTest(t, &NATPreRedirectUDPPort{})
|
|
}
|
|
|
|
func TestNATPreRedirectTCPPort(t *testing.T) {
|
|
singleTest(t, &NATPreRedirectTCPPort{})
|
|
}
|
|
|
|
func TestNATPreRedirectTCPOutgoing(t *testing.T) {
|
|
singleTest(t, &NATPreRedirectTCPOutgoing{})
|
|
}
|
|
|
|
func TestNATOutRedirectTCPIncoming(t *testing.T) {
|
|
singleTest(t, &NATOutRedirectTCPIncoming{})
|
|
}
|
|
func TestNATOutRedirectUDPPort(t *testing.T) {
|
|
singleTest(t, &NATOutRedirectUDPPort{})
|
|
}
|
|
|
|
func TestNATOutRedirectTCPPort(t *testing.T) {
|
|
singleTest(t, &NATOutRedirectTCPPort{})
|
|
}
|
|
|
|
func TestNATDropUDP(t *testing.T) {
|
|
singleTest(t, &NATDropUDP{})
|
|
}
|
|
|
|
func TestNATAcceptAll(t *testing.T) {
|
|
singleTest(t, &NATAcceptAll{})
|
|
}
|
|
|
|
func TestNATOutRedirectIP(t *testing.T) {
|
|
singleTest(t, &NATOutRedirectIP{})
|
|
}
|
|
|
|
func TestNATOutDontRedirectIP(t *testing.T) {
|
|
singleTest(t, &NATOutDontRedirectIP{})
|
|
}
|
|
|
|
func TestNATOutRedirectInvert(t *testing.T) {
|
|
singleTest(t, &NATOutRedirectInvert{})
|
|
}
|
|
|
|
func TestNATOutDNAT(t *testing.T) {
|
|
singleTest(t, &NATOutDNAT{})
|
|
}
|
|
|
|
func TestNATOutDNATAddrOnly(t *testing.T) {
|
|
singleTest(t, &NATOutDNATAddrOnly{})
|
|
}
|
|
|
|
func TestNATOutDNATPortOnly(t *testing.T) {
|
|
singleTest(t, &NATOutDNATPortOnly{})
|
|
}
|
|
|
|
func TestNATPreRedirectIP(t *testing.T) {
|
|
singleTest(t, &NATPreRedirectIP{})
|
|
}
|
|
|
|
func TestNATPreDontRedirectIP(t *testing.T) {
|
|
singleTest(t, &NATPreDontRedirectIP{})
|
|
}
|
|
|
|
func TestNATPreRedirectInvert(t *testing.T) {
|
|
singleTest(t, &NATPreRedirectInvert{})
|
|
}
|
|
|
|
func TestNATRedirectRequiresProtocol(t *testing.T) {
|
|
singleTest(t, &NATRedirectRequiresProtocol{})
|
|
}
|
|
|
|
func TestNATLoopbackSkipsPrerouting(t *testing.T) {
|
|
singleTest(t, &NATLoopbackSkipsPrerouting{})
|
|
}
|
|
|
|
func TestInputSource(t *testing.T) {
|
|
singleTest(t, &FilterInputSource{})
|
|
}
|
|
|
|
func TestInputInvertSource(t *testing.T) {
|
|
singleTest(t, &FilterInputInvertSource{})
|
|
}
|
|
|
|
func TestInputInterfaceAccept(t *testing.T) {
|
|
singleTest(t, &FilterInputInterfaceAccept{})
|
|
}
|
|
|
|
func TestInputInterfaceDrop(t *testing.T) {
|
|
singleTest(t, &FilterInputInterfaceDrop{})
|
|
}
|
|
|
|
func TestInputInterface(t *testing.T) {
|
|
singleTest(t, &FilterInputInterface{})
|
|
}
|
|
|
|
func TestInputInterfaceBeginsWith(t *testing.T) {
|
|
singleTest(t, &FilterInputInterfaceBeginsWith{})
|
|
}
|
|
|
|
func TestInputInterfaceInvertDrop(t *testing.T) {
|
|
singleTest(t, &FilterInputInterfaceInvertDrop{})
|
|
}
|
|
|
|
func TestInputInterfaceInvertAccept(t *testing.T) {
|
|
singleTest(t, &FilterInputInterfaceInvertAccept{})
|
|
}
|
|
|
|
func TestFilterInputInvertDportAccept(t *testing.T) {
|
|
singleTest(t, &FilterInputInvertDportAccept{})
|
|
}
|
|
|
|
func TestFilterInputInvertDportDrop(t *testing.T) {
|
|
singleTest(t, &FilterInputInvertDportDrop{})
|
|
}
|
|
|
|
func TestFilterAddrs(t *testing.T) {
|
|
tcs := []struct {
|
|
ipv6 bool
|
|
addrs []string
|
|
want []string
|
|
}{
|
|
{
|
|
ipv6: false,
|
|
addrs: []string{"192.168.0.1", "192.168.0.2/24", "::1", "::2/128"},
|
|
want: []string{"192.168.0.1", "192.168.0.2"},
|
|
},
|
|
{
|
|
ipv6: true,
|
|
addrs: []string{"192.168.0.1", "192.168.0.2/24", "::1", "::2/128"},
|
|
want: []string{"::1", "::2"},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tcs {
|
|
if got := netutils.FilterAddrs(tc.addrs, tc.ipv6); !slices.Equal(got, tc.want) {
|
|
t.Errorf("%v with IPv6 %t: got %v, but wanted %v", tc.addrs, tc.ipv6, got, tc.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNATPreOriginalDst(t *testing.T) {
|
|
singleTest(t, &NATPreOriginalDst{})
|
|
}
|
|
|
|
func TestNATOutOriginalDst(t *testing.T) {
|
|
singleTest(t, &NATOutOriginalDst{})
|
|
}
|
|
|
|
func TestNATPreRECVORIGDSTADDR(t *testing.T) {
|
|
singleTest(t, &NATPreRECVORIGDSTADDR{})
|
|
}
|
|
|
|
func TestNATOutRECVORIGDSTADDR(t *testing.T) {
|
|
singleTest(t, &NATOutRECVORIGDSTADDR{})
|
|
}
|
|
|
|
func TestNATPostSNATUDP(t *testing.T) {
|
|
singleTest(t, &NATPostSNATUDP{})
|
|
}
|
|
|
|
func TestNATPostSNATTCP(t *testing.T) {
|
|
singleTest(t, &NATPostSNATTCP{})
|
|
}
|
|
|
|
func TestFilterInputDropAllSrcPorts(t *testing.T) {
|
|
singleTest(t, &FilterInputDropAllSrcPorts{})
|
|
}
|
|
func TestFilterInputDropAllExceptOneDstPort(t *testing.T) {
|
|
singleTest(t, &FilterInputDropAllExceptOneDstPort{})
|
|
}
|
|
|
|
func TestFilterOutputAcceptInvertSrcPorts(t *testing.T) {
|
|
singleTest(t, &FilterOutputAcceptInvertSrcPorts{})
|
|
}
|
|
|
|
func TestFilterOutputDropSrcPorts(t *testing.T) {
|
|
singleTest(t, &FilterOutputDropSrcPorts{})
|
|
}
|
|
|
|
func TestFilterOutputAcceptInvertPorts(t *testing.T) {
|
|
singleTest(t, &FilterOutputAcceptInvertPorts{})
|
|
}
|
|
|
|
func TestFilterInputRejectDefault(t *testing.T) {
|
|
singleTest(t, &FilterInputRejectDefault{})
|
|
}
|
|
|
|
func TestFilterInputRejectDefaultUnmatched(t *testing.T) {
|
|
singleTest(t, &FilterInputRejectDefaultUnmatched{})
|
|
}
|
|
|
|
func TestFilterInputRejectTCPReset(t *testing.T) {
|
|
singleTest(t, &FilterInputRejectTCPReset{})
|
|
}
|
|
|
|
func TestFilterInputRejectTCPResetUnmatched(t *testing.T) {
|
|
singleTest(t, &FilterInputRejectTCPResetUnmatched{})
|
|
}
|