Sample Application: The Learning Switch Functionality
- Create a HashMap called mac_to_port
- On packet_in, parse packet to get source and destination MAC addresses
- Store in a hashmap mapping between src_mac and in_port
- Lookup dst_mac in mac_to_port map to find next hop
- If next hop is found, create flow_mod and send
- Else, flood like hub.
Processing a Packet: System View
The application's workflow when processing a packet is shown in the following figure.
Steps 1-3 in the figure show pkt_in processing. Steps 4-7 show pkt_out processing (flooding if not match is found). finally, Steps 8-12 show flow programming to the switch.
The sequence details are as follows:
- A packet_in is sent from the switch to controller
- The OpenFlow java library parses the packet and translates it into an MD-SAL format governed by the OpenFlow protocol model; the OpenFlow 1.0/1.3 Plugin creates an MD-SAL Notification and publishes it into the MD-SAL.
- MD-SAL routes the notification to all registered consumers, in this case the Learning Switch application
- If the Learning Switch application does not yet have the mapping between the mac address and the port, it floods the packet. Flooding is done as pkt_out to the switch. The application issues an MD-SAL RPC (with input parameter that constitutes the pkt_out PDU payload).
- MD-SAL routes the RPC to the OpenFlow 1.0/1.3 Plugin
- The OpenFlow 1.0/1.3 Plugin processes the packet, which is eventually translated into an OpenFlow pkt_out PDU in the OpenFlow Java library.
- The OpenFlow pkt_out PDU is sent to the switch.
- When the application wants to program a flow, it creates a new flow in the MD-SAL Database. A new flow is created in the appropriate table (Table 0) , which is in the appropriate flow-capable node (i.e switch, openflow:1 in the example), which is in the config space of the MD-SAL inventory database. The inventory database is a subtree (namespace) of the MD-SAL database.
- MD-SAL generates a change notification, which is received by the Forwarding Rules Manager (FRM). The FRM listens on flow updates - i.e. it registered for MD-SAL change notifications on the config name space subtree that corresponds to flows.
- The FRM programs the flow. It issues an MD-SAL RPC flow programming operation.
- MD-SAL routes the RPC to the OpenFlow 1.0/1.3 Plugin
- The OpenFlow 1.0/1.3 Plugin processes the packet, which is eventually translated into an OpenFlow FlowMod PDU in the OpenFlow Java library.
- The OpenFlow FlowMod PDU is sent to the switch.
Building the Application
- Prerequisites:
- Java 7, Maven 3.0.5 or later, Linux or Mac
- Download the application code from ODL OpenFlow Plugin repo:
> git clone https://git.opendaylight.org/gerrit/p/openflowplugin.git
- Build the application:
> cd openflowplugin/samples/learning-switch/ > mvn clean install
- The build creates the ‘learning-switch-0.0.3-SNAPSHOT.jar’ bundle in ‘openflowplugin/samples/learning-switch/target’
Analyzing the Code in Eclipse:
Prerequisites: Install maven plugin for Eclipse
Setting up the Environment
- Prerequisites:
- Java 7, Linux or Mac
- Mininet 2.1 with OpenFlow 1.3
- OpenDaylight Base Edition
- Unzip the downloaded controller package
- Delete the ‘Simple Forwarding Application’ bundle from the distribution:
> rm opendaylight/plugins/org.opendaylight.controller.samples.simpleforwarding-0.4.1.jar
- Upload the created bundle: put the ‘learning-switch-0.0.3-SNAPSHOT.jar’ bundle into the ‘opendaylight/plugins’ folder
- Update logger configuration:
- Optionally, add the following line to the 'configuration/logback.xml' file:
<logger name="org.opendaylight.openflowplugin.learningswitch" level="TRACE"/>
Update on dependencies
As the released version is getting outdated, it is preferable to use the latest version
SNAPSHOTs (grab latest SNAPSHOT).
Starting up the Environment
- Run the controller:
> ./run.sh -of13
- Check that the application bundle is active. On the controller console, type:
osgi > lb learn
- You should see something like:
START LEVEL 6 ID|State |Level|Name 103|Active | 4|learning-switch (0.0.3.SNAPSHOT) osgi>
- Optionally, check that the controller is listening on Ports 6633 and 6653.
- On a Linux console, type:
> netstat -lnp | grep 'java’
- On a Mac OSX console, type:
> lsof -i | grep LISTEN |grep java
- Start Mininet:
> sudo mn --topo single,10 --controller 'remote,ip=<controller-ip-address>,port=6633' --switch ovsk,protocols=OpenFlow13
Running the App
Workflow
Learning Switch Startup
- The bundle activator, org.opendaylight.openflowplugin.learningswitch.Activator is using AbstractBindingAwareConsumer as its activator base, which registers with OSGi and waits for MD-SAL to get initialized and fires off onSessionInitialized().
public class Activator extends AbstractBindingAwareConsumer implements AutoCloseable { @Override public void onSessionInitialized(ConsumerContext session) { [...] } }
- Once MD-SAL is online, we get references to the following services registered with MD-SAL:
- DataBrokerService
- NotificationService
- PacketProcessingService
and inject them into a new LearningSwitchManagerMultiImpl instance, which we then start.
- During its startup, LearningSwitchManagerMultiImpl hooks up into MD-SAL services by:
- registering a new instance of PacketInDispatcherImpl as a NotificationListener
- creating a FlowCommitWrapperImpl instance, which will store flow information into the Configuration data tree
- creating a MultipleLearningSwitchHandlerFacadeImpl instance, whose function is to ensure that a single instance of LearningSwitchHandlerSimpleImpl is created for each known switch
- creating a WakeupOnNode instance and registering it with DataBrokerService to have it notified about when FlowCapableNodes change in the inventory
New Switch Activation
When OpenFlow plugin discovers sees a new switch connected, it will create a new entry for it in the inventory and will start populating the inventory with the tables learned from the switch. Each such update triggers WakeupOnNode.onDataChanged() callback, which examines the inventory entry and looks for presence of a table with id == 0 (InstanceIdentifier: Nodes/Node/augmentation:FlowCapableNode/Table). As soon as it finds it, it will inform MultipleLearningSwitchHandlerFacadeImpl about the switch coming online.
MultipleLearningSwitchHandlerFacadeImpl reacts to the new switch by inserting a low-priority flow, which will forward all packets to the controller, into the configuration data tree. It then notifies the per-switch LearningSwitchHandlerSimpleImpl of the location of table 0. The store operation will asynchronously trigger FRM, which will push the flow onto the switch through the OpenFlow Plugin. LearningSwitchHandlerSimpleImpl disconnects WakeupOnNode listener from the inventory node of that particular switch, so as to suppress any future notifications.
From this point on the new switch is configured and the rest of the logic will only react to PacketInNotification events.
Processing a PacketInNotification
When a PacketIn occurs, LearningSwitchHandlerSimpleImpl.onPacketReceived() triggers. It examines the packet's source and destination MAC address and creates the source MAC to ingress port mapping. It then checks if the destination MAC has a port mapping defined. If it does not, it floods the packet to all ports. If it there is a mapping, it will check if a flow has been created to cover this packet's path towards the port where the destination MAC was seen. If not, it creates a flow. In either case it forwards the packet through the destination port. This is necessary because flow installation has a latency during which we should not be losing packets.
After starting injecting packets, you should see a gradual drop in the number of packets being sent to the controller as it builds up the flows to cover the traffic hitting the switches.
The Testing Scenario
- build distribution/base - remove plugins/org.opendaylight.controller.samples.simpleforwarding-*-SNAPSHOT.jar - copy simple learning jar into plugins folder - start controller (run.sh) - start wireshark - start mininet+(ovs(OF-1.0|OF-1.3)|cpqd)
- ovs(OF-1.0) : sudo mn --topo single,10 --controller 'remote,ip=10.0.42.5,port=6633' --switch ovsk,protocols=OpenFlow10 - ovs(OF-1.3) : sudo mn --topo single,10 --controller 'remote,ip=10.0.42.5,port=6633' --switch ovsk,protocols=OpenFlow13 - cpqd : sudo mn --topo single,10 --controller 'remote,ip=10.0.42.5,port=6633' --mac --switch user
- observe wireshark, wait for flow_mod message - check if flow is pushed to switch
- ovs(OF1.0): sudo ovs-ofctl -O OpenFlow10 dump-flows s1 - ovs(OF1.3): sudo ovs-ofctl -O OpenFlow13 dump-flows s1 - cpqd : sudo dpctl unix:/tmp/s1 stats-flow
- in mininet enter:
- h1 ping h2 - pingall
- observe ws, flows ..
Reference:https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:MD-SAL_App_Tutorial
评论
发表评论