github.com/cilium/cilium@v1.16.2/pkg/datapath/iptables/iptables_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package iptables
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  type expectation struct {
    13  	args string
    14  	out  []byte
    15  	err  error
    16  }
    17  
    18  type mockIptables struct {
    19  	t            *testing.T
    20  	prog         string
    21  	ipset        string
    22  	expectations []expectation
    23  	index        int
    24  }
    25  
    26  func (ipt *mockIptables) getProg() string {
    27  	return ipt.prog
    28  }
    29  
    30  func (ipt *mockIptables) getIpset() string {
    31  	return ipt.ipset
    32  }
    33  
    34  func (ipt *mockIptables) runProgOutput(args []string) (out string, err error) {
    35  	a := strings.Join(args, " ")
    36  	i := ipt.index
    37  	ipt.index++
    38  
    39  	if len(ipt.expectations) < ipt.index {
    40  		ipt.t.Errorf("%d: Unexpected %s %s", i, ipt.prog, a)
    41  		return "", fmt.Errorf("Unexpected %s %s", ipt.prog, a)
    42  	}
    43  	if a != ipt.expectations[i].args {
    44  		ipt.t.Errorf("%d: Unexpected %s (%q != %q)", i, ipt.prog, a, ipt.expectations[i].args)
    45  		return "", fmt.Errorf("Unexpected %s %s", ipt.prog, a)
    46  	}
    47  	out = string(ipt.expectations[i].out)
    48  	err = ipt.expectations[i].err
    49  
    50  	return out, err
    51  }
    52  
    53  func (ipt *mockIptables) runProg(args []string) error {
    54  	out, err := ipt.runProgOutput(args)
    55  	if len(out) > 0 {
    56  		ipt.t.Errorf("%d: Unexpected output for %s %s", ipt.index-1, ipt.prog, strings.Join(args, " "))
    57  	}
    58  	return err
    59  }
    60  
    61  func (ipt *mockIptables) checkExpectations() error {
    62  	if ipt.index != len(ipt.expectations) {
    63  		return fmt.Errorf("%d unmet expectations", len(ipt.expectations)-ipt.index)
    64  	}
    65  
    66  	// reset index for further testing
    67  	ipt.index = 0
    68  
    69  	return nil
    70  }
    71  
    72  var mockManager = &Manager{
    73  	haveIp6tables:        false,
    74  	haveSocketMatch:      true,
    75  	haveBPFSocketAssign:  false,
    76  	ipEarlyDemuxDisabled: false,
    77  	sharedCfg: SharedConfig{
    78  		EnableIPv4: true,
    79  		EnableIPv6: true,
    80  	},
    81  }
    82  
    83  func TestRenameCustomChain(t *testing.T) {
    84  	mockIp4tables := &mockIptables{t: t, prog: "iptables"}
    85  	mockIp4tables.expectations = []expectation{
    86  		{
    87  			args: "-t mangle -S CILIUM_PRE_mangle",
    88  		},
    89  		{
    90  			args: "-t mangle -E CILIUM_PRE_mangle OLD_CILIUM_PRE_mangle",
    91  		},
    92  	}
    93  	chain := &customChain{
    94  		table: "mangle",
    95  		name:  "CILIUM_PRE_mangle",
    96  	}
    97  	chain.doRename(mockIp4tables, "OLD_CILIUM_PRE_mangle")
    98  	err := mockIp4tables.checkExpectations()
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	mockIp6tables := &mockIptables{t: t, prog: "ip6tables"}
   104  	mockIp6tables.expectations = mockIp4tables.expectations
   105  	chain.doRename(mockIp6tables, "OLD_CILIUM_PRE_mangle")
   106  	err = mockIp6tables.checkExpectations()
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  }
   111  
   112  func TestCopyProxyRulesv4(t *testing.T) {
   113  	mockIp4tables := &mockIptables{t: t, prog: "iptables"}
   114  	mockIp4tables.expectations = []expectation{
   115  		{
   116  			args: "-t mangle -S",
   117  			out: []byte(
   118  				`-P PREROUTING ACCEPT
   119  -P INPUT ACCEPT
   120  -P FORWARD ACCEPT
   121  -P OUTPUT ACCEPT
   122  -P POSTROUTING ACCEPT
   123  -N OLD_CILIUM_POST_mangle
   124  -N OLD_CILIUM_PRE_mangle
   125  -N KUBE-KUBELET-CANARY
   126  -N KUBE-PROXY-CANARY
   127  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   128  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   129  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   130  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   131  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-random-proxy proxy" -j TPROXY --on-port 43499 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
   132  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   133  `),
   134  		}, {
   135  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   136  		}, {
   137  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   138  		},
   139  	}
   140  
   141  	// Copies DNS proxy rules from OLD_CILIUM_PRE_mangle to CILIUM_PRE_mangle
   142  	mockManager.doCopyProxyRules(mockIp4tables, "mangle", tproxyMatch, "cilium-dns-egress", "OLD_"+ciliumPreMangleChain, ciliumPreMangleChain)
   143  	err := mockIp4tables.checkExpectations()
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  }
   148  
   149  func TestCopyProxyRulesv6(t *testing.T) {
   150  	mockIp6tables := &mockIptables{t: t, prog: "ip6tables"}
   151  	mockIp6tables.expectations = []expectation{
   152  		{
   153  			args: "-t mangle -S",
   154  			out: []byte(
   155  				`-P PREROUTING ACCEPT
   156  -P INPUT ACCEPT
   157  -P FORWARD ACCEPT
   158  -P OUTPUT ACCEPT
   159  -P POSTROUTING ACCEPT
   160  -N OLD_CILIUM_POST_mangle
   161  -N OLD_CILIUM_PRE_mangle
   162  -N KUBE-KUBELET-CANARY
   163  -N KUBE-PROXY-CANARY
   164  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   165  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   166  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   167  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   168  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-random-proxy proxy" -j TPROXY --on-port 43499 --on-ip :: --tproxy-mark 0x200/0xffffffff
   169  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   170  `),
   171  		}, {
   172  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   173  		}, {
   174  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   175  		},
   176  	}
   177  
   178  	// Copies DNS proxy rules from OLD_CILIUM_PRE_mangle to CILIUM_PRE_mangle
   179  	mockManager.doCopyProxyRules(mockIp6tables, "mangle", tproxyMatch, "cilium-dns-egress", "OLD_"+ciliumPreMangleChain, ciliumPreMangleChain)
   180  	err := mockIp6tables.checkExpectations()
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  }
   185  
   186  func TestAddProxyRulesv4(t *testing.T) {
   187  	mockIp4tables := &mockIptables{t: t, prog: "iptables"}
   188  	mockIp4tables.expectations = []expectation{
   189  		{
   190  			args: "-t mangle -S",
   191  			out: []byte(
   192  				`-P PREROUTING ACCEPT
   193  -P INPUT ACCEPT
   194  -P FORWARD ACCEPT
   195  -P OUTPUT ACCEPT
   196  -P POSTROUTING ACCEPT
   197  -N OLD_CILIUM_POST_mangle
   198  -N OLD_CILIUM_PRE_mangle
   199  -N CILIUM_POST_mangle
   200  -N CILIUM_PRE_mangle
   201  -N KUBE-KUBELET-CANARY
   202  -N KUBE-PROXY-CANARY
   203  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   204  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   205  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   206  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   207  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   208  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   209  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   210  `),
   211  		}, {
   212  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
   213  		}, {
   214  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
   215  		},
   216  	}
   217  
   218  	// Adds new proxy rules
   219  	mockManager.addProxyRules(mockIp4tables, "127.0.0.1", 37379, "cilium-dns-egress")
   220  	err := mockIp4tables.checkExpectations()
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  
   225  	mockIp4tables.expectations = []expectation{
   226  		{
   227  			args: "-t mangle -S",
   228  			out: []byte(
   229  				`-P PREROUTING ACCEPT
   230  -P INPUT ACCEPT
   231  -P FORWARD ACCEPT
   232  -P OUTPUT ACCEPT
   233  -P POSTROUTING ACCEPT
   234  -N OLD_CILIUM_POST_mangle
   235  -N OLD_CILIUM_PRE_mangle
   236  -N CILIUM_POST_mangle
   237  -N CILIUM_PRE_mangle
   238  -N KUBE-KUBELET-CANARY
   239  -N KUBE-PROXY-CANARY
   240  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   241  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   242  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   243  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   244  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   245  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   246  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   247  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   248  -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   249  `),
   250  		},
   251  	}
   252  
   253  	// Nothing to add
   254  	mockManager.addProxyRules(mockIp4tables, "127.0.0.1", 37379, "cilium-dns-egress")
   255  	err = mockIp4tables.checkExpectations()
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	}
   259  
   260  	mockIp4tables.expectations = []expectation{
   261  		{
   262  			args: "-t mangle -S",
   263  			out: []byte(
   264  				`-P PREROUTING ACCEPT
   265  -P INPUT ACCEPT
   266  -P FORWARD ACCEPT
   267  -P OUTPUT ACCEPT
   268  -P POSTROUTING ACCEPT
   269  -N OLD_CILIUM_POST_mangle
   270  -N OLD_CILIUM_PRE_mangle
   271  -N CILIUM_POST_mangle
   272  -N CILIUM_PRE_mangle
   273  -N KUBE-KUBELET-CANARY
   274  -N KUBE-PROXY-CANARY
   275  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   276  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   277  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   278  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   279  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   280  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   281  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   282  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   283  -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   284  `),
   285  		}, {
   286  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x4920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37380",
   287  		}, {
   288  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0x4920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37380",
   289  		}, {
   290  			args: "-t mangle -D CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   291  		}, {
   292  			args: "-t mangle -D CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   293  		},
   294  	}
   295  
   296  	// New port number, adds new ones, deletes stale rules. Does not touch OLD_ chains
   297  	mockManager.addProxyRules(mockIp4tables, "127.0.0.1", 37380, "cilium-dns-egress")
   298  	err = mockIp4tables.checkExpectations()
   299  	if err != nil {
   300  		t.Fatal(err)
   301  	}
   302  
   303  	mockIp4tables.expectations = []expectation{
   304  		{
   305  			args: "-t mangle -S",
   306  			out: []byte(
   307  				`-P PREROUTING ACCEPT
   308  -P INPUT ACCEPT
   309  -P FORWARD ACCEPT
   310  -P OUTPUT ACCEPT
   311  -P POSTROUTING ACCEPT
   312  -N OLD_CILIUM_POST_mangle
   313  -N OLD_CILIUM_PRE_mangle
   314  -N CILIUM_POST_mangle
   315  -N CILIUM_PRE_mangle
   316  -N KUBE-KUBELET-CANARY
   317  -N KUBE-PROXY-CANARY
   318  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   319  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   320  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   321  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   322  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   323  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
   324  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
   325  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
   326  -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
   327  `),
   328  		}, {
   329  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
   330  		}, {
   331  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
   332  		}, {
   333  			args: "-t mangle -D CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff",
   334  		}, {
   335  			args: "-t mangle -D CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff",
   336  		},
   337  	}
   338  
   339  	// Same port number, new IP, adds new ones, deletes stale rules. Does not touch OLD_ chains
   340  	mockManager.addProxyRules(mockIp4tables, "127.0.0.1", 37379, "cilium-dns-egress")
   341  	err = mockIp4tables.checkExpectations()
   342  	if err != nil {
   343  		t.Fatal(err)
   344  	}
   345  }
   346  
   347  func TestGetProxyPorts(t *testing.T) {
   348  	mockIp4tables := &mockIptables{t: t, prog: "iptables"}
   349  	mockIp4tables.expectations = []expectation{
   350  		{
   351  			args: "-t mangle -n -L CILIUM_PRE_mangle",
   352  			out: []byte(
   353  				`Chain CILIUM_PRE_mangle (1 references)
   354  target     prot opt source               destination
   355  MARK       all  --  0.0.0.0/0            0.0.0.0/0            socket --transparent /* cilium: any->pod redirect proxied traffic to host proxy */ MARK set 0x200
   356  TPROXY     tcp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd5a90200 /* cilium: TPROXY to host cilium-dns-egress proxy */ TPROXY redirect 127.0.0.1:43477 mark 0x200/0xffffffff
   357  TPROXY     udp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd5a90200 /* cilium: TPROXY to host cilium-dns-egress proxy */ TPROXY redirect 127.0.0.1:43477 mark 0x200/0xffffffff
   358  TPROXY     tcp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd7a90200 /* cilium: TPROXY to host cilium-dns-egress proxy */ TPROXY redirect 127.0.0.1:43479 mark 0x200/0xffffffff
   359  TPROXY     udp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd7a90200 /* cilium: TPROXY to host cilium-dns-egress proxy */ TPROXY redirect 127.0.0.1:43479 mark 0x200/0xffffffff
   360  `),
   361  		},
   362  	}
   363  
   364  	// Finds the latest port number if multiple rules for the same proxy name
   365  	portMap := mockManager.doGetProxyPorts(mockIp4tables)
   366  	if len(portMap) != 1 || portMap["cilium-dns-egress"] != uint16(43479) {
   367  		t.Fatalf("expected port number %d, got %d, portMap: %v", uint16(43479), portMap["cilium-dns-egress"], portMap)
   368  	}
   369  	if err := mockIp4tables.checkExpectations(); err != nil {
   370  		t.Fatal(err)
   371  	}
   372  
   373  	// Now test the proxy port fetch when the proxy is not DNS. It should
   374  	// fallback to 0.0.0.0 instead of localhost.
   375  	mockIp4tables.expectations = []expectation{
   376  		{
   377  			args: "-t mangle -n -L CILIUM_PRE_mangle",
   378  			out: []byte(
   379  				`Chain CILIUM_PRE_mangle (1 references)
   380  target     prot opt source               destination
   381  MARK       all  --  0.0.0.0/0            0.0.0.0/0            socket --transparent /* cilium: any->pod redirect proxied traffic to host proxy */ MARK set 0x200
   382  TPROXY     tcp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd5a90200 /* cilium: TPROXY to host cilium-random-ingress proxy */ TPROXY redirect 0.0.0.0:43477 mark 0x200/0xffffffff
   383  TPROXY     udp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd5a90200 /* cilium: TPROXY to host cilium-random-ingress proxy */ TPROXY redirect 0.0.0.0:43477 mark 0x200/0xffffffff
   384  TPROXY     tcp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd7a90200 /* cilium: TPROXY to host cilium-random-ingress proxy */ TPROXY redirect 0.0.0.0:43479 mark 0x200/0xffffffff
   385  TPROXY     udp  --  0.0.0.0/0            0.0.0.0/0            mark match 0xd7a90200 /* cilium: TPROXY to host cilium-random-ingress proxy */ TPROXY redirect 0.0.0.0:43479 mark 0x200/0xffffffff
   386  `),
   387  		},
   388  	}
   389  
   390  	portMap = mockManager.doGetProxyPorts(mockIp4tables)
   391  	if len(portMap) != 1 || portMap["cilium-random-ingress"] != uint16(43479) {
   392  		t.Fatalf("expected port number %d, got %d, portMap: %v", uint16(43479), portMap["cilium-random-ingress"], portMap)
   393  	}
   394  	if err := mockIp4tables.checkExpectations(); err != nil {
   395  		t.Fatal(err)
   396  	}
   397  }
   398  
   399  func TestAddProxyRulesv6(t *testing.T) {
   400  	mockIp6tables := &mockIptables{t: t, prog: "ip6tables"}
   401  	mockIp6tables.expectations = []expectation{
   402  		{
   403  			args: "-t mangle -S",
   404  			out: []byte(
   405  				`-P PREROUTING ACCEPT
   406  -P INPUT ACCEPT
   407  -P FORWARD ACCEPT
   408  -P OUTPUT ACCEPT
   409  -P POSTROUTING ACCEPT
   410  -N OLD_CILIUM_POST_mangle
   411  -N OLD_CILIUM_PRE_mangle
   412  -N CILIUM_POST_mangle
   413  -N CILIUM_PRE_mangle
   414  -N KUBE-KUBELET-CANARY
   415  -N KUBE-PROXY-CANARY
   416  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   417  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   418  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   419  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   420  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   421  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   422  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   423  `),
   424  		}, {
   425  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip ::1 --on-port 43477",
   426  		}, {
   427  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip ::1 --on-port 43477",
   428  		},
   429  	}
   430  
   431  	// Adds new proxy rules
   432  	mockManager.addProxyRules(mockIp6tables, "::1", 43477, "cilium-dns-egress")
   433  	err := mockIp6tables.checkExpectations()
   434  	if err != nil {
   435  		t.Fatal(err)
   436  	}
   437  
   438  	mockIp6tables.expectations = []expectation{
   439  		{
   440  			args: "-t mangle -S",
   441  			out: []byte(
   442  				`-P PREROUTING ACCEPT
   443  -P INPUT ACCEPT
   444  -P FORWARD ACCEPT
   445  -P OUTPUT ACCEPT
   446  -P POSTROUTING ACCEPT
   447  -N OLD_CILIUM_POST_mangle
   448  -N OLD_CILIUM_PRE_mangle
   449  -N CILIUM_POST_mangle
   450  -N CILIUM_PRE_mangle
   451  -N KUBE-KUBELET-CANARY
   452  -N KUBE-PROXY-CANARY
   453  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   454  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   455  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   456  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   457  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   458  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   459  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   460  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   461  -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   462  `),
   463  		},
   464  	}
   465  
   466  	// Nothing to add
   467  	mockManager.addProxyRules(mockIp6tables, "::1", 43477, "cilium-dns-egress")
   468  	err = mockIp6tables.checkExpectations()
   469  	if err != nil {
   470  		t.Fatal(err)
   471  	}
   472  
   473  	mockIp6tables.expectations = []expectation{
   474  		{
   475  			args: "-t mangle -S",
   476  			out: []byte(
   477  				`-P PREROUTING ACCEPT
   478  -P INPUT ACCEPT
   479  -P FORWARD ACCEPT
   480  -P OUTPUT ACCEPT
   481  -P POSTROUTING ACCEPT
   482  -N OLD_CILIUM_POST_mangle
   483  -N OLD_CILIUM_PRE_mangle
   484  -N CILIUM_POST_mangle
   485  -N CILIUM_PRE_mangle
   486  -N KUBE-KUBELET-CANARY
   487  -N KUBE-PROXY-CANARY
   488  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   489  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   490  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   491  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   492  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   493  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   494  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   495  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   496  -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   497  `),
   498  		}, {
   499  			args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd7a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip ::1 --on-port 43479",
   500  		}, {
   501  			args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd7a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip ::1 --on-port 43479",
   502  		}, {
   503  			args: "-t mangle -D CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   504  		}, {
   505  			args: "-t mangle -D CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   506  		},
   507  	}
   508  
   509  	// New port number, adds new ones, deletes stale rules. Does not touch OLD_ chains
   510  	mockManager.addProxyRules(mockIp6tables, "::1", 43479, "cilium-dns-egress")
   511  	err = mockIp6tables.checkExpectations()
   512  	if err != nil {
   513  		t.Fatal(err)
   514  	}
   515  }
   516  
   517  func TestRemoveCiliumRulesv4(t *testing.T) {
   518  	mockIp4tables := &mockIptables{t: t, prog: "iptables"}
   519  	mockIp4tables.expectations = []expectation{
   520  		{
   521  			args: "-t mangle -S",
   522  			out: []byte(
   523  				`-P PREROUTING ACCEPT
   524  -P INPUT ACCEPT
   525  -P FORWARD ACCEPT
   526  -P OUTPUT ACCEPT
   527  -P POSTROUTING ACCEPT
   528  -N OLD_CILIUM_POST_mangle
   529  -N OLD_CILIUM_PRE_mangle
   530  -N CILIUM_POST_mangle
   531  -N CILIUM_PRE_mangle
   532  -N KUBE-KUBELET-CANARY
   533  -N KUBE-PROXY-CANARY
   534  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   535  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   536  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   537  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   538  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   539  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   540  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   541  -A CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   542  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   543  -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff
   544  `),
   545  		}, {
   546  			args: "-t mangle -D PREROUTING -m comment --comment cilium-feeder: CILIUM_PRE_mangle -j OLD_CILIUM_PRE_mangle",
   547  		}, {
   548  			args: "-t mangle -D POSTROUTING -m comment --comment cilium-feeder: CILIUM_POST_mangle -j OLD_CILIUM_POST_mangle",
   549  		}, {
   550  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment cilium: any->pod redirect proxied traffic to host proxy -j MARK --set-xmark 0x200/0xffffffff",
   551  		}, {
   552  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   553  		}, {
   554  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip 127.0.0.1 --tproxy-mark 0x200/0xffffffff",
   555  		},
   556  	}
   557  
   558  	// Only removes Cilium chains with the OLD_ prefix
   559  	mockManager.removeCiliumRules("mangle", mockIp4tables, oldCiliumPrefix+"CILIUM_")
   560  	err := mockIp4tables.checkExpectations()
   561  	if err != nil {
   562  		t.Fatal(err)
   563  	}
   564  }
   565  
   566  func TestRemoveCiliumRulesv6(t *testing.T) {
   567  	mockIp6tables := &mockIptables{t: t, prog: "ip6tables"}
   568  	mockIp6tables.expectations = []expectation{
   569  		{
   570  			args: "-t mangle -S",
   571  			out: []byte(
   572  				`-P PREROUTING ACCEPT
   573  -P INPUT ACCEPT
   574  -P FORWARD ACCEPT
   575  -P OUTPUT ACCEPT
   576  -P POSTROUTING ACCEPT
   577  -N OLD_CILIUM_POST_mangle
   578  -N OLD_CILIUM_PRE_mangle
   579  -N CILIUM_POST_mangle
   580  -N CILIUM_PRE_mangle
   581  -N KUBE-KUBELET-CANARY
   582  -N KUBE-PROXY-CANARY
   583  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
   584  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
   585  -A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
   586  -A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
   587  -A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   588  -A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   589  -A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   590  -A CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
   591  -A CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   592  -A CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff
   593  `),
   594  		}, {
   595  			args: "-t mangle -D PREROUTING -m comment --comment cilium-feeder: CILIUM_PRE_mangle -j OLD_CILIUM_PRE_mangle",
   596  		}, {
   597  			args: "-t mangle -D POSTROUTING -m comment --comment cilium-feeder: CILIUM_POST_mangle -j OLD_CILIUM_POST_mangle",
   598  		}, {
   599  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment cilium: any->pod redirect proxied traffic to host proxy -j MARK --set-xmark 0x200/0xffffffff",
   600  		}, {
   601  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   602  		}, {
   603  			args: "-t mangle -D OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0xd5a90200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 43477 --on-ip ::1 --tproxy-mark 0x200/0xffffffff",
   604  		},
   605  	}
   606  
   607  	// Only removes Cilium chains with the OLD_ prefix
   608  	mockManager.removeCiliumRules("mangle", mockIp6tables, oldCiliumPrefix+"CILIUM_")
   609  	err := mockIp6tables.checkExpectations()
   610  	if err != nil {
   611  		t.Fatal(err)
   612  	}
   613  }