summaryrefslogtreecommitdiff
path: root/tests/ovn-controller.at
blob: 60a67601d346c84cd1f3baf9310e9dcb9cc5d955 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
AT_BANNER([ovn-controller])

AT_SETUP([ovn-controller - ovn-bridge-mappings])
AT_KEYWORDS([ovn])
ovn_init_db ovn-sb
net_add n1
sim_add hv
as hv
ovs-vsctl \
    -- add-br br-phys \
    -- add-br br-eth0 \
    -- add-br br-eth1 \
    -- add-br br-eth2
ovn_attach n1 br-phys 192.168.0.1

# Waits until the OVS database contains exactly the specified patch ports.
# Each argument should be of the form BRIDGE PORT PEER.
check_patches () {
    # Generate code to check that the set of patch ports is exactly as
    # specified.
    echo 'ovs-vsctl -f csv -d bare --no-headings --columns=name find Interface type=patch | sort' > query
    for patch
    do
        echo $patch
    done | cut -d' ' -f 2 | sort > expout

    # Generate code to verify that the configuration of each patch
    # port is correct.
    for patch
    do
        set $patch; bridge=$1 port=$2 peer=$3
        echo >>query "ovs-vsctl iface-to-br $port -- get Interface $port type options"
        echo >>expout "$bridge
patch
{peer=$peer}"
    done

    # Run the query until we get the expected result (or until a timeout).
    #
    # (We use sed to drop all "s from output because ovs-vsctl quotes some
    # of the port names but not others.)
    AT_CAPTURE_FILE([query])
    AT_CAPTURE_FILE([expout])
    AT_CAPTURE_FILE([stdout])
    OVS_WAIT_UNTIL([. ./query | sed 's/"//g' > stdout #"
                    diff -u stdout expout >/dev/null])
}

# Make sure that the configured bridge mappings in the Open_vSwitch db
# is mirrored into the Chassis record in the OVN_Southbound db.
check_bridge_mappings () {
    local_mappings=$1
    sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id)
    chassis_mappings=$(ovn-sbctl get Chassis ${sysid} external_ids:ovn-bridge-mappings | sed -e 's/\"//g')
    echo $local_mappings
    echo $chassis_mappings
    AT_CHECK([test "${local_mappings}" = "${chassis_mappings}"])
}

# Initially there should be no patch ports.
check_patches

# Configure two ovn-bridge mappings, but no patch ports should be created yet
AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0,physnet2:br-eth1])
check_bridge_mappings "physnet1:br-eth0,physnet2:br-eth1"
check_patches

# Create a localnet port, but we should still have no patch ports, as they
# won't be created until there's a localnet port on a logical switch with
# another logical port bound to this chassis.
ovn-sbctl \
    -- --id=@dp101 create Datapath_Binding tunnel_key=101 \
    -- create Port_Binding datapath=@dp101 logical_port=localnet1 tunnel_key=1 \
        type=localnet options:network_name=physnet1
check_patches

# Create a localnet port on a logical switch with a port bound to this chassis.
# Now we should get some patch ports created.
ovn-sbctl \
    -- --id=@dp102 create Datapath_Binding tunnel_key=102 \
    -- create Port_Binding datapath=@dp102 logical_port=localnet2 tunnel_key=1 \
        type=localnet options:network_name=physnet1 \
    -- create Port_Binding datapath=@dp102 logical_port=localvif2 tunnel_key=2
ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2
check_patches \
    'br-int  patch-br-int-to-localnet2 patch-localnet2-to-br-int' \
    'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2'

# Add logical patch ports.
AT_CHECK([ovn-sbctl \
    -- --id=@dp1 create Datapath_Binding tunnel_key=1 \
    -- --id=@dp2 create Datapath_Binding tunnel_key=2 \
    -- create Port_Binding datapath=@dp1 logical_port=foo tunnel_key=1 type=patch options:peer=bar \
    -- create Port_Binding datapath=@dp2 logical_port=bar tunnel_key=2 type=patch options:peer=foo \
| ${PERL} $srcdir/uuidfilt.pl], [0], [<0>
<1>
<2>
<3>
])
check_patches \
    'br-int  patch-br-int-to-localnet2 patch-localnet2-to-br-int' \
    'br-eth0 patch-localnet2-to-br-int patch-br-int-to-localnet2' \
    'br-int  patch-foo-to-bar        patch-bar-to-foo' \
    'br-int  patch-bar-to-foo        patch-foo-to-bar'

# Delete the mapping and the ovn-bridge-mapping patch ports should go away;
# the ones from the logical patch port remain.
AT_CHECK([ovs-vsctl remove Open_vSwitch . external-ids ovn-bridge-mappings])
check_bridge_mappings
check_patches \
    'br-int patch-foo-to-bar patch-bar-to-foo' \
    'br-int patch-bar-to-foo patch-foo-to-bar'

# Change name of logical patch port, check that the OVS patch ports
# get updated.
AT_CHECK([ovn-sbctl \
    -- set Port_Binding foo logical_port=quux options:peer=baz \
    -- set Port_Binding bar logical_port=baz  options:peer=quux])
check_patches \
    'br-int patch-quux-to-baz patch-baz-to-quux' \
    'br-int patch-baz-to-quux patch-quux-to-baz'

# Create an empty database, serve it and switch to it
# and verify that the OVS patch ports disappear
# then put it back and verify that they reappear

on_exit 'kill `cat $ovs_base/ovn-sb/ovsdb-server-2.pid`'

ovsdb-tool create $ovs_base/ovn-sb/ovn-sb1.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
as ovn-sb ovsdb-server --detach --pidfile=$ovs_base/ovn-sb/ovsdb-server-2.pid --remote=punix:$ovs_base/ovn-sb/ovn-sb1.sock $ovs_base/ovn-sb/ovn-sb1.db \
   --unixctl=$ovs_base/ovn-sb/ovsdb-server-2.ctl
