Remove code for backuprestore
[integration/test.git] / csit / libraries / GBP / OpenFlowUtils.robot
1 *** Settings ***
2 Documentation       Operations on Docker containers for GBP
3
4 Library             SSHLibrary
5 Library             Collections
6 Resource            ../Utils.robot
7 Resource            ConnUtils.robot
8 Resource            DockerUtils.robot
9 Variables           ../../variables/Variables.py
10 Library             OperatingSystem
11
12
13 *** Keywords ***
14 Inspect Service Function
15     [Documentation]    Inspects traffic passing through service function node.
16     [Arguments]    ${in_port}    ${out_port}    ${outer_src_ip}    ${outer_dst_ip}    ${eth_type}    ${inner_src_ip}
17     ...    ${inner_dst_ip}    ${next_hop_ip}    ${nsp}    ${received_nsi}    ${proto}=${EMPTY}
18     @{matches}    Create List
19     @{actions}    Create List
20     Append In Port Check    ${matches}    ${in_port}
21     Append Ether-Type Check    ${matches}    ${eth_type}
22     Append Tunnel Set Check    ${matches}
23     Append Outer IPs Check
24     ...    ${matches}
25     ...    src_ip=${outer__src_ip}/255.255.255.255
26     ...    dst_ip=${outer_dst_ip}/255.255.255.255
27     Append NSI Check    ${matches}    ${received_nsi}
28     Append NSP Check    ${matches}    ${nsp}
29     Append Inner IPs Check    ${matches}    ${inner_src_ip}/0.0.0.0    ${inner_dst_ip}/0.0.0.0
30     IF    "${proto}" != "${EMPTY}"
31         Append Proto Check    ${matches}    ${proto}
32     END
33     Append Tunnel Set Check    ${actions}
34     Append Outer IPs Check    ${actions}    dst_ip=${next_hop_ip}
35     ${rewritten_nsi}    Evaluate    ${received_nsi} -1
36     Append NSI Check    ${actions}    ${rewritten_nsi}
37     Append NSP Check    ${actions}    ${nsp}
38     Append Out Port Check    ${actions}    ${out_port}
39     ${flow}    Find Flow in DPCTL Output    ${matches}    ${actions}
40     RETURN    ${flow}
41
42 Inspect Service Function Forwarder
43     [Documentation]    Inspects traffic passing through service function forwarder node.
44     [Arguments]    ${in_port}    ${out_port}    ${outer_src_ip}    ${outer_dst_ip}    ${eth_type}    ${inner_src_ip}
45     ...    ${inner_dst_ip}    ${next_hop_ip}    ${nsp}    ${nsi}    ${proto}=${EMPTY}
46     @{matches}    Create List
47     @{actions}    Create List
48     Append In Port Check    ${matches}    ${in_port}
49     Append Ether-Type Check    ${matches}    ${eth_type}
50     Append Tunnel Set Check    ${matches}
51     Append Outer IPs Check    ${matches}    src_ip=${outer_src_ip}    dst_ip=${outer_dst_ip}
52     Append NSI Check    ${matches}    ${nsi}
53     Append NSP Check    ${matches}    ${nsp}
54     Append Inner IPs Check    ${matches}    ${inner_src_ip}/255.255.255.255    ${inner_dst_ip}/255.255.255.255
55     IF    "${proto}" != "${EMPTY}"
56         Append Proto Check    ${matches}    ${proto}
57     END
58     Append Tunnel Set Check    ${actions}
59     Append Outer IPs Check    ${actions}    dst_ip=${next_hop_ip}
60     Append NSI Check    ${actions}    ${nsi}
61     Append NSP Check    ${actions}    ${nsp}
62     Append Out Port Check    ${actions}    ${out_port}
63     ${flow}    Find Flow in DPCTL Output    ${matches}    ${actions}
64     RETURN    ${flow}
65
66 Inspect Classifier Outbound
67     [Documentation]    Inspects outbound traffic of a classifier. Traffic source should be located on the classifier.
68     ...    If traffic destination is located on the same VM, do not specify neither of next_hop_ip and nsi.
69     ...    If traffic destination is located on different VM and the traffic is not forwarded into a chain, specify
70     ...    next_hop_ip and don't specify nsi.
71     ...    If traffic destination is located on different VM and the traffic is forwarded into a chain, specify both
72     ...    next_hop_ip and nsi.
73     [Arguments]    ${in_port}    ${out_port}    ${eth_type}    ${inner_src_ip}    ${inner_dst_ip}    ${next_hop_ip}=${EMPTY}
74     ...    ${nsi}=${EMPTY}    ${proto}=${EMPTY}    ${src_port}=${EMPTY}    ${dst_port}=${EMPTY}
75     @{matches}    Create List
76     @{actions}    Create List
77     Append In Port Check    ${matches}    ${in_port}
78     Append Ether-Type Check    ${matches}    ${eth_type}
79     IF    "${proto}" != "${EMPTY}"
80         Append Proto Check    ${matches}    ${proto}
81     END
82     IF    "${src_port}"!="${EMPTY}" or "${dst_port}"!="${EMPTY}"
83         Append L4 Check    ${matches}    src_port=${src_port}    dst_port=${dst_port}
84     END
85     Append Out Port Check    ${actions}    ${out_port}
86     Append Inner IPs Check    ${actions}    ${inner_src_ip}    ${inner_dst_ip}
87     IF    "${next_hop_ip}"!="${EMPTY}"
88         Append Tunnel Set Check    ${actions}
89         Append Outer IPs Check    ${actions}    dst_ip=${next_hop_ip}
90     ELSE
91         Append Tunnel Not Set Check    ${actions}
92     END
93     IF    "${nsi}"!="${EMPTY}"    Append NSI Check    ${actions}    255
94     ${flow}    Find Flow in DPCTL Output    ${matches}    ${actions}
95     RETURN    ${flow}
96
97 Inspect Classifier Inbound
98     [Documentation]    Inspects inbound traffic of a classifier. Traffic destination should be located on the classifier.
99     ...    If traffic source is located on different VM and the traffic comes out of a chain, specify nsi and nsp values.
100     ...    If traffic source is located on different VM and the traffic does not comes out of a chain, do not specify
101     ...    neither of nsi and nsp values.
102     [Arguments]    ${in_port}    ${out_port}    ${eth_type}    ${inner_src_ip}    ${inner_dst_ip}    ${outer_src_ip}
103     ...    ${outer_dst_ip}    ${nsp}=${EMPTY}    ${nsi}=${EMPTY}    ${proto}=${EMPTY}    ${src_port}=${EMPTY}    ${dst_port}=${EMPTY}
104     @{matches}    Create List
105     @{actions}    Create List
106     Append In Port Check    ${matches}    ${in_port}
107     Append Ether-Type Check    ${matches}    ${eth_type}
108     Append Outer IPs Check    ${matches}    src_ip=${outer_src_ip}    dst_ip=${outer_dst_ip}
109     Append Inner IPs Check    ${matches}    ${inner_src_ip}    ${inner_dst_ip}
110     IF    "${src_port}"!="${EMPTY}" or "${dst_port}"!="${EMPTY}"
111         Append L4 Check    ${matches}    src_port=${src_port}    dst_port=${dst_port}
112     END
113     Append Tunnel Set Check    ${matches}
114     IF    "${nsi}"!="${EMPTY}" and "${nsp}"!="${EMPTY}"
115         Append NSI Check    ${matches}    ${nsi}
116         Append NSP Check    ${matches}    ${nsp}
117     END
118     IF    "${proto}" != "${EMPTY}"
119         Append Proto Check    ${matches}    ${proto}
120         Append Proto Check    ${actions}    ${proto}
121     END
122     Append Out Port Check    ${actions}    ${out_port}
123     Append Inner IPs Check    ${actions}    ${inner_src_ip}    ${inner_dst_ip}
124     ${flow}    Find Flow in DPCTL Output    ${matches}    ${actions}
125     RETURN    ${flow}
126
127 Find Flow in DPCTL Output
128     [Documentation]    Executes 'ovs-dpctl dump-flows' on remote system and goes through each output line.
129     ...    A line is returned if all the criterias in actions part and matches part are matched. This is
130     ...    done by calling 'Check Match' keyword. If no match is found for any of the flows, caller test case
131     ...    will be failed.
132     [Arguments]    ${flow_match_criteria}    ${flow_action_criteria}
133     ${output}    SSHLibrary.Execute Command    sudo ovs-dpctl dump-flows
134     Log    ${output}
135     @{lines}    Split To Lines    ${output}
136     ${match_result}    Set Variable
137     ${action_result}    Set Variable
138     FOR    ${line}    IN    @{lines}
139         ${match}    Get Matches Part    ${line}
140         ${action}    Get Actions Part    ${line}
141         ${match_result}    Check Match    ${match}    @{flow_match_criteria}
142         ${action_result}    Check Match    ${action}    @{flow_action_criteria}
143         IF    "${match_result}" == "TRUE" and "${action_result}" == "TRUE"
144             RETURN    ${line}
145         END
146     END
147     Log    ${flow_match_criteria}
148     Log    ${flow_action_criteria}
149     Fail    Flow not found!
150
151 Get Matches Part
152     [Documentation]    Returns matches part of a flow captured with 'ovs-dpctl dump-flows'.
153     [Arguments]    ${ovs-dpctl_flow}
154     @{matches_actions}    Split String    ${ovs-dpctl_flow}    actions
155     Log    ${matches_actions[0]}
156     RETURN    ${matches_actions[0]}
157
158 Get Actions Part
159     [Documentation]    Returns actions part of a flow captured with 'ovs-dpctl dump-flows'.
160     [Arguments]    ${ovs-dpctl_flow}
161     @{matches_actions}    Split String    ${ovs-dpctl_flow}    actions
162     RETURN    ${matches_actions[1]}
163
164 Check Match
165     [Documentation]    Applies 'grep' on the string argument for each criterion.
166     [Arguments]    ${string}    @{match_criteria}
167     ${conditions}    Set Variable
168     FOR    ${criterio}    IN    @{match_criteria}
169         ${grep_criterio}    Catenate    | grep    ${criterio}
170         ${conditions}    Catenate    ${conditions}    ${grep_criterio}
171         ${debug_output}    OperatingSystem.Run    echo "${string}" ${conditions}
172         Log    ${debug_output}
173         IF    "${debug_output}" == "${EMPTY}"    Log    ${criterio}
174     END
175     ${output}    OperatingSystem.Run    echo "${string}" ${conditions}
176     Log    ${output}
177     IF    "${output}" == "${EMPTY}"    RETURN    FALSE    ELSE    RETURN    TRUE
178
179 Append Proto Check
180     [Documentation]    Returns proto part of flow can be captured with 'ovs-dpctl dump-flows'.
181     [Arguments]    ${list}    ${proto}
182     Append To List    ${list}    proto=${proto}
183
184 Append Inner MAC Check
185     [Documentation]    Returns encapsulated MAC addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
186     [Arguments]    ${list}    ${src_addr}=${EMPTY}    ${dst_addr}=${EMPTY}
187     IF    "${src_addr}" != "${EMPTY}" and "${dst_addr}" != "${EMPTY}"
188         Append To List    ${list}    "eth(src=${src_addr},dst=${dst_addr})"
189     ELSE IF    "${src_addr}" != "${EMPTY}"
190         Append To List    ${list}    "eth(src=${src_addr},dst=.*)"
191     ELSE IF    "${dst_addr}" != "${EMPTY}"
192         Append To List    ${list}    "eth(src=.*,dst=${dst_addr})"
193     ELSE
194         Fail    Specify at liest src or dest IP!
195     END
196
197 Append Inner IPs Check
198     [Documentation]    Returns encapsulated IP addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
199     [Arguments]    ${list}    ${src_ip}=${EMPTY}    ${dst_ip}=${EMPTY}
200     IF    "${src_ip}" != "${EMPTY}" and "${dst_ip}" != "${EMPTY}"
201         Append To List    ${list}    "ipv4(src=${src_ip},dst=${dst_ip}"
202     ELSE IF    "${src_ip}" != "${EMPTY}"
203         Append To List    ${list}    "ipv4(src=${src_ip},dst=.*"
204     ELSE IF    "${dst_ip}" != "${EMPTY}"
205         Append To List    ${list}    "ipv4(src=.*,dst=${dst_ip}"
206     ELSE
207         Fail    Specify at liest src or dest IP!
208     END
209
210 Append Outer IPs Check
211     [Documentation]    Returns packet IP addresses part of flow can be captured with 'ovs-dpctl dump-flows'.
212     [Arguments]    ${list}    ${src_ip}=${EMPTY}    ${dst_ip}=${EMPTY}
213     IF    "${src_ip}" != "${EMPTY}"
214         Append To List    ${list}    src=${src_ip}
215     ELSE IF    "${dst_ip}" != "${EMPTY}"
216         Append To List    ${list}    dst=${dst_ip}
217     ELSE
218         Fail    Specify at liest src or dest IP!
219     END
220
221 Append In Port Check
222     [Documentation]    Returns ingress port part of flow can be captured with 'ovs-dpctl dump-flows'.
223     [Arguments]    ${list}    ${in_port}
224     Append To List    ${list}    "in_port(${in_port})"
225
226 Append Out Port Check
227     [Documentation]    Returns egress port part of flow can be captured with 'ovs-dpctl dump-flows'.
228     [Arguments]    ${list}    ${out_port}
229     Append To List    ${list}    ,${out_port}
230
231 Append L4 Check
232     [Documentation]    Returns L4 port part of flow can be captured with 'ovs-dpctl dump-flows'.
233     [Arguments]    ${list}    ${src_port}=${EMPTY}    ${dst_port}=${EMPTY}
234     IF    "${src_port}" != "${EMPTY}"
235         Append To List    ${list}    src=${src_port}
236     ELSE IF    "${dst_port}" != "${EMPTY}"
237         Append To List    ${list}    dst=${dst_port}
238     ELSE
239         Fail    Specify at liest src or dest port!
240     END
241
242 Append NSI Check
243     [Documentation]    Returns NSI part of flow can be captured with 'ovs-dpctl dump-flows'.
244     [Arguments]    ${list}    ${nsi}
245     Append To List    ${list}    nsi=${nsi}
246
247 Append NSP Check
248     [Documentation]    Returns NSP part of flow can be captured with 'ovs-dpctl dump-flows'.
249     [Arguments]    ${list}    ${nsp}
250     Append To List    ${list}    nsp=${nsp}
251
252 Append Ether-Type Check
253     [Documentation]    Returns Ether-Type part of flow can be captured with 'ovs-dpctl dump-flows'.
254     [Arguments]    ${list}    ${eth_type}
255     Append To List    ${list}    "eth_type(${eth_type})"
256
257 Append Tunnel Set Check
258     [Documentation]    Tunnel ID is locally significant to neighbouring nodes and it is not
259     ...    statically determined. By checking it's presence in match ( or action) fields,
260     ...    we can say whether a packet was received (or send out) via tunnel port.
261     [Arguments]    ${list}
262     Append To List    ${list}    tun_id
263
264 Append Tunnel Not Set Check
265     [Documentation]    Tunnel ID is locally significant to neighbouring nodes and it is not
266     ...    statically determined. By checking it's presence in match ( or action) fields,
267     ...    we can say whether a packet was received (or send out) via tunnel port.
268     [Arguments]    ${list}
269     Append To List    ${list}    -v tun_id
270
271 Get NSP Value From Flow
272     [Documentation]    Reads and returns nsp value from flow captured with 'ovs-dpctl dump-flows'.
273     [Arguments]    ${flow}
274     ${flow}    Get Actions Part    ${flow}
275     ${output}    OperatingSystem.Run    echo "\$${flow}" | sed 's/.*nsp=/nsp=/' | sed 's/,.*//' | sed 's/.*=//'
276     RETURN    ${output}
277
278 Manager is Connected
279     ${output}    SSHLibrary.Execute Command    sudo ovs-vsctl show
280     Should Contain    ${output}    is_connected: true
281
282 Manager and Switch Connected
283     [Arguments]    ${sw_name}
284     ${output}    SSHLibrary.Execute Command    sudo ovs-vsctl show
285     Should Contain    ${output}    ${sw_name}
286     Should Contain x Times    ${output}    is_connected: true    2
287
288 Wait For Flows On Switch
289     [Documentation]    Counts flows on switch, fails if 0
290     [Arguments]    ${switch_ip}    ${switch_name}
291     ConnUtils.Connect and Login    ${switch_ip}
292     # check for OVS errors first
293     ${stdout}    ${stderr}    SSHLibrary.Execute Command
294     ...    sudo ovs-ofctl dump-flows ${switch_name} -OOpenFlow13
295     ...    return_stderr=True
296     IF    "${stderr}" != "${EMPTY}"    Fatal Error    ${stderr}
297     Wait Until Keyword Succeeds    120s    20s    Count Flows On Switch    ${switch_name}
298     SSHLibrary.Close Connection
299
300 Show Switch Status
301     [Documentation]    Shows status of a switch for easier debugging.
302     [Arguments]    ${switch_name}
303     ${stdout}    ${stderr}    SSHLibrary.Execute Command
304     ...    sudo ovs-ofctl dump-flows ${switch_name} -OOpenFlow13
305     ...    return_stderr=True
306     Log    ${stdout}
307     ${stdout}    ${stderr}    SSHLibrary.Execute Command    sudo ovs-vsctl show    return_stderr=True
308     Log    ${stdout}
309
310 Count Flows On Switch
311     [Arguments]    ${switch_name}
312     ${out}    SSHLibrary.Execute Command
313     ...    printf "%d" $(($(sudo ovs-ofctl dump-flows ${switch_name} -OOpenFlow13 | wc -l)-1))
314     Should Be True    ${out}>0