--- /dev/null
+"""
+Library for dynamic flow construction.
+Authors: james.luhrsen@hp.com
+Updated: 2014-08-29
+"""
+'''
+xmltodict and json libs not needed at this point, but may be useful in
+the future.
+'''
+##import xmltodict
+##import json
+import string
+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"?>' + \
+ '<flow xmlns="urn:opendaylight:flow:inventory">' + \
+ '<instructions></instructions>' + \
+ '<match></match>' + \
+ '</flow>'
+
+class Flow:
+ '''
+ Flow class for creating and interacting with OpenFlow flows
+ '''
+
+ strict = "false"
+ instruction_xmls = ""
+ match_xmls = ""
+ cookie = 0
+ cookie_mask = 0
+ table_id = 0
+ id = 1
+ hard_timeout = 60
+ idle_timeout = 30
+ flow_name = "No Name"
+ priority = 0
+ barrier = "false"
+
+ xml = xml_skeleton
+
+ json = ""
+
+ def set_field(self, field, value):
+ '''
+ allows for generically setting any attribute in this
+ class based on the 'field' passed in. In the future,
+ adding a new attribute only requires that single line
+ addition. no need for additional setter.
+ '''
+ setattr(self, field, value)
+
+def Make_Flow_Object():
+ '''
+ Robot Keyword to create and return an instance of the Flow
+ class.
+ '''
+ flow = Flow()
+ return flow
+
+def Set_Flow_Field(flow, field, value):
+ '''
+ Robot Keyword to allow the modification (setting) of the
+ flow object attributes
+ '''
+ flow.set_field(field,value)
+ return flow
+
+
+#def Convert_Flow_XML_To_Json(flow):
+# '''
+# There may be a need in the future to use json to push
+# flows, as opposed to xml format that is prevalent in
+# test code at this point. This function will give a
+# conversion, but unsure if it's proper. Also, unsure
+# if the xmltodict library is viable in the CSIT environment
+# '''
+# flowXmlDict = xmltodict.parse(flow.xml)
+# flow.json = json.dumps(flowXmlDict)
+# return flow
--- /dev/null
+*** Settings ***
+Documentation Keywords used to create/modify flow objects. The object is defined in the
+... corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
+... cookie and barrier fields, string formatted xml that can be used to push to
+... controller)
+Library ./FlowLib.py
+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}}"
+ [Return] ${flow}
+
+Set "${flow}" "${property}" With "${property_val}"
+ [Documentation] Embedded variables to make higher level keywords more readable.
+ ... There are some cases where the python attribute uses an underscore,
+ ... but a hyphen needs to be used. This seems inconsistent, and may need
+ ... to be looked at from the openflow plugin perspective.
+ ...
+ ... At this point, this library will remove the element ${property} from the
+ ... xml representation of the flow and reset with the given value. \ It's not
+ ... possible, yet, to have multiple elements with the same name. \ That will
+ ... likely be needed in the future.
+ ${property} Run Keyword If "table_id" != "${property}" and "cookie_mask" != "${property}" Replace String ${property} _ -
+ ... ELSE Set Variable ${property}
+ Remove Flow XML Element ${flow} ${property}
+ Add Flow XML Element ${flow} ${property} ${property_val}
+ Set Flow Field ${flow} ${property} ${property_val}
+ [Return] ${flow}
+
+Set Flow Action
+ [Arguments] ${flow} ${instruction_order} ${action_order} ${action} ${action_val}=${EMPTY}
+ [Documentation] Will remove the instruction element first, then add the proper xml structure
+ ... to implement the action as given in the arguments
+ ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
+ Remove Flow XML Element ${flow} instruction
+ Add Flow XML Element ${flow} instruction ${EMPTY} instructions
+ Add Flow XML Element ${flow} order ${instruction_order} instructions/instruction
+ Add Flow XML Element ${flow} apply-actions ${EMPTY} instructions/instruction
+ Add Flow XML Element ${flow} action ${EMPTY} instructions/instruction/apply-actions
+ Add Flow XML Element ${flow} order ${action_order} instructions/instruction/apply-actions/action
+ Add Flow XML Element ${flow} ${action} ${action_val} instructions/instruction/apply-actions/action
+ [Return] ${flow}
+
+Set Flow Ethernet Match
+ [Arguments] ${flow} ${match_value_dict}
+ [Documentation] Specific keyword for adding an ethernet match rules where the elements are given
+ ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
+ ... existing ethernet-match elements from the flow before adding
+ Clear Flow Matches ${flow} match/ethernet-match
+ Add Flow XML Element ${flow} ethernet-match ${EMPTY} match
+ ${type}= Get From Dictionary ${match_value_dict} type
+ Add Flow XML Element ${flow} ethernet-type ${EMPTY} match/ethernet-match
+ Add Flow XML Element ${flow} type ${type} match/ethernet-match/ethernet-type
+ ${src}= Get From Dictionary ${match_value_dict} source
+ Add Flow XML Element ${flow} ethernet-source ${EMPTY} match/ethernet-match
+ Add Flow XML Element ${flow} address ${src} match/ethernet-match/ethernet-source
+ ${dst}= Get From Dictionary ${match_value_dict} destination
+ Add Flow XML Element ${flow} ethernet-destination ${EMPTY} match/ethernet-match
+ Add Flow XML Element ${flow} address ${dst} match/ethernet-match/ethernet-destination
+ [Return] ${flow}
+
+Set Flow IPv4 Match
+ [Arguments] ${flow} ${match_value_dict}
+ [Documentation] Specific keyword for adding an ipv4 match rules where the elements are given
+ ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
+ ... existing ipv4 match elements from the flow before adding
+ Clear Flow Matches ${flow} match/ipv4-source
+ Clear Flow Matches ${flow} match/ipv4-destination
+ ${src}= Get From Dictionary ${match_value_dict} source
+ Add Flow XML Element ${flow} ipv4-source ${src} match
+ ${dst}= Get From Dictionary ${match_value_dict} destination
+ Add Flow XML Element ${flow} ipv4-destination ${dst} match
+ [Return] ${flow}
+
+Clear Flow Actions
+ [Arguments] ${flow}
+ [Documentation] Will clean out any existing flow actions in the given ${flow} object
+ Remove Flow XML Element ${flow} instructions/instruction
+ [Return] ${flow}
+
+Clear Flow Matches
+ [Arguments] ${flow} ${match_element}
+ [Documentation] Will clean out any existing flow matches in the given ${flow} object
+ Remove Flow XML Element ${flow} match/${match_element}
+ [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
+ ... the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
+ ... passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
+ ... are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
+ ... you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
+ ... location in the parameter list
+ ${flow_xml}= Parse XML ${flow.xml}
+ Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
+ ${xml_string}= Element To String ${flow_xml}
+ Set Flow Field ${flow} xml ${xml_string}
+ [Return] ${flow}
+
+Remove Flow XML Element
+ [Arguments] ${flow} ${element_xpath}
+ [Documentation] Removes the element at the given ${element_xpath} within the given ${flow}
+ ... object. The ${flow} object's xml representation will be updated to reflect this removal.
+ ${flow_xml}= Parse XML ${flow.xml}
+ Run Keyword And Ignore Error Remove Elements ${flow_xml} xpath=${element_xpath}
+ ${xml_string}= Element To String ${flow_xml}
+ Set Flow Field ${flow} xml ${xml_string}
+ [Return] ${flow}
Library OperatingSystem
Library String
Library XML
+Resource ../../../libraries/FlowLib.txt
Library ../../../libraries/RequestsLibrary.py
Library ../../../libraries/Common.py
Variables ../../../variables/Variables.py
${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
+${eth_src} 00:00:00:01:23:ae
+${eth_dst} ff:ff:ff:ff:ff:ff
-*** Test Cases *** ODL flow action action XML tableID flowID verify OVS? OVS specific string?
-Set_IP_TTL set-nw-ttl-action <nw-ttl>1</nw-ttl> 2 101 no set_ttl
+*** Test Cases *** ODL flow action action key action value tableID flowID verify OVS? OVS specific string?
+Set_IP_TTL [Documentation] OF1.3: \ OFPAT_SET_NW_TTL = 23, /* IP TTL. */\n(currently not supported on OVS)\n
+ [Tags] ttl set
+ set-nw-ttl-action nw-ttl 1 2 101 no set_ttl
-Dec_TTL dec-nw-ttl none 3 305 yes dec_ttl
+Dec_TTL [Documentation] OF1.3: \ OFPAT_DEC_NW_TTL = 24, /* Decrement IP TTL. */\n
+ [Tags] ttl dec
+ dec-nw-ttl none none 3 305 yes dec_ttl
-Copy_TTL_In copy-ttl-in none 9 202 no copy_ttl_in
+Copy_TTL_In [Documentation] OFPAT_COPY_TTL_IN = 12, /* Copy TTL "inwards" -- from outermost to\nnext-to-outermost */\n(currently NOT supported in OVS)\n
+ [Tags] ttl copyin
+ copy-ttl-in none none 9 202 no copy_ttl_in
-Copy_TTL_Out copy-ttl-out none 8 909 no copy_ttl_out
+Copy_TTL_Out [Documentation] OFPAT_COPY_TTL_OUT = 11, /* Copy TTL "outwards" -- from next-to-outermost\nto outermost */\n(currently NOT suported in OVS)
+ [Tags] ttl copyout
+ copy-ttl-out none none 8 909 no copy_ttl_out
-Set_MPLS_TTL set-mpls-ttl-action <mpls-ttl>1</mpls-ttl> 4 505 yes set_mpls_ttl
+Set_MPLS_TTL [Documentation] OFPAT_SET_MPLS_TTL = 15, /* MPLS TTL */
+ [Tags] ttl setmpls
+ set-mpls-ttl-action mpls-ttl 1 4 505 yes set_mpls_ttl
-Dec_MPLS_TTL dec-mpls-ttl none 2 1001 yes dec_mpls_ttl
+Dec_MPLS_TTL [Documentation] OFPAT_DEC_MPLS_TTL = 16, /* Decrement MPLS TTL */
+ [Tags] ttl decmpls
+ dec-mpls-ttl none none 2 1001 yes dec_mpls_ttl
*** Keywords ***
Create And Remove Flow
- [Arguments] ${flow_action} ${action_xml} ${table_id} ${flow_id} ${verify_switch_flag} ${additional_ovs_flowelements}
- ${flow_body}= OperatingSystem.Get File ${GENERIC_ACTION_FLOW_FILE}
- ${flow_body}= Replace String ${flow_body} FLOW_ACTION ${flow_action}
- ${flow_body}= Replace String ${flow_body} FLOW_ID ${flow_id}
- ${flow_body}= Replace String ${flow_body} TABLE_ID ${table_id}
- Log ${flow_body}
- ${flow_root}= Parse XML ${flow_body}
- Run Keyword If "set" in "${flow_action}" Add Element ${flow_root} ${action_xml} xpath=instructions/instruction/apply-actions/action/${flow_action}
- ${nw_src}= Get Element ${flow_root} match/ipv4-source
- ${nw_dst}= Get Element ${flow_root} match/ipv4-destination
- ${eth_src}= Get Element ${flow_root} match/ethernet-match/ethernet-source/address
- ${eth_dst}= Get Element ${flow_root} match/ethernet-match/ethernet-destination/address
- @{OVS_FLOWELEMENTS} Create List dl_dst=${eth_dst.text} table=${table_id} dl_src=${eth_src.text} nw_src=${nw_src.text} nw_dst=${nw_dst.text}
+ [Arguments] ${flow_action} ${action_key} ${action_value} ${table_id} ${flow_id} ${verify_switch_flag}
... ${additional_ovs_flowelements}
- ${flow_data}= Element To String ${flow_root}
- Log ${flow_data}
- Add Flow To Controller And Verify ${flow_data} ${table_id} ${flow_id}
+ @{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}
+ ##The dictionaries here will be used to populate the match and action elements of the flow mod
+ ${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
+ Set "${flow}" "table_id" With "${table_id}"
+ Set "${flow}" "id" With "${flow_id}"
+ Clear Flow Actions ${flow}
+ Set Flow Action ${flow} 0 0 ${flow_action}
+ Set Flow Ethernet Match ${flow} ${ethernet_match_dict}
+ Set Flow IPv4 Match ${flow} ${ipv4_match_dict}
+ ##If the ${flow_action} contains the string "set" we need to include a deeper action detail (e.g. set-ttl needs a element to indicate the value to set it to)
+ Run Keyword If "set" in "${flow_action}" Add Flow XML Element ${flow} ${action_key} ${action_value} instructions/instruction/apply-actions/action/${flow_action}
+ Log Flow XML is ${flow.xml}
+ Add Flow To Controller And Verify ${flow.xml} ${flow.table_id} ${flow.id}
Run Keyword If "${verify_switch_flag}" == "yes" Verify Flow On Switch ${OVS_FLOWELEMENTS}
- Remove Flow From Controller And Verify ${flow_body} ${table_id} ${flow_id}
+ Remove Flow From Controller And Verify ${flow.xml} ${flow.table_id} ${flow.id}
Run Keyword If "${verify_switch_flag}" == "yes" Verify Flow Does Not Exist On Switch ${OVS_FLOWELEMENTS}
Add Flow To Controller And Verify