[[PageOutline]] This page describes how to write [http://www.protogeni.net/trac/protogeni/wiki/RSpecSchema2 GENI compliant] Openflow rspecs. These new rspecs are supported by FOAM, the new Openflow AM. This page also provides instructions and how to convert Expedient rspecs to the new form of rspecs. = Openflow Slivers = In an Openflow Aggregate, an experimenter can control how the packets are forwarded within the network, using a custom controller running in an external compute resource. In the general case an Openflow Aggregate consists of Openflow-enabled devices(e.g. switches) which forward packets based on instructions received by the controllers. The traffic of an Openflow network can be sliced, using matching rules on the traversing packets. A set of rules that describes part of the passing traffic is called a ''flowspace''. A flowspace can be defined based on the datapath ids (aka dpids) and ports that the packets are going through, and/or based on their headers. Datapath is a virtual network device that is controlled using the Openflow protocol and can forward packets. So for example a switch running an Openflow compatible firmware might be a datapath. More details about how Openflow works and about which fields of the packet headers can be used in flowspaces can be found in the [http://www.openflow.org/documents/openflow-spec-v1.0.0.pdf Openflow Spec 1.0.0] and in the [http://www.openflow.org/ Openflow website]. For example a sliver on an Openflow network might request for : ''"All packets coming in port 5 on datapath 15, and have a source IP address in subnet 10.10.10.0/24."''' = FOAM rspecs = An Openflow rspec is describing the flowspace for an experiment and thus it has ways of describing datapaths, ports and rules to filter packets based on packet headers. FOAM, that is an Openflow Aggregate Manager, is using GENI compliant rspecs, with an Openflow extention(v2). You can find an example rspec [https://openflow.stanford.edu/display/FOAM/rspec here]. Here a list of supported tag is provided. The shorthand notations used in the description is: || ![1]|| An element is mandatory and it can only appear once || || [?] || An element is optional, but it can appear at most once || || [*] || An element is optional but it can appear multiple times in the rspec || || [+] || An element is mandatory , but it can appear multiple times in the rspec || === === ![1] This element contains all the information about the requested sliver. ''Attributes'':: * '''description''' : [?] a short description of your experiment * '''ref''' : [?] A URL pointing to a page describing your project * '''email''' : [?] user's email address that is used by FOAM to send notifications about the sliver. ''Children tags'':: * [+] * [+] * [+] '' Parent tags'':: === === [+] This element provides information about the controller for the sliver. It is MANDATORY to have one and only one primary controller. ''Attributes'':: * '''url''' : ![1] the information about where your openflow controller is running in the form of tcp::. Examples : tcp:10.0.0.1:6633 , tcp:myctrl.example.net:6637 * '''type''' : ![1] this defines what type of controller this is. There can be only three types of controllers: * '''primary''' : this is the controller that handles the network traffic and makes decisions about how packets should be forwarded. [MANDATORY to have one and only one primary controller]. * '''monitor''' : a monitor controller can not make decisions about how packets are forwarded, but it has the capability of creating and sending packets in the network, e.g. LLDP packets for performing topology discovery. [An rspec can have more than one monitor controllers] * backup : a backup controller is used if the primary controller goes down, multiple backup controllers can be defined and they are used in the order they appear in the request rspec. Right now defining backup monitors will have no effect. [An rspec can have more than one backup controllers] ''Children tags'':: None '' Parent tags'':: === === [+] This tag is used to group multiple datapath resources together, so they can be used as a bundle in defining matches. So if this sliver is interested in packets that go through some ports on datapaths A, B and C then the group should contain three elements on for each of A, B and C. ''Attributes'':: * '''name''' : ![1] this is the name of the group. ''Children tags'':: [*], a group element with no children implies ALL datapaths. '' Parent tags'':: === === [*] This tag provides information about a single datapath resource. ''Attributes'':: * component_id : ![1] the urn of the component, the best way to get this is from the advertisement rspec * component_manager_id : ![1] is urn of the Openflow Aggregate Manager that manages this resource as listed in the advertisement rspec '' Children tags'':: [*], a datapath element with no children implies ALL ports '' Parent tags'':: , === === [*] This provides information about a port on a datapath. ''Attributes'':: * num : ![1] the number of the port, the best way to get this is from the advertisement rspec * name : [?] the name of the port as defined in the advertisement rspec '' Children tags'':: None '' Parent tags'':: === === [+] This is the tag for describing requested matches. Conceptually this tag has two parts, one for describing the datapaths in which we would like to control the forwarding of packets and another part that defines filters on which packets to control. The first part is mandatory and uses the and tags. The second part is optional and uses the tag. If no filters are defined, ALL packets in the specified datapaths are requested. ''Attributes'':: None '' Children tags'':: [AT LEAST ONE OF THE or MUST BE PRESENT] * [*] * [*] * [?] '' Parent tags'':: === === [*] This tag specifies which group of datapaths should be used for this match. ''Attributes'':: * '''name''' : ![1] the name of the group as it is defined in the corresponding tag, if the group has not been defined the rspec will be rejected. '' Children tags'':: None '' Parent tags'':: === === [?] This tag describes the packet filters for defining this match. ''Attributes'':: None '' Children tags'':: [AT LEAST ONE OF THOSE SHOULD BE PRESENT] * [*] * [*] * [*] * [*] * [*] * [*] * [*] * [*] * [*] '' Parent tags'':: === Filter elements === In order to filter the traffic that will be delegated to this sliver packets can be filtered based on the following packet header fields. Each field corresponds to an element. In all of them you can specify a list of values by using a comma separated list (e.g. a,b,c) , or if ranges are supported to use the dash (e.g a-c), or a mixture of the two (e.g. a-c, f-j). Each element can appear multiple times within a packet element. If an element appears more than once, then the union of all the requested values is requested. All of the match elements have the same structure so we will describe it here : ''Attributes'':: * '''value''' : ![1] A list or a range of values, the value format id different for each element '' Children tags'':: None '' Parent tags'':: ==== ==== [*] Matches on the source ethernet address of the packet. Format xx:xx:xx:xx:xx:xx, does NOT support ranges. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*] Matches on the destination ethernet address of the packet. Format xx:xx:xx:xx:xx:xx, does NOT support ranges. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*] Matches on the ethernet type of the packet. Format is numbers, does NOT support ranges. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*] Matches on the vlan id of the packet. Format is numbers, supports ranges. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*]Matches on the IP source address of the packet. IP addresses or subnets in CIDR format (e.g. 10.43.123.0/24), does not support ranges. If this is used then should be matching IP (0x0806) and/or ARP (0x806) packets. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*]Matches on the IP destination address of the packet. IP addresses or subnets in CIDR format (e.g. 10.43.123.0/24), does NOT support ranges. If this is used then should be matching IP (0x0800) and/or ARP (0x806) packets. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*]Matches on the IP protocol. Protocol numbers (e.g. 17 for UDP), supports ranges. If this is used then should be matching IP (0x0800) and/or ARP (0x806) packets. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here] ==== ==== [*]Matches on the source port of TCP or UDP headers. Format is numbers, supports ranges. If this is used then should be matching TCP (6) and/or UDP (17) packets.For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here.] ==== ==== [*]Matches on the destination port of TCP or UDP headers. Format is numbers, supports ranges. If this is used then should be matching TCP (6) and/or UDP (17) packets. For details on the structure look [wiki:HowTo/ConvertExpedientToFoamRspecs#Matchelements here.] = Writing FOAM request rspecs = The best way to understand and write FOAM rspecs is by looking at example rspecs. Keep in mind that the rspec is merely a structured representation of flowspaces that describe the traffic that an experiment wants to control. This [https://openflow.stanford.edu/display/FOAM/rspec example rspec], is a complete example. Here there is also a list of simpler example rspecs : * [attachment:of_one_match.rspec Rspec with only one match element] * [Rspec with multiple match elements] * [Rspec with two groups] In essence your rspec should: 1. start with the and the tags : {{{ #!xml }}} 2. Specify where your controller is running. E.g.: {{{ #!xml }}} 3. Organize the datapaths that are relevant to this sliver within groups. The best way to construct the elements is by copying them from the advertisement rspecs. E.g if [attachment:ad-sample.rspec this] is the advertisement rspec, and you want : * ports 7 and 20 of datapath with dpid 06:a4:00:12:e2:b8:a5:d0 * ports 50 and 71 of datapath with dpid 06:af:00:24:a8:c4:b9:00 Then you can construct a group that looks like : {{{ #!xml }}} 4. Specify your flowspace. E.g. if you want for the above group to get all traffic that is sourced or destined to the IP subnet 10.1.1.0/24 and uses tcp port 80, then you will need two tags, one to match the packets that are sourced from that subnet and one to match the packets that are destined to that subnet. Keep in mind that your flowspace is the union of the traffic that is described by each {{{ #!xml }}} Done! The complete rspec looks like : {{{ #!xml }}} = FOAM and Expedient rspecs = Although the FOAM and the Expedient