github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/supervisor/iptablesctrl/iptablesV6_test.go (about)

     1  // +build !windows,!rhel6
     2  
     3  package iptablesctrl
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	"fmt"
     9  	"net"
    10  	"testing"
    11  
    12  	"github.com/aporeto-inc/go-ipset/ipset"
    13  	"github.com/magiconair/properties/assert"
    14  	. "github.com/smartystreets/goconvey/convey"
    15  	"go.aporeto.io/enforcerd/trireme-lib/common"
    16  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    17  	tacls "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/acls"
    18  	provider "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/aclprovider"
    19  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/ipsetmanager"
    20  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet"
    21  	"go.aporeto.io/enforcerd/trireme-lib/controller/runtime"
    22  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    23  	"go.aporeto.io/enforcerd/trireme-lib/utils/portspec"
    24  )
    25  
    26  func testICMPAllow() string {
    27  	return "16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0"
    28  }
    29  
    30  func TestNewInstanceV6(t *testing.T) {
    31  
    32  	Convey("When I create a new iptables instance", t, func() {
    33  		Convey("If I create a remote implemenetation and iptables exists", func() {
    34  			ips := ipsetmanager.NewTestIpsetProvider()
    35  			iptv4 := provider.NewTestIptablesProvider()
    36  			iptv6 := provider.NewTestIptablesProvider()
    37  
    38  			i, err := createTestInstance(ips, iptv4, iptv6, constants.RemoteContainer, policy.None)
    39  			Convey("It should succeed", func() {
    40  				So(i, ShouldNotBeNil)
    41  				So(err, ShouldBeNil)
    42  			})
    43  		})
    44  	})
    45  
    46  	Convey("When I create a new iptables instance", t, func() {
    47  		Convey("If I create a Linux server implemenetation and iptables exists", func() {
    48  			ips := ipsetmanager.NewTestIpsetProvider()
    49  			iptv4 := provider.NewTestIptablesProvider()
    50  			iptv6 := provider.NewTestIptablesProvider()
    51  
    52  			i, err := createTestInstance(ips, iptv4, iptv6, constants.LocalServer, policy.None)
    53  			Convey("It should succeed", func() {
    54  				So(i, ShouldNotBeNil)
    55  				So(err, ShouldBeNil)
    56  			})
    57  		})
    58  	})
    59  }
    60  
    61  func Test_NegativeConfigureRulesV6(t *testing.T) {
    62  
    63  	Convey("Given a valid instance", t, func() {
    64  		ips := ipsetmanager.NewTestIpsetProvider()
    65  		iptv4 := provider.NewTestIptablesProvider()
    66  		iptv6 := provider.NewTestIptablesProvider()
    67  
    68  		i, err := createTestInstance(ips, iptv4, iptv6, constants.LocalServer, policy.None)
    69  		So(err, ShouldBeNil)
    70  
    71  		ctx, cancel := context.WithCancel(context.Background())
    72  		defer cancel()
    73  
    74  		err = i.Run(ctx)
    75  		So(err, ShouldBeNil)
    76  		cfg := &runtime.Configuration{}
    77  		i.SetTargetNetworks(cfg) // nolint
    78  
    79  		ipl := policy.ExtendedMap{}
    80  		policyrules := policy.NewPUPolicy(
    81  			"Context",
    82  			"/ns1",
    83  			policy.Police,
    84  			nil,
    85  			nil,
    86  			nil,
    87  			nil,
    88  			nil,
    89  			nil,
    90  			nil,
    91  			nil,
    92  			ipl,
    93  			0,
    94  			0,
    95  			nil,
    96  			nil,
    97  			[]string{},
    98  			policy.EnforcerMapping,
    99  			policy.Reject|policy.Log,
   100  			policy.Reject|policy.Log,
   101  		)
   102  		containerinfo := policy.NewPUInfo("Context",
   103  			"/ns1", common.ContainerPU)
   104  		containerinfo.Policy = policyrules
   105  		containerinfo.Runtime = policy.NewPURuntimeWithDefaults()
   106  		containerinfo.Runtime.SetOptions(policy.OptionsType{
   107  			CgroupMark: "10",
   108  		})
   109  
   110  		Convey("When I configure the rules with no errors, it should succeed", func() {
   111  			err := i.ConfigureRules(1,
   112  				"ID", containerinfo)
   113  			So(err, ShouldBeNil)
   114  		})
   115  
   116  		Convey("When I configure the rules and the proxy set fails, it should error", func() {
   117  			ips.MockNewIpset(t, func(name, hash string, p *ipset.Params) (ipsetmanager.Ipset, error) {
   118  				return nil, fmt.Errorf("error")
   119  			})
   120  			err := i.ConfigureRules(1,
   121  				"ID", containerinfo)
   122  			So(err, ShouldNotBeNil)
   123  		})
   124  
   125  		Convey("When I configure the rules and acls fail, it should error", func() {
   126  			iptv6.MockAppend(t, func(table, chain string, rulespec ...string) error {
   127  				return fmt.Errorf("error")
   128  			})
   129  			err := i.ConfigureRules(1,
   130  				"ID", containerinfo)
   131  			So(err, ShouldNotBeNil)
   132  		})
   133  
   134  		Convey("When I configure the rules and commit fails, it should error", func() {
   135  			iptv6.MockCommit(t, func() error {
   136  				return fmt.Errorf("error")
   137  			})
   138  			err := i.iptv6.ConfigureRules(1,
   139  				"ID", containerinfo)
   140  			So(err, ShouldNotBeNil)
   141  		})
   142  	})
   143  }
   144  
   145  var (
   146  	expectedGlobalMangleChainsV6 = map[string][]string{
   147  		"TRI-Nfq-IN": {"-j HMARK --hmark-tuple dport,sport --hmark-mod 4 --hmark-offset 67 --hmark-rnd 0xdeadbeef",
   148  			"-m mark --mark 67 -j NFQUEUE --queue-num 0 --queue-bypass",
   149  			"-m mark --mark 68 -j NFQUEUE --queue-num 1 --queue-bypass",
   150  			"-m mark --mark 69 -j NFQUEUE --queue-num 2 --queue-bypass",
   151  			"-m mark --mark 70 -j NFQUEUE --queue-num 3 --queue-bypass"},
   152  		"TRI-Nfq-OUT": {"-j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 0 --hmark-rnd 0xdeadbeef",
   153  			"-m mark --mark 0 -j NFQUEUE --queue-num 0 --queue-bypass",
   154  			"-m mark --mark 1 -j NFQUEUE --queue-num 1 --queue-bypass",
   155  			"-m mark --mark 2 -j NFQUEUE --queue-num 2 --queue-bypass",
   156  			"-m mark --mark 3 -j NFQUEUE --queue-num 3 --queue-bypass"},
   157  		"INPUT": {
   158  			"-m set ! --match-set TRI-v6-Excluded src -j TRI-Net",
   159  		},
   160  		"OUTPUT": {
   161  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-App",
   162  		},
   163  		"TRI-App": {
   164  			"-m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-p udp --dport 53 -m mark --mark 0x40 -m cgroup --cgroup 1536 -j CONNMARK --set-mark 61167", "-p udp --dport 53 -m mark --mark 0x40 -j CONNMARK --set-mark 61167", "-j TRI-Prx-App", "-m connmark --mark 61167 -j ACCEPT", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   165  			"-m connmark --mark 61166 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m connmark --mark 61166 -p udp -j ACCEPT", "-m mark --mark 1073741922 -j ACCEPT",
   166  			"-p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-OUT", "-j TRI-Pid-App", "-j TRI-Svc-App", "-j TRI-Hst-App"},
   167  		"TRI-Net": {
   168  			"-j TRI-Prx-Net", "-p tcp -m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-m connmark --mark 61167 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP src -p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-IN",
   169  			"-p udp -m string --string n30njxq7bmiwr6dtxq --algo bm --to 65535 -j TRI-Nfq-IN", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   170  			"-m connmark --mark 61166 -p udp -j ACCEPT", "-j TRI-Pid-Net", "-j TRI-Svc-Net", "-j TRI-Hst-Net"},
   171  		"TRI-Pid-App": {},
   172  		"TRI-Pid-Net": {},
   173  		"TRI-Prx-App": {
   174  			"-m mark --mark 0x40 -j ACCEPT",
   175  		},
   176  		"TRI-Prx-Net": {
   177  			"-m mark --mark 0x40 -j ACCEPT",
   178  		},
   179  		"TRI-Hst-App": {},
   180  		"TRI-Hst-Net": {},
   181  		"TRI-Svc-App": {},
   182  		"TRI-Svc-Net": {},
   183  	}
   184  
   185  	expectedGlobalNATChainsV6 = map[string][]string{
   186  		"PREROUTING": {
   187  			"-p tcp -m addrtype --dst-type LOCAL -m set ! --match-set TRI-v6-Excluded src -j TRI-Redir-Net",
   188  		},
   189  		"OUTPUT": {
   190  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-Redir-App",
   191  		},
   192  		"TRI-Redir-App": {
   193  			"-m mark --mark 0x40 -j RETURN",
   194  		},
   195  		"TRI-Redir-Net": {
   196  			"-m mark --mark 0x40 -j ACCEPT",
   197  		},
   198  	}
   199  
   200  	expectedMangleAfterPUInsertV6 = map[string][]string{
   201  		"TRI-Nfq-IN": {"-j HMARK --hmark-tuple dport,sport --hmark-mod 4 --hmark-offset 67 --hmark-rnd 0xdeadbeef",
   202  			"-m mark --mark 67 -j NFQUEUE --queue-num 0 --queue-bypass",
   203  			"-m mark --mark 68 -j NFQUEUE --queue-num 1 --queue-bypass",
   204  			"-m mark --mark 69 -j NFQUEUE --queue-num 2 --queue-bypass",
   205  			"-m mark --mark 70 -j NFQUEUE --queue-num 3 --queue-bypass"},
   206  		"TRI-Nfq-OUT": {"-j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 0 --hmark-rnd 0xdeadbeef",
   207  			"-m mark --mark 0 -j NFQUEUE --queue-num 0 --queue-bypass",
   208  			"-m mark --mark 1 -j NFQUEUE --queue-num 1 --queue-bypass",
   209  			"-m mark --mark 2 -j NFQUEUE --queue-num 2 --queue-bypass",
   210  			"-m mark --mark 3 -j NFQUEUE --queue-num 3 --queue-bypass"},
   211  		"INPUT": {
   212  			"-m set ! --match-set TRI-v6-Excluded src -j TRI-Net",
   213  		},
   214  		"OUTPUT": {
   215  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-App",
   216  		},
   217  		"TRI-App": {
   218  			"-m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-p udp --dport 53 -m mark --mark 0x40 -m cgroup --cgroup 1536 -j CONNMARK --set-mark 61167", "-p udp --dport 53 -m mark --mark 0x40 -j CONNMARK --set-mark 61167", "-j TRI-Prx-App", "-m connmark --mark 61167 -j ACCEPT", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP", "-m connmark --mark 61166 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT",
   219  			"-m connmark --mark 61166 -p udp -j ACCEPT", "-m mark --mark 1073741922 -j ACCEPT",
   220  			"-p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-OUT", "-j TRI-Pid-App", "-j TRI-Svc-App", "-j TRI-Hst-App"},
   221  		"TRI-Net": {
   222  			"-j TRI-Prx-Net", "-p tcp -m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-m connmark --mark 61167 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP src -p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-IN",
   223  			"-p udp -m string --string n30njxq7bmiwr6dtxq --algo bm --to 65535 -j TRI-Nfq-IN", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   224  			"-m connmark --mark 61166 -p udp -j ACCEPT", "-j TRI-Pid-Net", "-j TRI-Svc-Net", "-j TRI-Hst-Net"},
   225  		"TRI-Pid-App": {
   226  			"-m cgroup --cgroup 10 -m comment --comment PU-Chain -j MARK --set-mark 10",
   227  			"-m mark --mark 10 -m comment --comment PU-Chain -j TRI-App-pu1N7uS6--0"},
   228  		"TRI-Pid-Net": {
   229  			"-p tcp -m multiport --destination-ports 9000 -m comment --comment PU-Chain -j TRI-Net-pu1N7uS6--0",
   230  			"-p udp -m multiport --destination-ports 5000 -m comment --comment PU-Chain -j TRI-Net-pu1N7uS6--0",
   231  		},
   232  		"TRI-Prx-App": {
   233  			"-m mark --mark 0x40 -j ACCEPT",
   234  			"-p tcp -m tcp --sport 0 -j ACCEPT",
   235  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -j ACCEPT",
   236  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst dst,dst -m mark ! --mark 0x40 -j ACCEPT",
   237  			"-p udp -m udp --sport 0 -j ACCEPT",
   238  		},
   239  		"TRI-Prx-Net": {
   240  			"-m mark --mark 0x40 -j ACCEPT",
   241  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst src,src -j ACCEPT",
   242  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -m addrtype --src-type LOCAL -j ACCEPT",
   243  			"-p tcp -m tcp --dport 0 -j ACCEPT",
   244  			"-p udp -m udp --dport 0 -j ACCEPT",
   245  		},
   246  		"TRI-Hst-App": {},
   247  		"TRI-Hst-Net": {},
   248  		"TRI-Svc-App": {},
   249  		"TRI-Svc-Net": {},
   250  
   251  		"TRI-Net-pu1N7uS6--0": {
   252  			"-p tcp -m tcp --tcp-option 34 -m tcp --tcp-flags FIN,RST,URG,PSH NONE -j TRI-Nfq-IN",
   253  			"-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= src -m state --state ESTABLISHED -m connmark --mark 61167 -j ACCEPT",
   254  			"-p TCP -m set --match-set TRI-v6-ext-w5frVvhsnpU= src -m state --state NEW --match multiport --dports 80 -j DROP",
   255  			"-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= src -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 --match multiport --dports 443 -j CONNMARK --set-mark 61167",
   256  			"-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= src -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 --match multiport --dports 443 -j ACCEPT",
   257  			"-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT",
   258  			"-p tcp -m set --match-set TRI-v6-TargetTCP src -m tcp --tcp-flags SYN NONE -j TRI-Nfq-IN",
   259  			"-p udp -m set --match-set TRI-v6-TargetUDP src --match limit --limit 1000/s -j TRI-Nfq-IN",
   260  			"-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT",
   261  			"-s ::/0 -m state --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:6",
   262  			"-s ::/0 -m state ! --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:10",
   263  			"-s ::/0 -j DROP",
   264  		},
   265  		"TRI-App-pu1N7uS6--0": {
   266  			"-p TCP -m set --match-set TRI-v6-ext-uNdc0vdcFZA= dst -m state --state NEW --match multiport --dports 80 -j DROP", "-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= dst -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 -m set ! --match-set TRI-v6-TargetUDP dst --match multiport --dports 443 -j CONNMARK --set-mark 61167", "-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= dst -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 -m set ! --match-set TRI-v6-TargetUDP dst --match multiport --dports 443 -j ACCEPT", "-p icmpv6 -m set --match-set TRI-v6-ext-w5frVvhsnpU= dst -j ACCEPT", "-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= dst -m state --state ESTABLISHED -m connmark --mark 61167 -j ACCEPT", "-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -m tcp --tcp-flags FIN FIN -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 40 --hmark-rnd 0xdeadbeef", "-p udp -m set --match-set TRI-v6-TargetUDP dst -j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 40 --hmark-rnd 0xdeadbeef", "-m mark --mark 40 -j NFQUEUE --queue-num 0 --queue-bypass", "-m mark --mark 41 -j NFQUEUE --queue-num 1 --queue-bypass", "-m mark --mark 42 -j NFQUEUE --queue-num 2 --queue-bypass", "-m mark --mark 43 -j NFQUEUE --queue-num 3 --queue-bypass",
   267  			"-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT", "-p udp -m state --state ESTABLISHED -m comment --comment UDP-Established-Connections -j ACCEPT",
   268  			"-d ::/0 -m state --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:6", "-d ::/0 -m state ! --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:10", "-d ::/0 -j DROP"},
   269  	}
   270  
   271  	expectedNATAfterPUInsertV6 = map[string][]string{
   272  		"PREROUTING": {
   273  			"-p tcp -m addrtype --dst-type LOCAL -m set ! --match-set TRI-v6-Excluded src -j TRI-Redir-Net",
   274  		},
   275  		"OUTPUT": {
   276  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-Redir-App",
   277  		},
   278  		"TRI-Redir-App": {
   279  			"-m mark --mark 0x40 -j RETURN",
   280  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst dst,dst -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j REDIRECT --to-ports 0",
   281  			"-d ::/0 -p udp --dport 53 -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j CONNMARK --save-mark",
   282  			"-d ::/0 -p udp --dport 53 -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j REDIRECT --to-ports 0",
   283  		},
   284  		"TRI-Redir-Net": {
   285  			"-m mark --mark 0x40 -j ACCEPT",
   286  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv dst -m mark ! --mark 0x40 -j REDIRECT --to-ports 0",
   287  		},
   288  		"POSTROUTING": {
   289  			"-p udp -m addrtype --src-type LOCAL -m multiport --source-ports 5000 -j ACCEPT",
   290  		},
   291  	}
   292  
   293  	expectedMangleAfterPUUpdateV6 = map[string][]string{
   294  		"TRI-Nfq-IN": {"-j HMARK --hmark-tuple dport,sport --hmark-mod 4 --hmark-offset 67 --hmark-rnd 0xdeadbeef",
   295  			"-m mark --mark 67 -j NFQUEUE --queue-num 0 --queue-bypass",
   296  			"-m mark --mark 68 -j NFQUEUE --queue-num 1 --queue-bypass",
   297  			"-m mark --mark 69 -j NFQUEUE --queue-num 2 --queue-bypass",
   298  			"-m mark --mark 70 -j NFQUEUE --queue-num 3 --queue-bypass"},
   299  		"TRI-Nfq-OUT": {"-j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 0 --hmark-rnd 0xdeadbeef",
   300  			"-m mark --mark 0 -j NFQUEUE --queue-num 0 --queue-bypass",
   301  			"-m mark --mark 1 -j NFQUEUE --queue-num 1 --queue-bypass",
   302  			"-m mark --mark 2 -j NFQUEUE --queue-num 2 --queue-bypass",
   303  			"-m mark --mark 3 -j NFQUEUE --queue-num 3 --queue-bypass"},
   304  		"INPUT": {
   305  			"-m set ! --match-set TRI-v6-Excluded src -j TRI-Net",
   306  		},
   307  		"OUTPUT": {
   308  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-App",
   309  		},
   310  		"TRI-App": {
   311  			"-m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-p udp --dport 53 -m mark --mark 0x40 -m cgroup --cgroup 1536 -j CONNMARK --set-mark 61167", "-p udp --dport 53 -m mark --mark 0x40 -j CONNMARK --set-mark 61167", "-j TRI-Prx-App", "-m connmark --mark 61167 -j ACCEPT", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   312  			"-m connmark --mark 61166 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m connmark --mark 61166 -p udp -j ACCEPT", "-m mark --mark 1073741922 -j ACCEPT",
   313  			"-p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-OUT", "-j TRI-Pid-App", "-j TRI-Svc-App", "-j TRI-Hst-App"},
   314  		"TRI-Net": {
   315  			"-j TRI-Prx-Net", "-p tcp -m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-m connmark --mark 61167 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP src -p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-IN", "-p udp -m string --string n30njxq7bmiwr6dtxq --algo bm --to 65535 -j TRI-Nfq-IN", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   316  			"-m connmark --mark 61166 -p udp -j ACCEPT", "-j TRI-Pid-Net", "-j TRI-Svc-Net", "-j TRI-Hst-Net"},
   317  		"TRI-Pid-App": {
   318  			"-m cgroup --cgroup 10 -m comment --comment PU-Chain -j MARK --set-mark 10",
   319  			"-m mark --mark 10 -m comment --comment PU-Chain -j TRI-App-pu1N7uS6--1"},
   320  		"TRI-Pid-Net": {
   321  			"-p tcp -m set --match-set TRI-v6-ProcPort-pu19gtV dst -m comment --comment PU-Chain -j TRI-Net-pu1N7uS6--1",
   322  		},
   323  		"TRI-Prx-App": {
   324  			"-m mark --mark 0x40 -j ACCEPT",
   325  			"-p tcp -m tcp --sport 0 -j ACCEPT",
   326  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -j ACCEPT",
   327  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst dst,dst -m mark ! --mark 0x40 -j ACCEPT",
   328  			"-p udp -m udp --sport 0 -j ACCEPT",
   329  		},
   330  		"TRI-Prx-Net": {
   331  			"-m mark --mark 0x40 -j ACCEPT",
   332  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst src,src -j ACCEPT",
   333  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -m addrtype --src-type LOCAL -j ACCEPT",
   334  			"-p tcp -m tcp --dport 0 -j ACCEPT",
   335  			"-p udp -m udp --dport 0 -j ACCEPT",
   336  		},
   337  		"TRI-Hst-App": {},
   338  		"TRI-Hst-Net": {},
   339  		"TRI-Svc-App": {},
   340  		"TRI-Svc-Net": {},
   341  
   342  		"TRI-Net-pu1N7uS6--1": {
   343  			"-p tcp -m tcp --tcp-option 34 -m tcp --tcp-flags FIN,RST,URG,PSH NONE -j TRI-Nfq-IN",
   344  			"-p TCP -m set --match-set TRI-v6-ext-w5frVvhsnpU= src -m state --state NEW --match multiport --dports 80 -j DROP",
   345  			"-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT",
   346  			"-p tcp -m set --match-set TRI-v6-TargetTCP src -m tcp --tcp-flags SYN NONE -j TRI-Nfq-IN",
   347  			"-p udp -m set --match-set TRI-v6-TargetUDP src --match limit --limit 1000/s -j TRI-Nfq-IN",
   348  			"-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT",
   349  			"-s ::/0 -m state --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:6",
   350  			"-s ::/0 -m state ! --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:10",
   351  			"-s ::/0 -j DROP"},
   352  		"TRI-App-pu1N7uS6--1": {
   353  			"-p TCP -m set --match-set TRI-v6-ext-uNdc0vdcFZA= dst -m state --state NEW --match multiport --dports 80 -j DROP", "-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -m tcp --tcp-flags FIN FIN -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 40 --hmark-rnd 0xdeadbeef", "-p udp -m set --match-set TRI-v6-TargetUDP dst -j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 40 --hmark-rnd 0xdeadbeef", "-m mark --mark 40 -j NFQUEUE --queue-num 0 --queue-bypass", "-m mark --mark 41 -j NFQUEUE --queue-num 1 --queue-bypass", "-m mark --mark 42 -j NFQUEUE --queue-num 2 --queue-bypass", "-m mark --mark 43 -j NFQUEUE --queue-num 3 --queue-bypass",
   354  			"-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT", "-p udp -m state --state ESTABLISHED -m comment --comment UDP-Established-Connections -j ACCEPT",
   355  			"-d ::/0 -m state --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:6", "-d ::/0 -m state ! --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:10", "-d ::/0 -j DROP"},
   356  	}
   357  )
   358  
   359  func Test_OperationWithLinuxServicesV6(t *testing.T) {
   360  
   361  	Convey("Given an iptables controller with a memory backend ", t, func() {
   362  		cfg := &runtime.Configuration{
   363  			TCPTargetNetworks: []string{"::/0"},
   364  			UDPTargetNetworks: []string{"1120::/64"},
   365  			ExcludedNetworks:  []string{"::1"},
   366  		}
   367  
   368  		commitFunc := func(buf *bytes.Buffer) error {
   369  			return nil
   370  		}
   371  
   372  		iptv4 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   373  			"mangle"})
   374  		So(iptv4, ShouldNotBeNil)
   375  
   376  		iptv6 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   377  			"mangle"})
   378  		So(iptv6, ShouldNotBeNil)
   379  
   380  		ips := &memoryIPSetProvider{sets: map[string]*memoryIPSet{}}
   381  		i, err := createTestInstance(ips, iptv4, iptv6, constants.LocalServer, policy.None)
   382  		So(err, ShouldBeNil)
   383  		So(i, ShouldNotBeNil)
   384  
   385  		Convey("When I start the controller, I should get the right global chains and ipsets", func() {
   386  			ctx, cancel := context.WithCancel(context.Background())
   387  			defer cancel()
   388  			err := i.Run(ctx)
   389  			i.SetTargetNetworks(cfg) // nolint
   390  
   391  			So(err, ShouldBeNil)
   392  
   393  			t := i.iptv6.impl.RetrieveTable()
   394  			So(t, ShouldNotBeNil)
   395  			So(len(t), ShouldEqual, 2)
   396  			So(t["mangle"], ShouldNotBeNil)
   397  			So(t["nat"], ShouldNotBeNil)
   398  
   399  			for chain, rules := range t["mangle"] {
   400  				So(expectedGlobalMangleChainsV6, ShouldContainKey, chain)
   401  				So(rules, ShouldResemble, expectedGlobalMangleChainsV6[chain])
   402  			}
   403  
   404  			for chain, rules := range t["nat"] {
   405  				So(expectedGlobalNATChainsV6, ShouldContainKey, chain)
   406  				So(rules, ShouldResemble, expectedGlobalNATChainsV6[chain])
   407  			}
   408  
   409  			Convey("When I configure a new set of rules, the ACLs must be correct", func() {
   410  
   411  				appACLs := policy.IPRuleList{
   412  					policy.IPRule{
   413  						Addresses: []string{"1120::/64"},
   414  						Ports:     []string{"80"},
   415  						Protocols: []string{"TCP"},
   416  						Policy: &policy.FlowPolicy{
   417  							Action:    policy.Reject,
   418  							ServiceID: "s1",
   419  							PolicyID:  "1",
   420  						},
   421  					},
   422  					policy.IPRule{
   423  						Addresses: []string{"1120::/64"},
   424  						Ports:     []string{"443"},
   425  						Protocols: []string{"UDP"},
   426  						Policy: &policy.FlowPolicy{
   427  							Action:    policy.Accept,
   428  							ServiceID: "s2",
   429  							PolicyID:  "2",
   430  						},
   431  					},
   432  					policy.IPRule{
   433  						Addresses: []string{"1122::/64"},
   434  						Ports:     []string{"443"},
   435  						Protocols: []string{"icmpv6"},
   436  						Policy: &policy.FlowPolicy{
   437  							Action:    policy.Accept,
   438  							ServiceID: "s3",
   439  							PolicyID:  "3",
   440  						},
   441  					},
   442  					policy.IPRule{
   443  						Addresses: []string{"40.0.0.0/24"},
   444  						Ports:     []string{"443"},
   445  						Protocols: []string{"icmp"},
   446  						Policy: &policy.FlowPolicy{
   447  							Action:    policy.Accept,
   448  							ServiceID: "s3",
   449  							PolicyID:  "3",
   450  						},
   451  					},
   452  				}
   453  				netACLs := policy.IPRuleList{
   454  					policy.IPRule{
   455  						Addresses: []string{"1122::/64"},
   456  						Ports:     []string{"80"},
   457  						Protocols: []string{"TCP"},
   458  						Policy: &policy.FlowPolicy{
   459  							Action:    policy.Reject,
   460  							ServiceID: "s3",
   461  							PolicyID:  "1",
   462  						},
   463  					},
   464  					policy.IPRule{
   465  						Addresses: []string{"1122::/64"},
   466  						Ports:     []string{"443"},
   467  						Protocols: []string{"UDP"},
   468  						Policy: &policy.FlowPolicy{
   469  							Action:    policy.Accept,
   470  							ServiceID: "s4",
   471  							PolicyID:  "2",
   472  						},
   473  					},
   474  				}
   475  				ipl := policy.ExtendedMap{}
   476  				policyrules := policy.NewPUPolicy(
   477  					"Context",
   478  					"/ns1",
   479  					policy.Police,
   480  					appACLs,
   481  					netACLs,
   482  					nil,
   483  					nil,
   484  					nil,
   485  					nil,
   486  					nil,
   487  					nil,
   488  					ipl,
   489  					0,
   490  					0,
   491  					nil,
   492  					nil,
   493  					[]string{},
   494  					policy.EnforcerMapping,
   495  					policy.Reject|policy.Log,
   496  					policy.Reject|policy.Log,
   497  				)
   498  				puInfo := policy.NewPUInfo("Context",
   499  					"/ns1", common.LinuxProcessPU)
   500  				puInfo.Policy = policyrules
   501  				puInfo.Runtime.SetOptions(policy.OptionsType{
   502  					CgroupMark: "10",
   503  				})
   504  
   505  				udpPortSpec, err := portspec.NewPortSpecFromString("5000", nil)
   506  				So(err, ShouldBeNil)
   507  				tcpPortSpec, err := portspec.NewPortSpecFromString("9000", nil)
   508  				So(err, ShouldBeNil)
   509  
   510  				puInfo.Runtime.SetServices([]common.Service{
   511  					{
   512  						Ports:    udpPortSpec,
   513  						Protocol: 17,
   514  					},
   515  					{
   516  						Ports:    tcpPortSpec,
   517  						Protocol: 6,
   518  					},
   519  				})
   520  
   521  				var iprules policy.IPRuleList
   522  				iprules = append(iprules, puInfo.Policy.ApplicationACLs()...)
   523  				iprules = append(iprules, puInfo.Policy.NetworkACLs()...)
   524  				i.iptv6.ipsetmanager.RegisterExternalNets("pu1", iprules) // nolint
   525  
   526  				err = i.ConfigureRules(0,
   527  					"pu1", puInfo)
   528  				So(err, ShouldBeNil)
   529  				t := i.iptv6.impl.RetrieveTable()
   530  
   531  				for chain, rules := range t["mangle"] {
   532  					So(expectedMangleAfterPUInsertV6, ShouldContainKey, chain)
   533  					So(rules, ShouldResemble, expectedMangleAfterPUInsertV6[chain])
   534  				}
   535  
   536  				for chain, rules := range t["nat"] {
   537  					So(expectedNATAfterPUInsertV6, ShouldContainKey, chain)
   538  					So(rules, ShouldResemble, expectedNATAfterPUInsertV6[chain])
   539  				}
   540  
   541  				Convey("When I update the policy, the update must result in correct state", func() {
   542  					appACLs := policy.IPRuleList{
   543  						policy.IPRule{
   544  							Addresses: []string{"1120::/64"},
   545  							Ports:     []string{"80"},
   546  							Protocols: []string{"TCP"},
   547  							Policy: &policy.FlowPolicy{
   548  								Action:    policy.Reject,
   549  								ServiceID: "s1",
   550  								PolicyID:  "1",
   551  							},
   552  						},
   553  					}
   554  					netACLs := policy.IPRuleList{
   555  						policy.IPRule{
   556  							Addresses: []string{"1122::/64"},
   557  							Ports:     []string{"80"},
   558  							Protocols: []string{"TCP"},
   559  							Policy: &policy.FlowPolicy{
   560  								Action:    policy.Reject,
   561  								ServiceID: "s3",
   562  								PolicyID:  "1",
   563  							},
   564  						},
   565  					}
   566  					ipl := policy.ExtendedMap{}
   567  					policyrules := policy.NewPUPolicy(
   568  						"Context",
   569  						"/ns1",
   570  						policy.Police,
   571  						appACLs,
   572  						netACLs,
   573  						nil,
   574  						nil,
   575  						nil,
   576  						nil,
   577  						nil,
   578  						nil,
   579  						ipl,
   580  						0,
   581  						0,
   582  						nil,
   583  						nil,
   584  						[]string{},
   585  						policy.EnforcerMapping,
   586  						policy.Reject|policy.Log,
   587  						policy.Reject|policy.Log,
   588  					)
   589  					puInfoUpdated := policy.NewPUInfo("Context",
   590  						"/ns1", common.LinuxProcessPU)
   591  					puInfoUpdated.Policy = policyrules
   592  					puInfoUpdated.Runtime.SetOptions(policy.OptionsType{
   593  						CgroupMark: "10",
   594  					})
   595  
   596  					err := i.UpdateRules(1,
   597  						"pu1", puInfoUpdated, puInfo)
   598  					So(err, ShouldBeNil)
   599  
   600  					t := i.iptv6.impl.RetrieveTable()
   601  					for chain, rules := range t["mangle"] {
   602  						So(expectedMangleAfterPUUpdateV6, ShouldContainKey, chain)
   603  						So(rules, ShouldResemble, expectedMangleAfterPUUpdateV6[chain])
   604  					}
   605  
   606  					Convey("When I delete the same rule, the chains must be restored in the global state", func() {
   607  						err := i.DeleteRules(1,
   608  							"pu1",
   609  							"0",
   610  							"5000",
   611  							"10",
   612  							"", puInfoUpdated)
   613  						So(err, ShouldBeNil)
   614  
   615  						t := i.iptv6.impl.RetrieveTable()
   616  
   617  						So(t["mangle"], ShouldNotBeNil)
   618  						So(t["nat"], ShouldNotBeNil)
   619  
   620  						for chain, rules := range t["mangle"] {
   621  							So(expectedGlobalMangleChainsV6, ShouldContainKey, chain)
   622  							So(rules, ShouldResemble, expectedGlobalMangleChainsV6[chain])
   623  						}
   624  
   625  						for chain, rules := range t["nat"] {
   626  							if len(rules) > 0 {
   627  								So(expectedGlobalNATChainsV6, ShouldContainKey, chain)
   628  								So(rules, ShouldResemble, expectedGlobalNATChainsV6[chain])
   629  							}
   630  						}
   631  					})
   632  				})
   633  			})
   634  		})
   635  	})
   636  }
   637  
   638  func Test_OperationNomatchIpsetsV6(t *testing.T) {
   639  
   640  	Convey("Given an iptables controller with a memory backend ", t, func() {
   641  		cfg := &runtime.Configuration{
   642  			TCPTargetNetworks: []string{"::/0",
   643  				"!2001:db8:1234::/48"},
   644  			UDPTargetNetworks: []string{"1120::/64"},
   645  			ExcludedNetworks:  []string{"::1"},
   646  		}
   647  
   648  		commitFunc := func(buf *bytes.Buffer) error {
   649  			return nil
   650  		}
   651  
   652  		iptv4 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   653  			"mangle"})
   654  		So(iptv4, ShouldNotBeNil)
   655  
   656  		iptv6 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   657  			"mangle"})
   658  		So(iptv6, ShouldNotBeNil)
   659  
   660  		ips := &memoryIPSetProvider{sets: map[string]*memoryIPSet{}}
   661  		i, err := createTestInstance(ips, iptv4, iptv6, constants.LocalServer, policy.None)
   662  		So(err, ShouldBeNil)
   663  		So(i, ShouldNotBeNil)
   664  
   665  		Convey("When I start the controller, I should get the right global chains and ipsets", func() {
   666  			ctx, cancel := context.WithCancel(context.Background())
   667  			defer cancel()
   668  			err := i.Run(ctx)
   669  			i.SetTargetNetworks(cfg) // nolint
   670  
   671  			So(err, ShouldBeNil)
   672  
   673  			So(ips.sets, ShouldContainKey,
   674  				"TRI-v6-TargetTCP")
   675  			So(ips.sets["TRI-v6-TargetTCP"].set, ShouldContainKey,
   676  				"2001:db8:1234::/48")
   677  			So(ips.sets["TRI-v6-TargetTCP"].set["2001:db8:1234::/48"], ShouldBeTrue)
   678  			So(ips.sets["TRI-v6-TargetTCP"].set, ShouldContainKey,
   679  				"::/1")
   680  			So(ips.sets["TRI-v6-TargetTCP"].set["::/1"], ShouldBeFalse)
   681  			So(ips.sets["TRI-v6-TargetTCP"].set, ShouldContainKey,
   682  				"8000::/1")
   683  			So(ips.sets["TRI-v6-TargetTCP"].set["8000::/1"], ShouldBeFalse)
   684  		})
   685  	})
   686  }
   687  
   688  func Test_OperationNomatchIpsetsInExternalNetworksV6(t *testing.T) {
   689  
   690  	Convey("Given an iptables controller with a memory backend ", t, func() {
   691  		cfg := &runtime.Configuration{
   692  			TCPTargetNetworks: []string{"::/0",
   693  				"!2001:db8:1234::/48"},
   694  			UDPTargetNetworks: []string{"1120::/64"},
   695  			ExcludedNetworks:  []string{"::1"},
   696  		}
   697  
   698  		commitFunc := func(buf *bytes.Buffer) error {
   699  			return nil
   700  		}
   701  
   702  		iptv4 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   703  			"mangle"})
   704  		So(iptv4, ShouldNotBeNil)
   705  
   706  		iptv6 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   707  			"mangle"})
   708  		So(iptv6, ShouldNotBeNil)
   709  
   710  		ips := &memoryIPSetProvider{sets: map[string]*memoryIPSet{}}
   711  		i, err := createTestInstance(ips, iptv4, iptv6, constants.LocalServer, policy.None)
   712  		So(err, ShouldBeNil)
   713  		So(i, ShouldNotBeNil)
   714  
   715  		Convey("When I start the controller, I should get the right global chains and ipsets", func() {
   716  			ctx, cancel := context.WithCancel(context.Background())
   717  			defer cancel()
   718  			err := i.Run(ctx)
   719  			i.SetTargetNetworks(cfg) // nolint
   720  
   721  			So(err, ShouldBeNil)
   722  
   723  			// Setup external networks
   724  			appACLs := policy.IPRuleList{
   725  				policy.IPRule{
   726  					Addresses: []string{"::/0",
   727  						"!2001:db8:1234::/48"},
   728  					Ports:     []string{"80"},
   729  					Protocols: []string{constants.TCPProtoNum},
   730  					Policy: &policy.FlowPolicy{
   731  						Action:    policy.Accept | policy.Log,
   732  						ServiceID: "a3",
   733  						PolicyID:  "1234a",
   734  					},
   735  				},
   736  			}
   737  			netACLs := policy.IPRuleList{}
   738  
   739  			policyRules := policy.NewPUPolicy("Context",
   740  				"/ns1", policy.Police, appACLs, netACLs, nil, nil, nil, nil, nil, nil, nil, 20992, 0, nil, nil, []string{}, policy.EnforcerMapping, policy.Reject|policy.Log, policy.Reject|policy.Log)
   741  
   742  			puInfo := policy.NewPUInfo("Context",
   743  				"/ns1", common.HostPU)
   744  			puInfo.Policy = policyRules
   745  			puInfo.Runtime = policy.NewPURuntimeWithDefaults()
   746  			puInfo.Runtime.SetPUType(common.HostPU)
   747  			puInfo.Runtime.SetOptions(policy.OptionsType{
   748  				CgroupMark: "10",
   749  			})
   750  
   751  			// configure rules
   752  			var iprules policy.IPRuleList
   753  			iprules = append(iprules, puInfo.Policy.ApplicationACLs()...)
   754  			iprules = append(iprules, puInfo.Policy.NetworkACLs()...)
   755  			err = i.iptv4.ipsetmanager.RegisterExternalNets("pu1", iprules)
   756  			So(err, ShouldBeNil)
   757  			err = i.iptv6.ipsetmanager.RegisterExternalNets("pu1", iprules)
   758  			So(err, ShouldBeNil)
   759  
   760  			err = i.ConfigureRules(0,
   761  				"pu1", puInfo)
   762  			So(err, ShouldBeNil)
   763  
   764  			// Check ipsets
   765  			setName := i.iptv6.ipsetmanager.GetACLIPsetsNames(appACLs[0:1])[0]
   766  			So(ips.sets[setName].set, ShouldContainKey,
   767  				"::/1")
   768  			So(ips.sets[setName].set, ShouldContainKey,
   769  				"8000::/1")
   770  			So(ips.sets[setName].set, ShouldContainKey,
   771  				"2001:db8:1234::/48")
   772  			So(ips.sets[setName].set["::/1"], ShouldBeFalse)
   773  			So(ips.sets[setName].set["8000::/1"], ShouldBeFalse)
   774  			So(ips.sets[setName].set["2001:db8:1234::/48"], ShouldBeTrue)
   775  
   776  			// Configure and check acl cache
   777  			aclCache := tacls.NewACLCache()
   778  			err = aclCache.AddRuleList(puInfo.Policy.ApplicationACLs())
   779  			So(err, ShouldBeNil)
   780  			defaultFlowPolicy := &policy.FlowPolicy{Action: policy.Reject | policy.Log, PolicyID: "default", ServiceID: "default"}
   781  
   782  			report, _, err := aclCache.GetMatchingAction(net.ParseIP("2001:db8:5678::"), 80, packet.IPProtocolTCP, defaultFlowPolicy)
   783  			So(err, ShouldBeNil)
   784  			So(report.Action, ShouldEqual, policy.Accept|policy.Log)
   785  
   786  			report, _, err = aclCache.GetMatchingAction(net.ParseIP("2001:db8:1234:5678::"), 80, packet.IPProtocolTCP, defaultFlowPolicy)
   787  			So(err, ShouldNotBeNil)
   788  			So(report.Action, ShouldEqual, policy.Reject|policy.Log)
   789  		})
   790  	})
   791  }
   792  
   793  var (
   794  	expectedContainerGlobalMangleChainsV6 = map[string][]string{
   795  		"TRI-Nfq-IN": {"-j HMARK --hmark-tuple dport,sport --hmark-mod 4 --hmark-offset 67 --hmark-rnd 0xdeadbeef",
   796  			"-m mark --mark 67 -j NFQUEUE --queue-num 0 --queue-bypass",
   797  			"-m mark --mark 68 -j NFQUEUE --queue-num 1 --queue-bypass",
   798  			"-m mark --mark 69 -j NFQUEUE --queue-num 2 --queue-bypass",
   799  			"-m mark --mark 70 -j NFQUEUE --queue-num 3 --queue-bypass"},
   800  		"TRI-Nfq-OUT": {"-j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 0 --hmark-rnd 0xdeadbeef",
   801  			"-m mark --mark 0 -j NFQUEUE --queue-num 0 --queue-bypass",
   802  			"-m mark --mark 1 -j NFQUEUE --queue-num 1 --queue-bypass",
   803  			"-m mark --mark 2 -j NFQUEUE --queue-num 2 --queue-bypass",
   804  			"-m mark --mark 3 -j NFQUEUE --queue-num 3 --queue-bypass"},
   805  		"INPUT": {
   806  			"-m set ! --match-set TRI-v6-Excluded src -j TRI-Net",
   807  		},
   808  		"OUTPUT": {
   809  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-App",
   810  		},
   811  		"TRI-App": {
   812  			"-m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-p udp --dport 53 -m mark --mark 0x40 -m cgroup --cgroup 1536 -j CONNMARK --set-mark 61167", "-p udp --dport 53 -m mark --mark 0x40 -j CONNMARK --set-mark 61167", "-j TRI-Prx-App", "-m connmark --mark 61167 -j ACCEPT", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP",
   813  			"-m connmark --mark 61166 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m connmark --mark 61166 -p udp -j ACCEPT",
   814  			"-m mark --mark 1073741922 -j ACCEPT", "-p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-OUT"},
   815  		"TRI-Net": {
   816  			"-j TRI-Prx-Net", "-p tcp -m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-m connmark --mark 61167 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT",
   817  			"-m set --match-set TRI-v6-TargetTCP src -p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-IN", "-p udp -m string --string n30njxq7bmiwr6dtxq --algo bm --to 65535 -j TRI-Nfq-IN", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP", "-m connmark --mark 61166 -p udp -j ACCEPT",
   818  		},
   819  		"TRI-Prx-App": {
   820  			"-m mark --mark 0x40 -j ACCEPT",
   821  		},
   822  		"TRI-Prx-Net": {
   823  			"-m mark --mark 0x40 -j ACCEPT",
   824  		},
   825  	}
   826  
   827  	expectedContainerGlobalNATChainsV6 = map[string][]string{
   828  		"PREROUTING": {
   829  			"-p tcp -m addrtype --dst-type LOCAL -m set ! --match-set TRI-v6-Excluded src -j TRI-Redir-Net",
   830  		},
   831  		"OUTPUT": {
   832  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-Redir-App",
   833  		},
   834  		"TRI-Redir-App": {
   835  			"-m mark --mark 0x40 -j RETURN",
   836  		},
   837  		"TRI-Redir-Net": {
   838  			"-m mark --mark 0x40 -j ACCEPT",
   839  		},
   840  	}
   841  
   842  	expectedContainerMangleAfterPUInsertV6 = map[string][]string{
   843  		"TRI-Nfq-IN": {"-j HMARK --hmark-tuple dport,sport --hmark-mod 4 --hmark-offset 67 --hmark-rnd 0xdeadbeef",
   844  			"-m mark --mark 67 -j NFQUEUE --queue-num 0 --queue-bypass",
   845  			"-m mark --mark 68 -j NFQUEUE --queue-num 1 --queue-bypass",
   846  			"-m mark --mark 69 -j NFQUEUE --queue-num 2 --queue-bypass",
   847  			"-m mark --mark 70 -j NFQUEUE --queue-num 3 --queue-bypass"},
   848  		"TRI-Nfq-OUT": {"-j HMARK --hmark-tuple sport,dport --hmark-mod 4 --hmark-offset 0 --hmark-rnd 0xdeadbeef",
   849  			"-m mark --mark 0 -j NFQUEUE --queue-num 0 --queue-bypass",
   850  			"-m mark --mark 1 -j NFQUEUE --queue-num 1 --queue-bypass",
   851  			"-m mark --mark 2 -j NFQUEUE --queue-num 2 --queue-bypass",
   852  			"-m mark --mark 3 -j NFQUEUE --queue-num 3 --queue-bypass"},
   853  		"INPUT": {
   854  			"-m set ! --match-set TRI-v6-Excluded src -j TRI-Net",
   855  		},
   856  		"OUTPUT": {
   857  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-App",
   858  		},
   859  		"TRI-App": {
   860  			"-m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-p udp --dport 53 -m mark --mark 0x40 -m cgroup --cgroup 1536 -j CONNMARK --set-mark 61167", "-p udp --dport 53 -m mark --mark 0x40 -j CONNMARK --set-mark 61167", "-j TRI-Prx-App", "-m connmark --mark 61167 -j ACCEPT", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP", "-m connmark --mark 61166 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT",
   861  			"-m connmark --mark 61166 -p udp -j ACCEPT", "-m mark --mark 1073741922 -j ACCEPT",
   862  			"-p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-OUT", "-m comment --comment Container-specific-chain -j TRI-App-pu1N7uS6--0"},
   863  		"TRI-Net": {
   864  			"-j TRI-Prx-Net", "-p tcp -m mark --mark 66 -j CONNMARK --set-mark 61167", "-p tcp -m mark --mark 66 -j ACCEPT", "-m connmark --mark 61167 -p tcp ! --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP src -p tcp -m tcp --tcp-flags FIN,RST,URG,PSH,SYN,ACK SYN,ACK -j TRI-Nfq-IN",
   865  			"-p udp -m string --string n30njxq7bmiwr6dtxq --algo bm --to 65535 -j TRI-Nfq-IN", "-p udp -m connmark --mark 61165 -m comment --comment Drop UDP ACL -j DROP", "-m connmark --mark 61166 -p udp -j ACCEPT", "-m comment --comment Container-specific-chain -j TRI-Net-pu1N7uS6--0",
   866  		},
   867  		"TRI-Prx-App": {
   868  			"-m mark --mark 0x40 -j ACCEPT",
   869  			"-p tcp -m tcp --sport 0 -j ACCEPT",
   870  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -j ACCEPT",
   871  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst dst,dst -m mark ! --mark 0x40 -j ACCEPT",
   872  			"-p udp -m udp --sport 0 -j ACCEPT",
   873  		},
   874  		"TRI-Prx-Net": {
   875  			"-m mark --mark 0x40 -j ACCEPT",
   876  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst src,src -j ACCEPT",
   877  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv src -m addrtype --src-type LOCAL -j ACCEPT",
   878  			"-p tcp -m tcp --dport 0 -j ACCEPT",
   879  			"-p udp -m udp --dport 0 -j ACCEPT",
   880  		},
   881  		"TRI-Net-pu1N7uS6--0": {
   882  			"-p tcp -m tcp --tcp-option 34 -m tcp --tcp-flags FIN,RST,URG,PSH NONE -j TRI-Nfq-IN",
   883  			"-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= src -m state --state ESTABLISHED -m connmark --mark 61167 -j ACCEPT",
   884  			"-p TCP -m set --match-set TRI-v6-ext-w5frVvhsnpU= src -m state --state NEW --match multiport --dports 80 -j DROP",
   885  			"-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= src -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 --match multiport --dports 443 -j CONNMARK --set-mark 61167",
   886  			"-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= src -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 --match multiport --dports 443 -j ACCEPT",
   887  			"-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT",
   888  			"-p tcp -m set --match-set TRI-v6-TargetTCP src -m tcp --tcp-flags SYN NONE -j TRI-Nfq-IN",
   889  			"-p udp -m set --match-set TRI-v6-TargetUDP src --match limit --limit 1000/s -j TRI-Nfq-IN",
   890  			"-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT",
   891  			"-s ::/0 -m state --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:6",
   892  			"-s ::/0 -m state ! --state NEW -j NFLOG --nflog-group 11 --nflog-prefix 913787369:default:default:10",
   893  			"-s ::/0 -j DROP",
   894  		},
   895  		"TRI-App-pu1N7uS6--0": {
   896  			"-p TCP -m set --match-set TRI-v6-ext-uNdc0vdcFZA= dst -m state --state NEW --match multiport --dports 80 -j DROP", "-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= dst -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 -m set ! --match-set TRI-v6-TargetUDP dst --match multiport --dports 443 -j CONNMARK --set-mark 61167", "-p UDP -m set --match-set TRI-v6-ext-6zlJIvP3B68= dst -m string ! --string n30njxq7bmiwr6dtxq --algo bm --to 128 -m set ! --match-set TRI-v6-TargetUDP dst --match multiport --dports 443 -j ACCEPT", "-p UDP -m set --match-set TRI-v6-ext-IuSLsD1R-mE= dst -m state --state ESTABLISHED -m connmark --mark 61167 -j ACCEPT", "-p icmpv6 -m bpf --bytecode 16,48 0 0 0,84 0 0 240,21 0 12 96,48 0 0 6,21 0 10 58,48 0 0 40,21 5 0 133,21 4 0 134,21 3 0 135,21 2 0 136,21 1 0 141,21 0 3 142,48 0 0 41,21 0 1 0,6 0 0 65535,6 0 0 0 -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -m tcp --tcp-flags FIN FIN -j ACCEPT", "-m set --match-set TRI-v6-TargetTCP dst -p tcp -j TRI-Nfq-OUT",
   897  			"-p udp -m set --match-set TRI-v6-TargetUDP dst -j TRI-Nfq-OUT", "-p tcp -m state --state ESTABLISHED -m comment --comment TCP-Established-Connections -j ACCEPT", "-p udp -m state --state ESTABLISHED -m comment --comment UDP-Established-Connections -j ACCEPT", "-d ::/0 -m state --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:6",
   898  			"-d ::/0 -m state ! --state NEW -j NFLOG --nflog-group 10 --nflog-prefix 913787369:default:default:10", "-d ::/0 -j DROP"},
   899  	}
   900  
   901  	expectedContainerNATAfterPUInsertV6 = map[string][]string{
   902  		"PREROUTING": {
   903  			"-p tcp -m addrtype --dst-type LOCAL -m set ! --match-set TRI-v6-Excluded src -j TRI-Redir-Net",
   904  		},
   905  		"OUTPUT": {
   906  			"-m set ! --match-set TRI-v6-Excluded dst -j TRI-Redir-App",
   907  		},
   908  		"TRI-Redir-App": {
   909  			"-m mark --mark 0x40 -j RETURN",
   910  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-dst dst,dst -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j REDIRECT --to-ports 0",
   911  			"-d ::/0 -p udp --dport 53 -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j CONNMARK --save-mark",
   912  			"-d ::/0 -p udp --dport 53 -m mark ! --mark 0x40 -m cgroup --cgroup 10 -j REDIRECT --to-ports 0",
   913  		},
   914  		"TRI-Redir-Net": {
   915  			"-m mark --mark 0x40 -j ACCEPT",
   916  			"-p tcp -m set --match-set TRI-v6-Proxy-pu19gtV-srv dst -m mark ! --mark 0x40 -j REDIRECT --to-ports 0",
   917  		},
   918  	}
   919  )
   920  
   921  func Test_OperationWithContainersV6(t *testing.T) {
   922  
   923  	Convey("Given an iptables controller with a memory backend for containers ", t, func() {
   924  		cfg := &runtime.Configuration{
   925  			TCPTargetNetworks: []string{"::/0"},
   926  			UDPTargetNetworks: []string{"1120::/64"},
   927  			ExcludedNetworks:  []string{"::1"},
   928  		}
   929  
   930  		commitFunc := func(buf *bytes.Buffer) error {
   931  			return nil
   932  		}
   933  
   934  		iptv4 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   935  			"mangle"})
   936  		So(iptv4, ShouldNotBeNil)
   937  
   938  		iptv6 := provider.NewCustomBatchProvider(&baseIpt{}, commitFunc, []string{"nat",
   939  			"mangle"})
   940  		So(iptv6, ShouldNotBeNil)
   941  
   942  		ips := &memoryIPSetProvider{sets: map[string]*memoryIPSet{}}
   943  		i, err := createTestInstance(ips, iptv4, iptv6, constants.RemoteContainer, policy.None)
   944  		So(err, ShouldBeNil)
   945  		So(i, ShouldNotBeNil)
   946  
   947  		Convey("When I start the controller, I should get the right global chains and sets", func() {
   948  			ctx, cancel := context.WithCancel(context.Background())
   949  			defer cancel()
   950  			err := i.Run(ctx)
   951  			So(err, ShouldBeNil)
   952  			i.SetTargetNetworks(cfg) // nolint
   953  
   954  			t := i.iptv6.impl.RetrieveTable()
   955  			So(t, ShouldNotBeNil)
   956  			So(len(t), ShouldEqual, 2)
   957  			So(t["mangle"], ShouldNotBeNil)
   958  			So(t["nat"], ShouldNotBeNil)
   959  
   960  			for chain, rules := range t["mangle"] {
   961  				So(expectedContainerGlobalMangleChainsV6, ShouldContainKey, chain)
   962  				So(rules, ShouldResemble, expectedContainerGlobalMangleChainsV6[chain])
   963  			}
   964  
   965  			for chain, rules := range t["nat"] {
   966  				So(expectedContainerGlobalNATChainsV6, ShouldContainKey, chain)
   967  				So(rules, ShouldResemble, expectedContainerGlobalNATChainsV6[chain])
   968  			}
   969  
   970  			Convey("When I configure a new set of rules, the ACLs must be correct", func() {
   971  				appACLs := policy.IPRuleList{
   972  					policy.IPRule{
   973  						Addresses: []string{"1120::/64"},
   974  						Ports:     []string{"80"},
   975  						Protocols: []string{"TCP"},
   976  						Policy: &policy.FlowPolicy{
   977  							Action:    policy.Reject,
   978  							ServiceID: "s1",
   979  							PolicyID:  "1",
   980  						},
   981  					},
   982  					policy.IPRule{
   983  						Addresses: []string{"1120::/64"},
   984  						Ports:     []string{"443"},
   985  						Protocols: []string{"UDP"},
   986  						Policy: &policy.FlowPolicy{
   987  							Action:    policy.Accept,
   988  							ServiceID: "s2",
   989  							PolicyID:  "2",
   990  						},
   991  					},
   992  				}
   993  				netACLs := policy.IPRuleList{
   994  					policy.IPRule{
   995  						Addresses: []string{"1122::/64"},
   996  						Ports:     []string{"80"},
   997  						Protocols: []string{"TCP"},
   998  						Policy: &policy.FlowPolicy{
   999  							Action:    policy.Reject,
  1000  							ServiceID: "s3",
  1001  							PolicyID:  "1",
  1002  						},
  1003  					},
  1004  					policy.IPRule{
  1005  						Addresses: []string{"1122::/64"},
  1006  						Ports:     []string{"443"},
  1007  						Protocols: []string{"UDP"},
  1008  						Policy: &policy.FlowPolicy{
  1009  							Action:    policy.Accept,
  1010  							ServiceID: "s4",
  1011  							PolicyID:  "2",
  1012  						},
  1013  					},
  1014  				}
  1015  				ipl := policy.ExtendedMap{}
  1016  				policyrules := policy.NewPUPolicy(
  1017  					"Context",
  1018  					"/ns1",
  1019  					policy.Police,
  1020  					appACLs,
  1021  					netACLs,
  1022  					nil,
  1023  					nil,
  1024  					nil,
  1025  					nil,
  1026  					nil,
  1027  					nil,
  1028  					ipl,
  1029  					0,
  1030  					0,
  1031  					nil,
  1032  					nil,
  1033  					[]string{},
  1034  					policy.EnforcerMapping,
  1035  					policy.Reject|policy.Log,
  1036  					policy.Reject|policy.Log,
  1037  				)
  1038  				puInfo := policy.NewPUInfo("Context",
  1039  					"/ns1", common.ContainerPU)
  1040  				puInfo.Policy = policyrules
  1041  				puInfo.Runtime.SetOptions(policy.OptionsType{
  1042  					CgroupMark: "10",
  1043  				})
  1044  
  1045  				var iprules policy.IPRuleList
  1046  				iprules = append(iprules, puInfo.Policy.ApplicationACLs()...)
  1047  				iprules = append(iprules, puInfo.Policy.NetworkACLs()...)
  1048  				i.iptv6.ipsetmanager.RegisterExternalNets("pu1", iprules) // nolint
  1049  
  1050  				err := i.ConfigureRules(0,
  1051  					"pu1", puInfo)
  1052  				So(err, ShouldBeNil)
  1053  				t := i.iptv6.impl.RetrieveTable()
  1054  
  1055  				for chain, rules := range t["mangle"] {
  1056  					So(expectedContainerMangleAfterPUInsertV6, ShouldContainKey, chain)
  1057  					So(rules, ShouldResemble, expectedContainerMangleAfterPUInsertV6[chain])
  1058  				}
  1059  
  1060  				for chain, rules := range t["nat"] {
  1061  					So(expectedContainerNATAfterPUInsertV6, ShouldContainKey, chain)
  1062  					So(rules, ShouldResemble, expectedContainerNATAfterPUInsertV6[chain])
  1063  				}
  1064  
  1065  				Convey("When I delete the same rule, the chains must be restored in the global state",
  1066  					func() {
  1067  						err := i.iptv6.DeleteRules(0,
  1068  							"pu1",
  1069  							"0",
  1070  							"0",
  1071  							"10",
  1072  							"", puInfo)
  1073  						So(err, ShouldBeNil)
  1074  
  1075  						t := i.iptv6.impl.RetrieveTable()
  1076  						if err != nil {
  1077  							printTable(t)
  1078  						}
  1079  
  1080  						So(t["mangle"], ShouldNotBeNil)
  1081  						So(t["nat"], ShouldNotBeNil)
  1082  
  1083  						for chain, rules := range t["mangle"] {
  1084  							So(expectedContainerGlobalMangleChainsV6, ShouldContainKey, chain)
  1085  							So(rules, ShouldResemble, expectedContainerGlobalMangleChainsV6[chain])
  1086  						}
  1087  
  1088  						for chain, rules := range t["nat"] {
  1089  							So(expectedContainerGlobalNATChainsV6, ShouldContainKey, chain)
  1090  							So(rules, ShouldResemble, expectedContainerGlobalNATChainsV6[chain])
  1091  						}
  1092  					})
  1093  
  1094  			})
  1095  		})
  1096  	})
  1097  }
  1098  
  1099  func TestIpv6Disable(t *testing.T) {
  1100  	ipv6Instance := &ipv6{ipv6Enabled: false}
  1101  
  1102  	assert.Equal(t, ipv6Instance.Append("", "") == nil, true, "error should be nil")
  1103  	assert.Equal(t, ipv6Instance.Insert("", "", 0) == nil, true, "error should be nil")
  1104  	assert.Equal(t, ipv6Instance.ClearChain("", "") == nil, true, "error should be nil")
  1105  	assert.Equal(t, ipv6Instance.DeleteChain("", "") == nil, true, "error should be nil")
  1106  	assert.Equal(t, ipv6Instance.NewChain("", "") == nil, true, "error should be nil")
  1107  	assert.Equal(t, ipv6Instance.Commit() == nil, true, "error should be nil")
  1108  	chains, err := ipv6Instance.ListChains("")
  1109  
  1110  	assert.Equal(t, chains == nil, true, "chains should be nil")
  1111  	assert.Equal(t, err == nil, true, "error should be nil")
  1112  }