diff options
Diffstat (limited to 'doc/source')
-rw-r--r-- | doc/source/index.rst | 1 | ||||
-rw-r--r-- | doc/source/writing_ryu_app.rst | 123 |
2 files changed, 124 insertions, 0 deletions
diff --git a/doc/source/index.rst b/doc/source/index.rst index c51f1e2f..aab048c3 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -13,6 +13,7 @@ Contents: :maxdepth: 2 overview.rst + writing_ryu_app.rst getting_started.rst using_with_openstack.rst step_by_step.rst diff --git a/doc/source/writing_ryu_app.rst b/doc/source/writing_ryu_app.rst new file mode 100644 index 00000000..87097f7e --- /dev/null +++ b/doc/source/writing_ryu_app.rst @@ -0,0 +1,123 @@ +*********************** +Writing Ryu Application +*********************** + +Whetting Your Appetite +====================== + +If you want to manage the network gears (switches, routers, etc) at +your way, you need to write your Ryu application. Your application +tells Ryu how you want to manage the gears. Then Ryu configures the +gears by using OpenFlow protocol, etc. + +Writing Ryu application is easy. It's just Python scripts. + + +The first Ryu application +========================= + +We show a Ryu application that make OpenFlow switches work as a dumb +layer 2 switch. + +Open a text editor creating a new file with the following content: + +.. code-block:: python + + from ryu.base import app_manager + + class L2Switch(app_manager.RyuApp): + def __init__(self, *args, **kwargs): + super(L2Switch, self).__init__(*args, **kwargs) + +Ryu application is just a Python script so you can save the file with +any name, extensions, and any place you want. Let's name the file +'l2.py' at your home directory. + +This application does nothing useful yet, however it's a complete Ryu +application. In fact, you can run this Ryu application:: + + % ryu-manager ~/l2.py + loading app /Users/fujita/l2.py + instantiating app /Users/fujita/l2.py + + +All you have to do is defining needs a new subclass of RyuApp to run +your Python script as a Ryu application. + +Next let's add the functionality of sending a received packet to all +the ports. + +.. code-block:: python + + from ryu.base import app_manager + from ryu.controller import ofp_event + from ryu.controller.handler import MAIN_DISPATCHER + from ryu.controller.handler import set_ev_cls + + class L2Switch(app_manager.RyuApp): + def __init__(self, *args, **kwargs): + super(L2Switch, self).__init__(*args, **kwargs) + + @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) + def packet_in_handler(self, ev): + msg = ev.msg + dp = msg.datapath + ofp = dp.ofproto + ofp_parser = dp.ofproto_parser + + actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)] + out = ofp_parser.OFPPacketOut( + datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port, + actions=actions) + dp.send_msg(out) + + +A new method 'packet_in_handler' is added to L2Switch class. This is +called when Ryu receives an OpenFlow packet_in message. The trick is +'set_ev_cls' decorator. This decorator tells Ryu when the decorated +function should be called. + +The first argument of the decorator indicates an event that makes +function called. As you expect easily, every time Ryu gets a +packet_in message, this function is called. + +The second argument indicates the state of the switch. Probably, you +want to ignore packet_in messages before the negotiation between Ryu +and the switch finishes. Using 'MAIN_DISPATCHER' as the second +argument means this function is called only after the negotiation +completes. + +Next let's look at the first half of the 'packet_in_handler' function. + +* ev.msg is an object that represents a packet_in data structure. + +* msg.dp is an object that represents a datapath (switch). + +* dp.ofproto and dp.ofproto_parser are objects that represent the + OpenFlow protocol that Ryu and the switch negotiated. + +Ready for the second half. + +* OFPActionOutput class is used with a packet_out message to specify a + switch port that you want to send the packet out of. This + application need a switch to send out of all the ports so OFPP_FLOOD + constant is used. + +* OFPPacketOut class is used to build a packet_out message. + +* If you call Datapath class's send_msg method with a OpenFlow message + class object, Ryu builds and send the on-wire data format to the switch. + + +Here, you finished implementing your first Ryu application. You are ready to +run this Ryu application that does something useful. + + +A dumb l2 switch is too dumb? You want to implement a learning l2 +switch? Move to `the next step +<https://github.com/osrg/ryu/blob/master/ryu/app/simple_switch.py>`_. You +can learn from the existing Ryu applications at `ryu/app +<https://github.com/osrg/ryu/blob/master/ryu/app/>`_ directory and +`integrated tests +<https://github.com/osrg/ryu/blob/master/ryu/tests/integrated/>`_ +directory. |