import robot
from robot.libraries.BuiltIn import BuiltIn
-##bare bones xml for building a flow
-xml_skeleton = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + \
+##bare bones xml for building a flow xml for flow:inventory
+flow_xml_skeleton = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + \
'<flow xmlns="urn:opendaylight:flow:inventory">' + \
'<instructions></instructions>' + \
'<match></match>' + \
'</flow>'
+input_xml_skeleton = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' + \
+ '<input xmlns="urn:opendaylight:flow:service">' + \
+ '</input>'
+
+
class Flow:
'''
Flow class for creating and interacting with OpenFlow flows
priority = 0
barrier = "false"
- xml = xml_skeleton
+ xml = ""
json = ""
'''
setattr(self, field, value)
-def Make_Flow_Object():
+def Make_Inventory_Flow():
'''
Robot Keyword to create and return an instance of the Flow
class.
'''
flow = Flow()
+ flow.xml = flow_xml_skeleton
+ return flow
+
+def Make_Service_Flow():
+ '''
+ Robot Keyword to create an input XML that can be used to
+ directly send to flow:service for things like accessing
+ the remove-flow RPC via restconf
+ '''
+ flow = Flow()
+ flow.xml = input_xml_skeleton
return flow
def Set_Flow_Field(flow, field, value):
Library XML
*** Variables ***
-##default flow attributes ...
-@{default_flow_fields} strict table_id id hard_timeout idle_timeout flow_name priority
-... barrier cookie cookie_mask
*** Keywords ***
-Create Flow
- [Documentation] Calls FlowLib.Make_Flow_Object() function and initializes and sanitizes
- ... the basic flow elements.
- ${flow}= Make Flow Object
- : FOR ${field} IN @{default_flow_fields}
- \ Set "${flow}" "${field}" With "${flow.${field}}"
+Create Inventory Flow
+ [Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
+ ... the basic flow elements that can be given to flow:inventory
+ ${flow}= Make Inventory Flow
+ [Return] ${flow}
+
+Create Service Flow
+ [Documentation] Used for creating an object that will use an XML format that
+ ... can be given to flow:service.
+ ${flow}= Make Service Flow
[Return] ${flow}
Set "${flow}" "${property}" With "${property_val}"
Remove Flow XML Element ${flow} match/${match_element}
[Return] ${flow}
+Set Flow XML Element Attribute
+ [Arguments] ${flow} ${element} ${id} ${value}
+ [Documentation] Will set the given id/value pair to the given to the element provided
+ ... and make the proper changes to the ${flow} object also provided.
+ ${flow_xml}= Parse XML ${flow.xml}
+ Set Element Attribute ${flow_xml} ${id} ${value} xpath=${element}
+ ${xml_string}= Element To String ${flow_xml}
+ Set Flow Field ${flow} xml ${xml_string}
+ Log ${flow.xml}
+ [Return] ${flow}
+
Add Flow XML Element
[Arguments] ${flow} ${element} ${element_val}=${EMPTY} ${xpath}=.
[Documentation] Will modify the current xml representation of the ${flow} object to contain
Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
${xml_string}= Element To String ${flow_xml}
Set Flow Field ${flow} xml ${xml_string}
+ Log ${flow.xml}
[Return] ${flow}
Remove Flow XML Element
Remove Default Flows
[Arguments] ${node_id}
[Documentation] Removes any flows considered "default". one such flow is
- ... to forward all traffic to the CONTROLLER. If/When others are implemented
- ... this keyword can be updated to include those.
- ##The preference for deleting flows would be via REST to the controller, but
- ##it's not possible with a call to the config API. For now, the flows are
- ##deleted via dpctl on mininet. The flows are present in the operational
- ##datastore, but you may need to wait for some time (15s) before it's refelcted
- ##there.
- write dpctl del-flows -O OpenFlow13
+ ... to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
+ ... If/When others are implemented this keyword can be updated to include those.
+ ${flow}= Make Service Flow
+ Set "${flow}" "priority" With "0"
+ Set "${flow}" "flow-table" With "0"
+ Add Flow XML Element ${flow} node /inv:nodes/inv:node[inv:id="${node_id}"]
+ Set Flow XML Element Attribute ${flow} node xmlns:inv urn:opendaylight:inventory
+ Log Flow XML is ${flow.xml}
+ write dpctl dump-flows -O OpenFlow13
${switchoutput} Read Until >
- #${flow}= Create Flow
- #Set "${flow}" "table_id" With "0"
- #Set "${flow}" "id" With "0"
- #Set Flow Output Action ${flow} 0 0 CONTROLLER
- #Log Flow XML is ${flow.xml}
- #Remove Flow From Controller And Verify ${flow.xml} ${node_id} ${flow.table_id} ${flow.id}
- #Run Keyword If "${verify_switch_flag}" == "yes" Verify Flow Does Not Exist On Mininet Switch CONTROLLER
+ ${headers}= Create Dictionary Content-Type application/yang.data+xml
+ ${resp} RequestsLibrary.Post session restconf/operations/sal-flow:remove-flow data=${flow.xml} headers=${headers}
+ Log ${resp.content}
+ Should Be Equal As Strings ${resp.status_code} 200
+ ${resp}= Get session ${REST_OPR}
+ Log ${resp.content}
+ Should Not Contain ${resp.content} "output-node-connector": "CONTROLLER",
+ ${strings_to_check_for}= Create List CONTROLLER
+ Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
${ethernet_match_dict}= Create Dictionary type=${eth_type} destination=${eth_dst} source=${eth_src}
${ipv4_match_dict}= Create Dictionary source=${ipv4_src} destination=${ipv4_dst}
##flow is a python Object to build flow details, including the xml format to send to controller
- ${flow}= Create Flow
+ ${flow}= Create Inventory Flow
Set "${flow}" "table_id" With "${table_id}"
Set "${flow}" "id" With "${flow_id}"
Clear Flow Actions ${flow}
... - output ALL
... - output CONTROLLER
... - output TABLE
-... - output IN_PORT
+... - output INPORT
... - output LOCAL
... - output NORMAL
... - output FLOOD
... - output ANY
...
-... NOTE: for OVS, IN_PORT does not appear to be supported
+... NOTE: for OVS, INPORT does not appear to be supported
Suite Setup Create Session session http://${CONTROLLER}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS_XML}
Suite Teardown Delete All Sessions
Test Template Create And Remove Flow
${eth_dst} ff:ff:ff:ff:ff:ff
${node_id} openflow:1
##documentation strings
-${IN_PORT_doc} OF1.3: OFPP_IN_PORT = 0xfffffff8, /* Send the packet out the input port. This\nreserved port must be explicitly used\nin order to send back out of the input\nport. */\n
+${INPORT_doc} OF1.3: OFPP_INPORT = 0xfffffff8, /* Send the packet out the input port. This\nreserved port must be explicitly used\nin order to send back out of the input\nport. */\n
${TABLE_doc} OF1.3: OFPP_TABLE = 0xfffffff9, /* Submit the packet to the first flow table NB: This destination port can only be used in packet-out messages. */
${NORMAL_doc} OF1.3 OFPP_NORMAL = 0xfffffffa, /* Process with normal L2/L3 switching. */
${FLOOD_doc} OF1.3 OFPP_FLOOD = 0xfffffffb, /* All physical ports in VLAN, except input port and those blocked or link down. */
${ANY_doc} OF1.3 OFPP_ANY = 0xffffffff /* Wildcard port used only for flow mod (delete) and flow stats requests. Selects all flows regardless of output port (including flows with no output port). */
*** Test Cases *** output port tableID flowID verify OVS? OVS specific strings
-IN_PORT [Documentation] ${IN_PORT_doc}
- [Tags] in_port
- ${TEST_NAME} 22 161 no actions=${TEST_NAME}
+INPORT [Documentation] ${INPORT_doc}
+ [Tags] inport
+ ${TEST_NAME} 22 161 yes actions=IN_PORT
TABLE [Documentation] ${TABLE_doc}
[Tags] table
Create And Remove Flow
[Arguments] ${output_port} ${table_id} ${flow_id} ${verify_switch_flag} ${additional_ovs_flowelements}
Remove Default Flows ${node_id}
- Run Keyword If "${output_port}" == "IN_PORT" Pass Execution Skipping ${output_port} test and marking it passed
Run Keyword If "${output_port}" == "ANY" Pass Execution Skipping ${output_port} test and marking it passed
@{OVS_FLOWELEMENTS} Create List dl_dst=${eth_dst} table=${table_id} dl_src=${eth_src} nw_src=${ipv4_src} nw_dst=${ipv4_dst}
... ${additional_ovs_flowelements}
${ethernet_match_dict}= Create Dictionary type=${eth_type} destination=${eth_dst} source=${eth_src}
${ipv4_match_dict}= Create Dictionary source=${ipv4_src} destination=${ipv4_dst}
##flow is a python Object to build flow details, including the xml format to send to controller
- ${flow}= Create Flow
+ ${flow}= Create Inventory Flow
Set "${flow}" "table_id" With "${table_id}"
Set "${flow}" "id" With "${flow_id}"
Clear Flow Actions ${flow}
${REST_CON} /restconf/config/opendaylight-inventory:nodes
${REST_OPR} /restconf/operational/opendaylight-inventory:nodes
${GENERIC_ACTION_FLOW_FILE} ${CURDIR}/../../../variables/xmls/genericActionFlow.xml
-${MININET_CMD} sudo mn --controller=remote,ip=${CONTROLLER} --topo tree,1 --switch ovsk,protocols=OpenFlow13
${ipv4_src} 10.1.2.0/24
${ipv4_dst} 40.4.0.0/16
${eth_type} 0x800
${ethernet_match_dict}= Create Dictionary type=${eth_type} destination=${eth_dst} source=${eth_src}
${ipv4_match_dict}= Create Dictionary source=${ipv4_src} destination=${ipv4_dst}
##flow is a python Object to build flow details, including the xml format to send to controller
- ${flow}= Create Flow
+ ${flow}= Create Inventory Flow
Set "${flow}" "table_id" With "${table_id}"
Set "${flow}" "id" With "${flow_id}"
Clear Flow Actions ${flow}
... - output ALL
... - output CONTROLLER
... - output TABLE
-... - output IN_PORT
+... - output INPORT
... - output LOCAL
... - output NORMAL
... - output FLOOD
... - output ANY
...
-... NOTE: for OVS, IN_PORT does not appear to be supported
+... NOTE: for OVS, INPORT does not appear to be supported
Suite Setup Create Session session http://${CONTROLLER}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS_XML}
Suite Teardown Delete All Sessions
Test Template Create And Remove Flow
*** Variables ***
${REST_CON} /restconf/config/opendaylight-inventory:nodes
${REST_OPR} /restconf/operational/opendaylight-inventory:nodes
-${GENERIC_ACTION_FLOW_FILE} ${CURDIR}/../../../variables/xmls/genericActionFlow.xml
-${MININET_CMD} sudo mn --controller=remote,ip=${CONTROLLER} --topo tree,1 --switch ovsk,protocols=OpenFlow13
${ipv4_src} 11.3.0.0/16
${ipv4_dst} 99.0.0.0/8
${eth_type} 0x800
${eth_dst} ff:ff:ff:ff:ff:ff
${node_id} openflow:1
##documentation strings
-${IN_PORT_doc} OF1.3: OFPP_IN_PORT = 0xfffffff8, /* Send the packet out the input port. This\nreserved port must be explicitly used\nin order to send back out of the input\nport. */\n
+${INPORT_doc} OF1.3: OFPP_INPORT = 0xfffffff8, /* Send the packet out the input port. This\nreserved port must be explicitly used\nin order to send back out of the input\nport. */\n
${TABLE_doc} OF1.3: OFPP_TABLE = 0xfffffff9, /* Submit the packet to the first flow table NB: This destination port can only be used in packet-out messages. */
${NORMAL_doc} OF1.3 OFPP_NORMAL = 0xfffffffa, /* Process with normal L2/L3 switching. */
${FLOOD_doc} OF1.3 OFPP_FLOOD = 0xfffffffb, /* All physical ports in VLAN, except input port and those blocked or link down. */
${ANY_doc} OF1.3 OFPP_ANY = 0xffffffff /* Wildcard port used only for flow mod (delete) and flow stats requests. Selects all flows regardless of output port (including flows with no output port). */
*** Test Cases *** output port tableID flowID verify OVS? OVS specific strings
-IN_PORT [Documentation] ${IN_PORT_doc}
- [Tags] in_port
- ${TEST_NAME} 22 161 no actions=${TEST_NAME}
+INPORT [Documentation] ${INPORT_doc}
+ [Tags] inport
+ ${TEST_NAME} 22 161 yes actions=IN_PORT
TABLE [Documentation] ${TABLE_doc}
[Tags] table
Create And Remove Flow
[Arguments] ${output_port} ${table_id} ${flow_id} ${verify_switch_flag} ${additional_ovs_flowelements}
Remove Default Flows ${node_id}
- Run Keyword If "${output_port}" == "IN_PORT" Pass Execution Skipping ${output_port} test and marking it passed
Run Keyword If "${output_port}" == "ANY" Pass Execution Skipping ${output_port} test and marking it passed
@{OVS_FLOWELEMENTS} Create List dl_dst=${eth_dst} table=${table_id} dl_src=${eth_src} nw_src=${ipv4_src} nw_dst=${ipv4_dst}
... ${additional_ovs_flowelements}
${ethernet_match_dict}= Create Dictionary type=${eth_type} destination=${eth_dst} source=${eth_src}
${ipv4_match_dict}= Create Dictionary source=${ipv4_src} destination=${ipv4_dst}
##flow is a python Object to build flow details, including the xml format to send to controller
- ${flow}= Create Flow
+ ${flow}= Create Inventory Flow
Set "${flow}" "table_id" With "${table_id}"
Set "${flow}" "id" With "${flow_id}"
Clear Flow Actions ${flow}