]>
Commit | Line | Data |
---|---|---|
cc08428b GS |
1 | AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, NAT]) |
2 | AT_KEYWORDS([ovnnat]) | |
3 | ||
4 | CHECK_CONNTRACK() | |
5 | ovn_start | |
6 | OVS_TRAFFIC_VSWITCHD_START() | |
7 | ADD_BR([br-int]) | |
8 | ||
9 | # Set external-ids in br-int needed for ovn-controller | |
10 | ovs-vsctl \ | |
11 | -- set Open_vSwitch . external-ids:system-id=hv1 \ | |
12 | -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ | |
13 | -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ | |
14 | -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ | |
15 | -- set bridge br-int fail-mode=secure other-config:disable-in-band=true | |
16 | ||
17 | # Start ovn-controller | |
18 | start_daemon ovn-controller | |
19 | ||
20 | # Logical network: | |
21 | # Two LRs - R1 and R2 that are connected to each other via LS "join" | |
22 | # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and | |
23 | # bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected | |
24 | # to it. R2 is a gateway router on which we add NAT rules. | |
25 | # | |
26 | # foo -- R1 -- join - R2 -- alice | |
27 | # | | |
28 | # bar ---- | |
29 | ||
30 | ovn-nbctl create Logical_Router name=R1 | |
31 | ovn-nbctl create Logical_Router name=R2 options:chassis=hv1 | |
32 | ||
33 | ovn-nbctl ls-add foo | |
34 | ovn-nbctl ls-add bar | |
35 | ovn-nbctl ls-add alice | |
36 | ovn-nbctl ls-add join | |
37 | ||
38 | # Connect foo to R1 | |
39 | ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24 | |
40 | ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \ | |
41 | type=router options:router-port=foo addresses=\"00:00:01:01:02:03\" | |
42 | ||
43 | # Connect bar to R1 | |
44 | ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24 | |
45 | ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \ | |
46 | type=router options:router-port=bar addresses=\"00:00:01:01:02:04\" | |
47 | ||
48 | # Connect alice to R2 | |
49 | ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24 | |
50 | ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \ | |
51 | type=router options:router-port=alice addresses=\"00:00:02:01:02:03\" | |
52 | ||
53 | # Connect R1 to join | |
54 | ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24 | |
55 | ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \ | |
56 | type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"' | |
57 | ||
58 | # Connect R2 to join | |
59 | ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24 | |
60 | ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \ | |
61 | type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"' | |
62 | ||
63 | # Static routes. | |
64 | ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2 | |
65 | ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1 | |
66 | ||
67 | # Logical port 'foo1' in switch 'foo'. | |
68 | ADD_NAMESPACES(foo1) | |
69 | ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \ | |
70 | "192.168.1.1") | |
71 | ovn-nbctl lsp-add foo foo1 \ | |
72 | -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2" | |
73 | ||
74 | # Logical port 'alice1' in switch 'alice'. | |
75 | ADD_NAMESPACES(alice1) | |
76 | ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \ | |
77 | "172.16.1.1") | |
78 | ovn-nbctl lsp-add alice alice1 \ | |
79 | -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2" | |
80 | ||
81 | # Logical port 'bar1' in switch 'bar'. | |
82 | ADD_NAMESPACES(bar1) | |
83 | ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \ | |
84 | "192.168.2.1") | |
85 | ovn-nbctl lsp-add bar bar1 \ | |
86 | -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2" | |
87 | ||
88 | # Add a DNAT rule. | |
89 | ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \ | |
90 | external_ip=30.0.0.2 -- add logical_router R2 nat @nat | |
91 | ||
92 | # Add a SNAT rule | |
93 | ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \ | |
94 | external_ip=30.0.0.1 -- add logical_router R2 nat @nat | |
95 | ||
96 | # wait for ovn-controller to catch up. | |
97 | OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat]) | |
98 | ||
99 | # 'alice1' should be able to ping 'foo1' directly. | |
100 | NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \ | |
101 | [0], [dnl | |
102 | 3 packets transmitted, 3 received, 0% packet loss, time 0ms | |
103 | ]) | |
104 | ||
105 | # North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2 | |
106 | NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ | |
107 | [0], [dnl | |
108 | 3 packets transmitted, 3 received, 0% packet loss, time 0ms | |
109 | ]) | |
110 | ||
111 | # Check conntrack entries. | |
112 | AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \ | |
113 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl | |
114 | icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>),zone=<cleared> | |
115 | ]) | |
116 | ||
117 | # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic | |
118 | # from 30.0.0.1 | |
119 | NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \ | |
120 | [0], [dnl | |
121 | 3 packets transmitted, 3 received, 0% packet loss, time 0ms | |
122 | ]) | |
123 | ||
124 | # We verify that SNAT indeed happened via 'dump-conntrack' command. | |
125 | AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \ | |
126 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl | |
127 | icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>),reply=(src=172.16.1.2,dst=30.0.0.1,id=<cleared>),zone=<cleared> | |
128 | ]) | |
129 | ||
130 | # Add static routes to handle east-west NAT. | |
131 | ovn-nbctl lr-route-add R1 30.0.0.0/24 20.0.0.2 | |
132 | ||
133 | # Flush conntrack entries for easier output parsing of next test. | |
134 | AT_CHECK([ovs-appctl dpctl/flush-conntrack]) | |
135 | ||
136 | # East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it. | |
137 | NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \ | |
138 | [0], [dnl | |
139 | 3 packets transmitted, 3 received, 0% packet loss, time 0ms | |
140 | ]) | |
141 | ||
142 | # As we have a static route that sends all packets with destination | |
143 | # 30.0.0.2 to R2, it hits the DNAT rule and converts 30.0.0.2 to 192.168.1.2 | |
144 | AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \ | |
145 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl | |
146 | icmp,orig=(src=192.168.2.2,dst=30.0.0.2,id=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>),zone=<cleared> | |
147 | ]) | |
148 | ||
149 | # As we have a SNAT rule that converts 192.168.2.2 to 30.0.0.1, the source is | |
150 | # SNATted and 'foo1' receives it. | |
151 | AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \ | |
152 | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl | |
153 | icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>),reply=(src=192.168.1.2,dst=30.0.0.1,id=<cleared>),zone=<cleared> | |
154 | ]) | |
155 | ||
156 | OVS_APP_EXIT_AND_WAIT([ovn-controller]) | |
157 | ||
158 | as ovn-sb | |
159 | OVS_APP_EXIT_AND_WAIT([ovsdb-server]) | |
160 | ||
161 | as ovn-nb | |
162 | OVS_APP_EXIT_AND_WAIT([ovsdb-server]) | |
163 | ||
164 | as northd | |
165 | OVS_APP_EXIT_AND_WAIT([ovn-northd]) | |
166 | ||
167 | as | |
168 | OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"]) | |
169 | AT_CLEANUP |