summaryrefslogtreecommitdiff
path: root/tests/ovn-controller-vtep.at
blob: 063feebcf388bd1914c5a3d0cbccf52757e8066e (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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
AT_BANNER([ovn_controller_vtep])

# OVN_CONTROLLER_VTEP_START
#
# Starts the test with a setup with vtep device.  Each test case must first
# call this macro.
#
# Uses vtep-ovs to simulate the vtep switch 'br-vtep' with two physical ports
# 'p0', 'p1'.
#
# Configures ovn-nb with a logical switch 'br-test'.
#
#
m4_define([OVN_CONTROLLER_VTEP_START],
  [
   # this will cause skip when 'make check' using Windows setup.
   AT_SKIP_IF([test $HAVE_PYTHON = no])

   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
   OVS_LOGDIR=`pwd`; export OVS_LOGDIR
   OVS_DBDIR=`pwd`; export OVS_DBDIR
   OVS_SYSCONFDIR=`pwd`; export OVS_SYSCONFDIR

   dnl Create databases (ovn-nb, ovn-sb, vtep).
   AT_CHECK([ovsdb-tool create vswitchd.db $abs_top_srcdir/vswitchd/vswitch.ovsschema])
   for daemon in ovn-nb ovn-sb vtep; do
      AT_CHECK([ovsdb-tool create $daemon.db $abs_top_srcdir/${daemon%%-*}/${daemon}.ovsschema])
   done

   dnl Start ovsdb-server.
   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --log-file --remote=punix:$OVS_RUNDIR/db.sock vswitchd.db vtep.db ovn-nb.db ovn-sb.db], [0], [], [stderr])
    ON_EXIT_UNQUOTED([kill `cat ovsdb-server.pid`])
   AT_CHECK([[sed < stderr '
/vlog|INFO|opened log file/d
/ovsdb_server|INFO|ovsdb-server (Open vSwitch)/d']])
   AT_CAPTURE_FILE([ovsdb-server.log])

   dnl Start ovs-vswitchd.
   AT_CHECK([ovs-vswitchd --enable-dummy --disable-system --detach --no-chdir --pidfile --log-file -vvconn -vofproto_dpif], [0], [], [stderr])
   AT_CAPTURE_FILE([ovs-vswitchd.log])
   ON_EXIT_UNQUOTED([kill `cat ovs-vswitchd.pid`])
   AT_CHECK([[sed < stderr '
/ovs_numa|INFO|Discovered /d
/vlog|INFO|opened log file/d
/vswitchd|INFO|ovs-vswitchd (Open vSwitch)/d
/reconnect|INFO|/d
/ofproto|INFO|using datapath ID/d
/ofproto|INFO|datapath ID changed to fedcba9876543210/d']])
   AT_CHECK([ovs-vsctl -- add-br br-vtep \
              -- set bridge br-vtep datapath-type=dummy other-config:datapath-id=fedcba9876543210 other-config:hwaddr=aa:55:aa:55:00:00 protocols=[[OpenFlow10,OpenFlow11,OpenFlow12,OpenFlow13,OpenFlow14,OpenFlow15]] fail-mode=secure \
              -- add-port br-vtep p0 -- set Interface p0 type=dummy ofport_request=1 \
              -- add-port br-vtep p1 -- set Interface p1 type=dummy ofport_request=2])

   dnl Start ovs-vtep.
   AT_CHECK([vtep-ctl add-ps br-vtep -- set Physical_Switch br-vtep tunnel_ips=1.2.3.4])
   AT_CHECK([ovs-vtep --log-file=ovs-vtep.log --pidfile=ovs-vtep.pid --detach br-vtep \], [0], [], [stderr])
   ON_EXIT_UNQUOTED([kill `cat ovs-vtep.pid`])
   AT_CHECK([[sed < stderr '
/vlog|INFO|opened log file/d']])
   # waits until ovs-vtep starts up.
   OVS_WAIT_UNTIL([test -n "`vtep-ctl show | grep Physical_Port`"])

   dnl Start ovn-northd.
   AT_CHECK([ovn-nbctl lswitch-add br-test])
   AT_CHECK([ovn-northd --detach --pidfile --log-file --ovnnb-db=unix:$OVS_RUNDIR/db.sock --ovnsb-db=unix:$OVS_RUNDIR/db.sock], [0], [], [stderr])
   ON_EXIT_UNQUOTED([kill `cat ovn-northd.pid`])
   AT_CHECK([[sed < stderr '
/vlog|INFO|opened log file/d']])
   AT_CAPTURE_FILE([ovn-northd.log])

   dnl Start ovn-controllger-vtep.
   AT_CHECK([ovn-controller-vtep --detach --pidfile --log-file --vtep-db=unix:$OVS_RUNDIR/db.sock --ovnsb-db=unix:$OVS_RUNDIR/db.sock], [0], [], [stderr])
   AT_CAPTURE_FILE([ovn-controller-vtep.log])
   ON_EXIT_UNQUOTED([kill `cat ovn-controller-vtep.pid`])
   AT_CHECK([[sed < stderr '
/vlog|INFO|opened log file/d
/reconnect|INFO|/d']])
])

# OVN_CONTROLLER_VTEP_STOP
#
# So many exits... Yeah, we started a lot daemons~
#
m4_define([OVN_CONTROLLER_VTEP_STOP],
  [# removes all 'Broken pipe' warning logs from ovsdb-server.log.  this is in
   # that *ctl command (e.g. ovn-nbctl) exits right after committing the change
   # to database.  however, in reaction, some daemon (e.g. ovn-controller-vtep)
   # may immediately update the database.  this later update may cause database
   # sending update back to *ctl command if *ctl has not proceeded to exit yet.
   # and if *ctl command exits before database calling send, the send from
   # database will fail with 'Broken pipe' error.
   AT_CHECK([check_logs "$1
/Broken pipe/d"])
   AT_CHECK([ovs-appctl -t ovs-vtep exit])
   AT_CHECK([ovs-appctl -t ovn-northd exit])
   AT_CHECK([ovs-appctl -t ovn-controller-vtep exit])
   # makes sure ovn-controller-vtep exits.
   OVS_WAIT_UNTIL([test ! -f ovn-controller-vtep.pid])
   AT_CHECK([ovs-appctl -t ovsdb-server exit])
   AT_CHECK([ovs-appctl -t ovs-vswitchd exit])])

# Adds logical port for a vtep gateway chassis in ovn-nb database.
#
# $1: logical switch name in ovn-nb database
# $2: logical port name
# $3: physical vtep gateway name
# $4: logical switch name on vtep gateway chassis
m4_define([OVN_NB_ADD_VTEP_PORT], [
AT_CHECK([ovn-nbctl lport-add $1 $2])
AT_CHECK([ovn-nbctl lport-set-type $2 vtep])
AT_CHECK([ovn-nbctl lport-set-options $2 vtep-physical-switch=$3 vtep-logical-switch=$4])
])

##############################################

# tests chassis related updates.
AT_SETUP([ovn-controller-vtep - test chassis])
OVN_CONTROLLER_VTEP_START

# verifies the initial ovn-sb db configuration.
AT_CHECK([ovn-sbctl show], [0], [dnl
Chassis br-vtep
    Encap vxlan
        ip: "1.2.3.4"
])

# deletes the chassis via ovn-sbctl and check that it is readded back
# with the log.
AT_CHECK([ovn-sbctl chassis-del br-vtep])
OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"])
AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log], [0], [dnl
|WARN|Chassis for VTEP physical switch (br-vtep) disappears, maybe deleted by ovn-sbctl, adding it back
])

# changes the tunnel_ip on physical switch, watches the update of chassis's
# encap.
AT_CHECK([vtep-ctl set Physical_Switch br-vtep tunnel_ips=1.2.3.5])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl show | grep 1\.2\.3\.5`"])
AT_CHECK([ovn-sbctl --columns=ip list Encap | cut -d ':' -f2 | tr -d ' '], [0], [dnl
"1.2.3.5"
])

# adds vlan_bindings to physical ports.
AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 -- bind-ls br-vtep p0 200 lswitch0 -- bind-ls br-vtep p1 300 lswitch0])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Chassis | grep -- lswitch0`"])
AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
[["lswitch0"]]
])

# adds another logical switch and new vlan_bindings.
AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 300 lswitch1])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Chassis | grep -- lswitch1`"])
AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' '], [0], [dnl
[["lswitch0","lswitch1"]]
])

# unbinds one port from lswitch0, nothing should change.
AT_CHECK([vtep-ctl unbind-ls br-vtep p0 200])
OVS_WAIT_UNTIL([test -z "`vtep-ctl --columns=vlan_bindings list physical_port p0 | grep -- '200='`"])
AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
[["lswitch0","lswitch1"]]
])

# unbinds all ports from lswitch0.
AT_CHECK([vtep-ctl unbind-ls br-vtep p0 100 -- unbind-ls br-vtep p1 300])
OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch0`"])
AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' ' ], [0], [dnl
[["lswitch1"]]
])

# unbinds all ports from lswitch1.
AT_CHECK([vtep-ctl unbind-ls br-vtep p0 300])
OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch1`"])
AT_CHECK([ovn-sbctl --columns=vtep_logical_switches list Chassis | cut -d ':' -f2 | tr -d ' '], [0], [dnl
[[]]
])

OVN_CONTROLLER_VTEP_STOP([/Chassis for VTEP physical switch (br-vtep) disappears/d])
AT_CLEANUP


# Tests binding updates.
AT_SETUP([ovn-controller-vtep - test binding 1])
OVN_CONTROLLER_VTEP_START

# adds logical switch 'lswitch0' and vlan_bindings.
AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 -- bind-ls br-vtep p1 300 lswitch0])
# adds lport in ovn-nb database, and sets the type and options.
OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-vtep_lswitch0`"])
# should see one binding, associated to chassis of 'br-vtep'.
chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d ':' -f2 | tr -d ' ')
AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
${chassis_uuid}
])

# adds another logical switch 'lswitch1' and vlan_bindings.
AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 200 lswitch1])
# adds lport in ovn-nb database for lswitch1.
OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch1], [br-vtep], [lswitch1])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep -- br-vtep_lswitch1`"])
# This is allowed, but not recommended, to have two vlan_bindings (to different vtep logical switches)
# from one vtep gateway physical port in one ovn-nb logical swithch.
AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort -d], [0], [dnl

${chassis_uuid}
${chassis_uuid}
])

# adds another lport in ovn-nb database for lswitch0.
OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0_dup], [br-vtep], [lswitch0])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep -- br-vtep_lswitch0_dup`"])
# it is not allowed to have more than one ovn-nb logical port for the same
# vtep logical switch on a vtep gateway chassis, so should still see only
# two port_binding entries bound.
AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort -d], [0], [dnl


[[]]
${chassis_uuid}
${chassis_uuid}
])
# confirms the warning log.
AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g' | uniq], [0], [dnl
|WARN|logical switch (), on vtep gateway chassis () has already been associated with logical port (), ignore logical port ()
])

