-
Notifications
You must be signed in to change notification settings - Fork 880
/
setup_ip_tables_test.go
138 lines (113 loc) · 4.43 KB
/
setup_ip_tables_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package bridge
import (
"net"
"testing"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/portmapper"
"github.com/docker/libnetwork/testutils"
"github.com/vishvananda/netlink"
)
const (
iptablesTestBridgeIP = "192.168.42.1"
)
func TestProgramIPTable(t *testing.T) {
// Create a test bridge with a basic bridge configuration (name + IPv4).
defer testutils.SetupTestOSContext(t)()
nh, err := netlink.NewHandle()
if err != nil {
t.Fatal(err)
}
createTestBridge(getBasicTestConfig(), &bridgeInterface{nlh: nh}, t)
// Store various iptables chain rules we care for.
rules := []struct {
rule iptRule
descr string
}{
{iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-d", "127.1.2.3", "-i", "lo", "-o", "lo", "-j", "DROP"}}, "Test Loopback"},
{iptRule{table: iptables.Nat, chain: "POSTROUTING", preArgs: []string{"-t", "nat"}, args: []string{"-s", iptablesTestBridgeIP, "!", "-o", DefaultBridgeName, "-j", "MASQUERADE"}}, "NAT Test"},
{iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-o", DefaultBridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}}, "Test ACCEPT INCOMING"},
{iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "!", "-o", DefaultBridgeName, "-j", "ACCEPT"}}, "Test ACCEPT NON_ICC OUTGOING"},
{iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "-o", DefaultBridgeName, "-j", "ACCEPT"}}, "Test enable ICC"},
{iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "-o", DefaultBridgeName, "-j", "DROP"}}, "Test disable ICC"},
}
// Assert the chain rules' insertion and removal.
for _, c := range rules {
assertIPTableChainProgramming(c.rule, c.descr, t)
}
}
func TestSetupIPChains(t *testing.T) {
// Create a test bridge with a basic bridge configuration (name + IPv4).
defer testutils.SetupTestOSContext(t)()
nh, err := netlink.NewHandle()
if err != nil {
t.Fatal(err)
}
driverconfig := &configuration{
EnableIPTables: true,
}
d := &driver{
config: driverconfig,
}
assertChainConfig(d, t)
config := getBasicTestConfig()
br := &bridgeInterface{nlh: nh}
createTestBridge(config, br, t)
assertBridgeConfig(config, br, d, t)
config.EnableIPMasquerade = true
assertBridgeConfig(config, br, d, t)
config.EnableICC = true
assertBridgeConfig(config, br, d, t)
config.EnableIPMasquerade = false
assertBridgeConfig(config, br, d, t)
}
func getBasicTestConfig() *networkConfiguration {
config := &networkConfiguration{
BridgeName: DefaultBridgeName,
AddressIPv4: &net.IPNet{IP: net.ParseIP(iptablesTestBridgeIP), Mask: net.CIDRMask(16, 32)}}
return config
}
func createTestBridge(config *networkConfiguration, br *bridgeInterface, t *testing.T) {
if err := setupDevice(config, br); err != nil {
t.Fatalf("Failed to create the testing Bridge: %s", err.Error())
}
if err := setupBridgeIPv4(config, br); err != nil {
t.Fatalf("Failed to bring up the testing Bridge: %s", err.Error())
}
}
// Assert base function which pushes iptables chain rules on insertion and removal.
func assertIPTableChainProgramming(rule iptRule, descr string, t *testing.T) {
// Add
if err := programChainRule(iptables.IPv4, rule, descr, true); err != nil {
t.Fatalf("Failed to program iptable rule %s: %s", descr, err.Error())
}
iptable := iptables.GetIptable(iptables.IPv4)
if iptable.Exists(rule.table, rule.chain, rule.args...) == false {
t.Fatalf("Failed to effectively program iptable rule: %s", descr)
}
// Remove
if err := programChainRule(iptables.IPv4, rule, descr, false); err != nil {
t.Fatalf("Failed to remove iptable rule %s: %s", descr, err.Error())
}
if iptable.Exists(rule.table, rule.chain, rule.args...) == true {
t.Fatalf("Failed to effectively remove iptable rule: %s", descr)
}
}
// Assert function which create chains.
func assertChainConfig(d *driver, t *testing.T) {
var err error
d.natChain, d.filterChain, d.isolationChain1, d.isolationChain2, err = setupIPChains(d.config, iptables.IPv4)
if err != nil {
t.Fatal(err)
}
}
// Assert function which pushes chains based on bridge config parameters.
func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, d *driver, t *testing.T) {
nw := bridgeNetwork{portMapper: portmapper.New(""),
config: config}
nw.driver = d
// Attempt programming of ip tables.
err := nw.setupIP4Tables(config, br)
if err != nil {
t.Fatalf("%v", err)
}
}