Module API and Detailed Documentation¶
Multicast Group Management¶
pox.openflow.igmp_manager¶
A POX module implementation providing IGMP v3 Multicast Router functionality.
This module does not support any command line arguments. All IGMP parameters are set to RFC recommended defaults (see RFC 3376).
Depends on openflow.discovery, misc.groupflow_event_tracer (optional)
Created on July 16, 2013
Author: Alexander Craig - alexcraig1@gmail.com
- class pox.openflow.igmp_manager.IGMPManager¶
Class which stores global IGMP settings, and manages a map of IGMPv3Router objects to implement IGMP support for OpenFlow switches.
- add_igmp_router(router_dpid, connection)¶
Registers a new router for management by the IGMP module.
- decrement_all_timers()¶
Decrements the source and group timers for all group_records in the network, and transitions any state as necessary.
As long as this is always called from a recoco Timer, mutual exclusion should not be an issue.
- drop_packet(packet_in_event)¶
Drops the packet represented by the PacketInEvent without any flow table modification.
- encapsulate_igmp_packet(igmp_pkt)¶
Encapsulates the provided IGMP packet into IP and Ethernet packets, and returns the encapsulating ethernet packet
- launch_igmp_general_query()¶
Generates an IGMP general query, broadcasts it from all ports on all routers.
- send_igmp_query_to_all_networks(igmp_pkt)¶
Encapsulates the provided IGMP packet into IP and Ethernet packets, and sends the packet to all attached network on all routers.
- class pox.openflow.igmp_manager.IGMPv3Router(manager)¶
Class representing an IGMP v3 router, with IGMP functionality implemented through OpenFlow interaction.
- create_group_record(event, igmp_group_record, group_timer)¶
Creates a group record from the specific PacketIn event and associated igmp_group_record read from the packet.
If the record did not already exist it is initialized with the provided group timer. If it did exist, the existing record IS NOT modified.
- process_current_state_record(event, igmp_group_record)¶
Processes current state IGMP membership reports according to the following table (See RFC 3376):
Router State Report Rec’d New Router State Actions INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI INCLUDE (A) IS_EX (B) EXCLUDE (A*B,B-A) (B-A)=0, Delete (A-B), Group Timer=GMI EXCLUDE (X,Y) IS_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI, Delete (X-A), Delete (Y-A), Group Timer=GMI Note: When the group is in INCLUDE mode, the set of addresses is stored in the same list as the X set when in EXCLUDE mode
- process_igmp_event(event, igmp_trace_event=None)¶
Processes any IGMP event received by the router.
- process_state_change_record(event, igmp_group_record)¶
Processes state change IGMP membership reports according to the following table (See RFC 3376):
Router State Report Rec’d New Router State Actions INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI INCLUDE (A) BLOCK (B) INCLUDE (A) Send Q(G,A*B) INCLUDE (A) TO_EX (B) EXCLUDE (A*B,B-A) (B-A)=0, Delete (A-B), Send Q(G,A*B), Group Timer=GMI INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI, Send Q(G,A-B) EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI EXCLUDE (X,Y) BLOCK (A) EXCLUDE(X+(A-Y),Y) (A-X-Y)=Group Timer, Send Q(G,A-Y) EXCLUDE (X,Y) TO_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=Group Timer, Delete (X-A), Delete (Y-A), Send Q(G,A-Y), Group Timer=GMI EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI, Send Q(G,X-A), Send Q(G) Note: When the group is in INCLUDE mode, the set of addresses is stored in the same list as the X set when in EXCLUDE mode
- remove_group_record(port, multicast_address)¶
Removes the group record identified by the provided port and multicast_address from the router’s set of records.
Does nothing if the record did not exist.
- send_group_and_source_specific_query(port, multicast_address, group_record, sources, retransmissions=-1)¶
Generates a group and source specific query, and sends a PacketOut message to deliver it to the specified port
- send_group_specific_query(port, multicast_address, group_record, retransmissions=-1)¶
Generates a group specific query, and sends a PacketOut message to deliver it to the specified port
- update_desired_reception_state(igmp_trace_event=None)¶
Updates the object’s cached map of desired reception state, and generates a MulticastGroupEvent if state changed.
- class pox.openflow.igmp_manager.MulticastGroupEvent(router_dpid, desired_reception, igmp_trace_event=None)¶
Event which represents the desired reception state for all interfaces/multicast groups on a single router.
This class contains the following public attributes:
- desired_reception - Records the desired reception state of the router with DPID router_dpid, and is formatted as a two dimensional map of lists:
desired_reception[multicast_address][port_index] = [list of desired source addresses]
An empty list in any map entry specifies that reception is desired from all available sources.
- class pox.openflow.igmp_manager.MulticastMembershipRecord(mcast_address, timer_value)¶
Class representing the group record state maintained by an IGMPv3 multicast router
Multicast routers implementing IGMPv3 keep state per group per attached network. This group state consists of a filter-mode, a list of sources, and various timers. For each attached network running IGMP, a multicast router records the desired reception state for that network. That state conceptually consists of a set of records of the form:
(multicast address, group timer, filter-mode, (source records))
Each source record is of the form:
(source address, source timer)
- get_curr_source_timer(ip_addr)¶
Returns the current source timer for the specified IP address, or 0 if the specified IP is not known by this group record.
- get_x_addr_set()¶
Returns the set of addresses in the X set of source records (see RFC 3376)
Note: When in INCLUDE mode, all sources are stored in the X set.
- get_y_addr_set()¶
Returns the set of addresses in the Y set of source records (see RFC 3376)
Note: When in INCLUDE mode, his set should always be empty.
- remove_source_record(ip_addr)¶
Removes the source record with the specified IP address from the group record
- class pox.openflow.igmp_manager.MulticastTopoEvent(event_type, link_changes, adjacency_map)¶
Event which signifies a change in topology that will be relevant to the multicast routing module.
This class contains the following public attributes:
- event_type: One of LINK_UP (0) or LINK_DOWN (1). Records which type of topology change triggered this event.
- link_changes: A list of tuples specifying which links changed state (type of state change determined by event_type). The tuples are formatted as (Egress Router DPID, Ingress Router DPID, Egress Router Port)
- adjacency_map: A map of all adjacencies between switches learned by the IGMP module, formatted as follows:
adjacency_map[egress_router_dpid][ingress_router_dpid] = egress_router_port
- pox.openflow.igmp_manager.int_to_filter_mode_str(filter_mode)¶
Converts an IGMP integer filter mode into the associated string constant.
Multicast Routing¶
pox.openflow.groupflow¶
A POX module implementation of multicast routing, supported by management of group state using the IGMP manager module.
Implementation adapted from NOX-Classic CastFlow implementation provided by caioviel. Multicast routing records are stored for each combination of multicast group and source address. For each of these records the GroupFlow module will calculate a shortest path tree using Dijkstra’s algorithm from the multicast source to all routers in the network (where each edge is weighted according to the number of hops from the multicast source). Branches of this tree which correspond to active multicast receivers are installed into the network through OpenFlow, and the spanning tree is only recalculated when the network topology changes. This should enable rapid changes of multicast group, as there is no need to completely recalculate the multicast tree when new receivers join a group.
The following command line arguments are supported:
- link_weight_type: Determines the method by which link weights are scaled with link utilization. Supported options are ‘linear’ (link weight scales as a linear function of utilization) or ‘exponential’ (link weight grows exponentially with increasing utilization). Default: linear
- static_link_weight: Determines the static weight which is applied to all links regardless of utilization. Default: 1
- util_link_weight: Determines the scaling factor by which utilization based link weight will be multiplied. Higher values cause the current traffic state to be more heavily weighted in routing (relative to the network topology). Note that setting this to 0 with either link weight type will produce shortest cost trees in terms of number of hops only. Default: 10
- flow_replacement_mode: Determines the manner in which replacement of existing flows is triggered. Supported options: ‘none’: Existing flows are never replaced. ‘periodic’: Existing flows are periodically replaced. ‘cong_threshold’: In this mode, flow replacement is triggered by the FlowTracker module reporting congestion on a link traversed by the flow. Upon receiving a LinkUtilizationEvent, the GroupFlow module will attempt to replace the largest flows traversing the link until the link is brought back under its congestion threshold. Default: ‘none’
- flow_replacement_interval: Determines the flow replacement interval in a mode specific fashion (always specified in seconds): ‘none’: Has no effect ‘periodic’: Sets the periodic interval at which flows are replaced. ‘cong_threshold’: Sets the minimum interval that must elapse after flow placement, before the flow can be replaced. Default: 10
Depends on openflow.igmp_manager, misc.groupflow_event_tracer (optional)
Created on July 16, 2013
Author: Alexander Craig - alexcraig1@gmail.com
- class pox.openflow.groupflow.GroupFlowManager(link_weight_type, static_link_weight, util_link_weight, flow_replacement_mode, flow_replacement_interval)¶
The GroupFlowManager implements multicast routing for OpenFlow networks.
- drop_packet(packet_in_event)¶
Drops the packet represented by the PacketInEvent without any flow table modification
Returns a new, unique cookie which should be assigned to a multicast_group / sender pair.
Using a unique cookie per multicast group / sender allows the FlowTracker module to accurately track bandwidth utilization on a per-flow basis.
- get_reception_state(mcast_group, src_ip)¶
Returns locations to which traffic must be routed for the specified multicast address and sender IP.
Returns a list of tuples of the form (router_dpid, output_port).
- parse_topology_graph(adjacency_map)¶
Parses an adjacency map into a node and edge graph (which is cached in self.topology_graph and self.node_set).
- class pox.openflow.groupflow.MulticastPath(src_ip, src_router_dpid, ingress_port, dst_mcast_address, groupflow_manager, groupflow_trace_event=None)¶
Manages multicast route calculation and installation for a single pair of multicast group and multicast sender.
- calc_path_tree_dijkstras(groupflow_trace_event=None)¶
Calculates a shortest path tree from the group sender to all network switches, and caches the resulting tree.
Note that this function does not install any flow modifications.
- install_openflow_rules(groupflow_trace_event=None)¶
Selects routes for active receivers from the cached shortest path tree, and installs/removes OpenFlow rules accordingly.
- remove_openflow_rules()¶
Removes all OpenFlow rules associated with this multicast group / sender pair.
This should be used when the group has no active receivers.
- update_flow_placement(groupflow_trace_event=None)¶
Replaces the existing flows by recalculating the cached shortest path tree, and installing new OpenFlow rules.
Link Utilization Estimation¶
pox.openflow.flow_tracker¶
A POX module which periodically queries the network to estimate link utilization.
Bandwidth usage is tracked on selected links in the network (using both FlowStats on the transmission side, and PortStats on the receive side). Number of flow table installations is tracked on all switches in the network.
The following command line arguments are supported:
- query_interval: The length of time (in seconds) which should elapse between consecutive flow/port stats queries to switches. Default: 2
- link_max_bw: The maximum bandwidth (in Mbps) of network links. Note that in the current implementation, all links must have uniform bandwidth. Default: 30
- link_cong_threshold: The utilization (in Mbps) above which a link should be considered as congested. Must be <= link_max_bw. Default: 28.5
- avg_smooth_factor: The alpha value to use for the bandwidth estimation exponential average. The bandwidth utilization at each monitoring interval i is specified by BW_est_i = (alpha * BW_val_(i)) + ((1 - alpha) * BW_est_(i-1)). Higher alpha values therefore result in an average that more heavily weights recent samples. Default: 0.7
- log_peak_usage: (True/False) If true, the peak and average utilization in the network are logged to debug.info at an interval of (query_interval / 1.5) seconds. Default: False.
Depends on openflow.discovery
Created on Oct 16, 2013
Author: Alexander Craig - alexcraig1@gmail.com
- class pox.openflow.flow_tracker.FlowTrackedSwitch(flow_tracker)¶
Class used to manage statistics querying and processing for a single OpenFlow switch.
The FlowTracker module implements bandwidth tracking by managing a map of these objects.
- ignore_connection()¶
Disconnects listener methods on statistics queries, and stops the periodic query timer.
- launch_stats_query()¶
Sends an OpenFlow FlowStatsRequest and PortStatsRequest to the switch associated with this object.
- listen_on_connection(connection)¶
Configures listener methods to handle query responses, and starts the periodic query timer.
- connection: Connection object for this switch (usually obtained from a ConnectionUp event)
- process_flow_stats(stats, reception_time)¶
Processes a FlowStats response to a FlowStatsRequest.
Flow stats are processed to determine bandwidth utilization from the transmission side of a link. This method can produce inaccurate measurements when using Mininet link emulation. In particular, the statistics returned by emulated switches will not properly detect dropped packets, and the byte counts returned in FlowStats responses will overestimate the actual bytes forwarded when the link becomes congested. FlowStats are recorded on a per-flow basis, allowing the module the percentage of link utilization contributed by each flow in the network. Flows are differentiated by their controller assigned flow cookie. Flows with no cookie default to a cookie value of 0, and the FlowTracker module will consider all flows without a cookie as a single flow with cookie value 0.
An exponential moving average is used to smooth bandwidth estimates, where the alpha of the exponential average is set by flow_tracker.avg_smooth_factor.
- process_port_stats(stats, reception_time)¶
Processes a PortStats response to a PortStatsRequest.
Port stats are processed to determine bandwidth utilization from the receiving side of a link. This method was chosen to overcome limitations in Mininet’s link emulation technique, which causes FlowStats to overestimate the utilization of a link when a link becomes congested. PortStats should always give an accurate count of the bytes received on a particular port even in congestion conditions, but the utilization cannot be determined on a per-flow basis using PortStats messages.
An exponential moving average is used to smooth bandwidth estimates, where the alpha of the exponential average is set by flow_tracker.avg_smooth_factor.
- set_tracked_ports(tracked_ports)¶
Sets the port numbers on which bandwidth utilization should be tracked for this switch.
- tracked_ports: List of integer port numbers on which utilization should be tracked for this switch
- class pox.openflow.flow_tracker.FlowTracker(query_interval, link_max_bw, link_cong_threshold, avg_smooth_factor, log_peak_usage)¶
Module which implements bandwidth utilization tracking by managing a map of FlowTrackedSwitches.
- get_flow_utilization_normalized(switch_dpid, output_port, flow_cookie)¶
Returns the percentage of link utilization on a particular link contributed by a particular flow (as a normalized value between 0 and 1).
- switch_dpid: The dataplane identifier of the switch on the transmitting side of the link
- output_port: The output port on switch with dpid switch_dpid corresponding to the link
- flow_cookie: The flow cookie assigned to the link of interest
- get_link_utilization_mbps(switch_dpid, output_port)¶
Returns the current estimated utilization (in Mbps) on the specified switch and output port.
If a utilization is available based on port stats from the receive side of the specified link, this value will be returned (as port stats are more reliable in Mininet than flow stats). If port stats are not available (which would occur when the opposite side of the link is not being tracked) then a utilization estimate derived from flow stats will be returned.
- get_link_utilization_normalized(switch_dpid, output_port)¶
Returns the current estimated utilization (as a normalized value between 0 and 1) on a particular link.
- switch_dpid: The dataplane identifier of the switch on the transmitting side of the link
- output_port: The output port on switch with dpid switch_dpid corresponding to the link
Note: Current implementation assumes all links have equal maximum bandwidth which is defined by self.link_max_bw
- output_peak_usage()¶
Outputs the current peak utilization and average link utilization to log.info
- termination_handler(signal, frame)¶
Method to cleanly terminate the module (i.e. close the log file) when a SIGINT signal is received.
This function is typically called by the BenchmarkTerminator module.
- class pox.openflow.flow_tracker.LinkUtilizationEvent(router_dpid, output_port, cong_threshold, link_utilization, stats_type, flow_map)¶
Event which reports link status in the event of link congestion, or under under other conditions (TBD).
This class contains the following public attributes:
- router_dpid: The egress router of the link on which status is being reported
- output_port: The output port of the link on which status is being reported
- cong_threshold: The flow tracker’s congestion threshold (in Mbps)
- link_utilization: The utilization (in Mbps) of the link, as determined from PortStats on the ingress router. If port stats are not available on the ingress router, the utilization as determined from the egress router ports stats will be included instead.
- stats_type: One of FLOW_STATS (0) or PORT_STATS (1). Records which type of stats reception triggered this event.
- flow_map: A map of normalized bandwidth utilizations keyed by flow_cookie. This should be used to determine which flows should be replaced.
flow_map[flow_cookie] = normalized bandwidth of flow with flow cookie flow_cookie
Benchmarking and Event Tracing¶
pox.misc.groupflow_event_tracer¶
This module allows event traces to be produced by the IGMP Manager and Groupflow modules, with the goal of tracing various event processing times for benchmarking and evaluation purposes.
This module does not support any command line arguments.
Created on Oct 28th, 2013
Author: Alexander Craig - alexcraig1@gmail.com
- class pox.misc.groupflow_event_tracer.GroupFlowEventTracer¶
The GroupFlowEventTracer is responsible for managing currently active IGMPTraceEvents and GroupFlowTraceEvents
- archive_trace_event(trace_event)¶
Archives the specified event by serializing it to the log file, and removes the event from the module’s memory.
- init_groupflow_event_trace(igmp_trace_event=None)¶
Returns a new GroupFlowTraceEvent with a unique event_id.
- init_igmp_event_trace(router_dpid)¶
Returns a new IGMPTraceEvent with a unique event_id.
- termination_handler(signal, frame)¶
Method to cleanly terminate the module when a SIGINT signal is received.
All currently active trace events will be discarded, and the log file will be closed. This function is typically called by the BenchmarkTerminator module.
- class pox.misc.groupflow_event_tracer.GroupFlowTraceEvent(event_id, igmp_trace_event=None)¶
Trace event which records processing times associated with a routing event performed by the GroupFlow module.
The following data is recorded:
- igmp_trace_event: The IGMPTraceEvent associated with the IGMP packet which triggered this routing event. Note that not all routing events are triggered by IGMP events, and this value will be set to None in cases where there is no associated IGMP event. An example of this is when routing is triggered by a new multicast sender being detected.
- tree_calc_start_time: Time at which tree calculation was started for this routing event.
- tree_calc_end_time: Time at which tree calculation was completed for this routing event.
- route_processing_start_time: Time at which route processing was started for this routing event. Route processing is defined as the operation of selecting branches from the cached route tree to install for this particular routing event.
- route_processing_end_time: Time at which route processing was completed for this routing event.
- flow_installation_start_time: Time at which OpenFlow rule installation was started for this routing event.
- flow_installation_end_time: Time at which OpenFlow rule installation was completed for this routing event.
- multicast_group: Multicast group address which this routing event is associated with.
- src_ip: Multicast sender IP address which this routing event is associated with.
Note: Due to the tree caching behaviour of the GroupFlow module, not all routing events will require a full tree calculation, and in these cases tree_calc_start_time and tree_calc_end_time will be set to None
- get_flow_installation_time()¶
Returns the length of time (in seconds) associated with OpenFlow rule installation for this routing event.
Returns None if the associated times have not been recorded.
- get_log_str()¶
Returns a plain-text representation of the event that will be used when the event is serialized to a log file.
- get_route_processing_time()¶
Returns the length of time (in seconds) associated with route selection for this routing event.
Returns None if the associated times have not been recorded.
- get_tree_calc_time()¶
Returns the length of time (in seconds) associated with tree calculation for this routing event.
Returns None if no tree calculation was required for this routing event (often the case when the tree is already cached), or if the associated times have not been recorded.
- set_flow_installation_end_time()¶
Records the current time as the time at which OpenFlow rule installation was completed.
- set_flow_installation_start_time()¶
Records the current time as the time at which OpenFlow rule installation was initiated.
- set_route_processing_end_time()¶
Records the current time as the time at which route selection was completed.
- set_route_processing_start_time(multicast_group, src_ip)¶
Records the current time as the time at which route selection was initiated.
- set_tree_calc_end_time()¶
Records the current time as the time at which tree calculation was completed.
- set_tree_calc_start_time(multicast_group, src_ip)¶
Records the current time as the time at which tree calculation was initiated.
- class pox.misc.groupflow_event_tracer.IGMPTraceEvent(event_id, router_dpid)¶
Trace event which records processing times associated with a single IGMP packet.
The following data is recorded:
- router_dpid: Data plane identifier of the router which received the packet
- igmp_msg_type: The type of IGMP message processed (see constants defined in pox.lib.packet.igmpv3)
- igmp_group_records: A list of tuples specifying the group records contained in the IGMP packet. Tuples are of the form (group_record_type, multicast_address). Valid group records types are defined in pox.lib.packet.igmpv3.
- num_igmp_group_records: Number of group records contained in the IGMP packet
- igmp_processing_start_time: Time at which the packet was identified as an IGMP packet
- igmp_prcessing_end_time: Time at which all IGMP processing associated with the IGMP packet was completed
- get_igmp_processing_time()¶
Returns the length of time (in seconds) associated with IGMP processing for this event.
Returns None if no end time has been set for the event.
- get_log_str()¶
Returns a plain-text representation of the event that will be used when the event is serialized to a log file.
Note that the current implementation does not serialize complete IGMP group records.
- set_igmp_end_time()¶
Records the current time as the time at which IGMP processing associated with this event was completed.
- set_igmp_start_time(igmp_packet_in_event)¶
Processes a PacketIn event containing an IGMP packet, and sets associated data fields in the trace event.
Fields which are populated by this method: * igmp_msg_type, igmp_group_records, num_igmp_group_records, igmp_processing_start_time
For best benchmarking accuracy, this method should be called as soon as the PacketIn is determined to contain an IGMP packet
- class pox.misc.groupflow_event_tracer.TraceEvent(event_id=0)¶
Superclass for trace events. Stores only the event ID and time of the event’s creation.
Subclassed by IGMPTraceEvent and GroupFlowTraceEvent.
- get_curr_time()¶
Returns the current time, using the method selected by the TIMING_MODE constant.
This method is used to record time values in all subclasses of this class. Valid values for TIMING_MODE are USE_TIME_TIME (which uses time.time() to get the current time) and USE_TIME_CLOCK (which uses time.clock() to get the current time)
pox.misc.benchmark_terminator¶
The purpose of this module is to capture a SIGINT signal, and cleanly terminate the benchmarking functionality of the FlowTracker and GroupFlowEventTracer modules, before rethrowing the signal so that POX can catch it and terminate entirely.
This module does not support any command line arguments.
Depends on misc.groupflow_event_tracer, openflow.flow_tracker
Created on Nov 4, 2013
Author: Alexander Craig - alexcraig1@gmail.com