AT_CHECK([ovs-vsctl -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb1.sock])
check_patches
AT_CHECK([ovs-vsctl -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock])
check_patches \
    'br-int patch-quux-to-baz patch-baz-to-quux' \
    'br-int patch-baz-to-quux patch-quux-to-baz'

# Change the logical patch ports to VIFs and verify that the OVS patch
# ports disappear.
AT_CHECK([ovn-sbctl \
    -- set Port_Binding quux type='""' options='{}' \
    -- set Port_Binding baz type='""' options='{}'])
check_patches

# Gracefully terminate daemons
OVN_CLEANUP_SBOX([hv])
OVN_CLEANUP_VSWITCH([main])
as ovn-sb
OVS_APP_EXIT_AND_WAIT_BY_TARGET([$ovs_base/ovn-sb/ovsdb-server-2.ctl], [$ovs_base/ovn-sb/ovsdb-server-2.pid])
OVS_APP_EXIT_AND_WAIT([ovsdb-server])

AT_CLEANUP

# Checks that ovn-controller populates datapath-type and iface-types
# correctly in the Chassis external-ids column.
AT_SETUP([ovn-controller - Chassis external_ids])
AT_KEYWORDS([ovn])
ovn_init_db ovn-sb

net_add n1
sim_add hv
as hv
ovs-vsctl \
    -- add-br br-phys \
    -- add-br br-eth0 \
    -- add-br br-eth1 \
    -- add-br br-eth2
ovn_attach n1 br-phys 192.168.0.1

sysid=$(ovs-vsctl get Open_vSwitch . external_ids:system-id)

# Make sure that the datapath_type set in the Bridge table
# is mirrored into the Chassis record in the OVN_Southbound db.
check_datapath_type () {
    datapath_type=$1
    chassis_datapath_type=$(ovn-sbctl get Chassis ${sysid} external_ids:datapath-type | sed -e 's/"//g') #"
    test "${datapath_type}" = "${chassis_datapath_type}"
}

OVS_WAIT_UNTIL([check_datapath_type ""])

ovs-vsctl set Bridge br-int datapath-type=foo
OVS_WAIT_UNTIL([check_datapath_type foo])

# Change "ovn-bridge-mappings" value. It should not change the "datapath-type".
ovs-vsctl set Open_vSwitch . external_ids:ovn-bridge-mappings=foo-mapping
check_datapath_type foo

ovs-vsctl set Bridge br-int datapath-type=bar
OVS_WAIT_UNTIL([check_datapath_type bar])

ovs-vsctl set Bridge br-int datapath-type=\"\"
OVS_WAIT_UNTIL([check_datapath_type ""])

expected_iface_types=$(ovs-vsctl get Open_vSwitch . iface_types|sed 's/[[]][[ ]]//g')
chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
echo "chassis_iface_types = ${chassis_iface_types}"
AT_CHECK([test "${expected_iface_types}" = "${chassis_iface_types}"])

# Change the value of external_ids:iface-types using ovn-sbctl.
# ovn-controller should again set it back to proper one.
ovn-sbctl set Chassis ${sysid} external_ids:iface-types="foo"
OVS_WAIT_UNTIL([
    chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
    echo "chassis_iface_types = ${chassis_iface_types}"
    test "${expected_iface_types}" = "${chassis_iface_types}"
])

# Gracefully terminate daemons
OVN_CLEANUP_SBOX([hv])
OVN_CLEANUP_VSWITCH([main])
as ovn-sb
OVS_APP_EXIT_AND_WAIT([ovsdb-server])

AT_CLEANUP

# Checks that ovn-controller correctly maintains the mapping from the Encap
# table in the Southbound database to OVS in the face of changes on both sides
AT_SETUP([ovn-controller - change Encap properties])
AT_KEYWORDS([ovn])
ovn_init_db ovn-sb

net_add n1
sim_add hv
as hv
ovs-vsctl \
    -- add-br br-phys \
    -- add-br br-eth0 \
    -- add-br br-eth1 \
    -- add-br br-eth2
ovn_attach n1 br-phys 192.168.0.1

check_tunnel_property () {
    test "`ovs-vsctl get interface ovn-fakech-0 $1`" = "$2"
}

# Start off with a remote chassis supporting STT
ovn-sbctl chassis-add fakechassis stt 192.168.0.2
OVS_WAIT_UNTIL([check_tunnel_property type stt])

# See if we switch to Geneve as the first choice when it is available
encap_uuid=$(ovn-sbctl add chassis fakechassis encaps @encap -- --id=@encap create encap type=geneve ip="127.0.0.1")
OVS_WAIT_UNTIL([check_tunnel_property type geneve])

# Check that changes within an encap row are propagated
ovn-sbctl set encap ${encap_uuid} ip=192.168.0.2
OVS_WAIT_UNTIL([check_tunnel_property options:remote_ip "\"192.168.0.2\""])

# Change the type on the OVS side and check than OVN fixes it
ovs-vsctl set interface ovn-fakech-0 type=vxlan
OVS_WAIT_UNTIL([check_tunnel_property type geneve])

# Delete the port entirely and it should be resurrected
ovs-vsctl del-port ovn-fakech-0
OVS_WAIT_UNTIL([check_tunnel_property type geneve])

# Gracefully terminate daemons
OVN_CLEANUP_SBOX([hv])
OVN_CLEANUP_VSWITCH([main])
as ovn-sb
OVS_APP_EXIT_AND_WAIT([ovsdb-server])

AT_CLEANUP