# deletes physical ports from vtep.
AT_CHECK([ovs-vsctl del-port p0 -- del-port p1])
AT_CHECK([vtep-ctl del-port br-vtep p0 -- del-port br-vtep p1])
OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- br-vtep_lswitch`"])
# should see empty chassis column in both binding entries.
AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut -d ':' -f2 | tr -d ' ' | sort], [0], [dnl


[[]]
[[]]
[[]]
])

OVN_CONTROLLER_VTEP_STOP([/has already been associated with logical port/d])
AT_CLEANUP


# Tests corner case: Binding the vtep logical switch from two different
# datapath.
AT_SETUP([ovn-controller-vtep - test binding 2])
OVN_CONTROLLER_VTEP_START

# adds logical switch 'lswitch0' and vlan_bindings.
AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0])
# adds lport in ovn-nb database, and sets the type and options.
OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], [lswitch0])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-vtep_lswitch0`"])

# adds another lswitch 'br-void' in ovn-nb database.
AT_CHECK([ovn-nbctl lswitch-add br-void])
# adds another vtep pswitch 'br-vtep-void' in vtep database.
AT_CHECK([vtep-ctl add-ps br-vtep-void -- add-port br-vtep-void p0-void -- bind-ls br-vtep-void p0-void 100 lswitch0])
# adds a conflicting logical port (both br-vtep_lswitch0 and br-vtep-void_lswitch0
# are bound to the same logical switch, but they are on different datapath).
OVN_NB_ADD_VTEP_PORT([br-void], [br-vtep-void_lswitch0], [br-vtep-void], [lswitch0])
OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding  | grep br-vtep-void_lswitch0`"])
OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"])
# confirms the warning log.
AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g;s/(with tunnel key [[0-9]][[0-9]]*)/()/g' | uniq], [0], [dnl
|WARN|logical switch (), on vtep gateway chassis () has already been associated with logical datapath (), ignore logical port () which belongs to logical datapath ()
])

# then deletes 'br-void' and 'br-vtep-void', should see 'br-vtep_lswitch0'
# bound correctly.
AT_CHECK([ovn-nbctl lswitch-del br-void])
# adds another vtep pswitch 'br-vtep-void' in vtep database.
AT_CHECK([vtep-ctl del-ps br-vtep-void])
OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Port_Binding | grep br-vtep-void_lswitch0`"])
chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d ':' -f2 | tr -d ' ')
AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl
${chassis_uuid}
])

OVN_CONTROLLER_VTEP_STOP([/has already been associated with logical datapath/d])
AT_CLEANUP