Thanks for sending the code! First, please send the code as a patch:
https://github.com/osrg/ryu/blob/master/SubmittingPatches.rst Second, we don't put word doc into the code. So please convert the word doc into a format that fit under doc directory. Lastly there are some comments on the code. On Wed, 28 Aug 2013 12:00:06 +0530 Sujai Buvaneswaran <[email protected]> wrote: > # Copyright (C) 2013 Veryx Technologies Pvt Limited. > # > # Licensed under the Apache License, Version 2.0 (the "License"); > # you may not use this file except in compliance with the License. > # You may obtain a copy of the License at > # > # http://www.apache.org/licenses/LICENSE-2.0 > # > # Unless required by applicable law or agreed to in writing, software > # distributed under the License is distributed on an "AS IS" BASIS, > # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > # implied. > # See the License for the specific language governing permissions and > # limitations under the License. > > """ > This module performs L2 learning for an incoming flow, assigns it > to a specific egress port queue based on the flow's VLAN Pbit value and > adds the flow entry in the switch flow table. The queue assignment will > be > based on default Pbit-Queue mapping defined by default in the module or > overwritten using user defined value Pbit-Queue mapping value. Any flows > received without VLAN tag will be assigned to Queue 1. > > The default Pbit-Queue mapping is {0:8, 1:7, 2:6, 3:5, 4:4, 5:3, 6:2, > 7:1} where > 0 denotes VLAN Pbit and 8 denotes Queue ID. > """ > > import logging > import struct > import ast > > from oslo.config import cfg > from ryu.base import app_manager > from ryu.controller import mac_to_port > from ryu.controller import ofp_event > from ryu.controller.handler import MAIN_DISPATCHER > from ryu.controller.handler import set_ev_cls > from ryu.ofproto import ofproto_v1_0 > from ryu.lib.mac import haddr_to_str > > # User-defined input > # Below code re-assigns the Pbit-Queue mapping for Queue ID 4 and 5 with Pbit > 5 and 6 > CONF = cfg.CONF > CONF.register_cli_opts([ > cfg.StrOpt('pcp-queue', default={5:4,6:5}, > help='pcp to queue map') > ]) The above works? > > class L2QoS(app_manager.RyuApp): > OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] > > def __init__(self, *args, **kwargs): > super(L2QoS, self).__init__(CONF.pcp_queue,*args, **kwargs) > self.mac_to_port = {} # MAC Address table initialization > self.pcp_queue = CONF.pcp_queue > self.port = self.pcp_queue.keys() > > """ > This function installs the flow in the OpenFlow switch Flow Table > """ > def add_flow(self, datapath, in_port, dst, vlan_pcp, _eth_type,nw_src, > actions): > ofproto = datapath.ofproto > wildcards = ofproto_v1_0.OFPFW_ALL > wildcards &= ~ofproto_v1_0.OFPFW_IN_PORT > wildcards &= ~ofproto_v1_0.OFPFW_DL_DST > if _eth_type == 33024 : Please use ofproto/ether.py for ether types. > wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN_PCP > wildcards &= ~ofproto_v1_0.OFPFW_NW_SRC_MASK > match = datapath.ofproto_parser.OFPMatch( > wildcards, in_port, 0, dst, > 0, vlan_pcp, 0, 0, 0, nw_src, 0, 0, 0) > elif _eth_type == 2048 : > wildcards &= ~ofproto_v1_0.OFPFW_DL_TYPE > wildcards &= ~ofproto_v1_0.OFPFW_NW_SRC_MASK > match = datapath.ofproto_parser.OFPMatch( > wildcards, in_port, 0, dst, > 0, 0, _eth_type, 0, 0, nw_src, 0, 0, 0) > else : > wildcards &= ~ofproto_v1_0.OFPFW_DL_TYPE > match = datapath.ofproto_parser.OFPMatch( > wildcards, in_port, 0, dst, > 0, 0, _eth_type, 0, 0, 0, 0, 0, 0) > > mod = datapath.ofproto_parser.OFPFlowMod( > datapath=datapath, match=match, cookie=0, > command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, > priority=ofproto.OFP_DEFAULT_PRIORITY, > flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) > datapath.send_msg(mod) > > @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) > """ > This function handles packet-in messages from the switch and performs L2 > learning and vlan > pcp to queue mapping. > """ > def _packet_in_handler(self, ev): > msg = ev.msg > datapath = msg.datapath > ofproto = datapath.ofproto > > dst, src, _eth_type, vlan_pcp = struct.unpack_from('!6s6sHB', > buffer(msg.data), 0) > vlan_pcp = int(vlan_pcp)/32 Can you use our packet library to parse packets? > dpid = datapath.id > self.mac_to_port.setdefault(dpid, {}) > #Learn new MAC Address from packet-in message. > self.mac_to_port[dpid][src] = msg.in_port > nw_src = 0 > #Flood the frame if destination MAC is unknown > if dst not in self.mac_to_port[dpid] and haddr_to_str(dst) != > 'ff:ff:ff:ff:ff:ff': > out_port = ofproto.OFPP_FLOOD > self.logger.info("Port for %s unknown -- flooding" % > haddr_to_str(dst)) > #Flood the frame if destination MAC is Broadcast > elif haddr_to_str(dst) == 'ff:ff:ff:ff:ff:ff': > out_port = ofproto.OFPP_FLOOD > self.logger.info("Destination address %s is broadcast -- > flooding" % haddr_to_str(dst)) > #Forward the frame based on MAC Address table learnings > elif dst in self.mac_to_port[dpid]: > out_port = self.mac_to_port[dpid][dst] > self.logger.info("packet in %s %s %s %s", > dpid, haddr_to_str(src), haddr_to_str(dst), > msg.in_port) > #Assign the flow to Queue ID 1 if the flow is untagged > if _eth_type == 2048: > q_id = 1 > vlan_pcp = 0 > a=struct.unpack_from('!6s6sHBxHBB2xIII', buffer(msg.data), 0) Ditto. > nw_src = a[8] > #Assign the flow to the defined Queue ID if the flow is VLAN > tagged > elif _eth_type == 33024: > if self.pcp_queue.keys().count(vlan_pcp) == 0 : > dict = {0:8, 1:7, 2:6, 3:5, 4:4, 5:3, 6:2, 7:1} #Default > Pbit to Queue mapping > q_id = dict[vlan_pcp] > else : > q_id = self.pcp_queue[vlan_pcp] #Overwrite Pbit to Queue > mapping with user defined inputs > a=struct.unpack_from('!6s6sHBxHBB2xIII', buffer(msg.data), 0) > nw_src = a[9] > else : > q_id = 1 > vlan_pcp = 0 > > if out_port != ofproto.OFPP_FLOOD: > actions = > [datapath.ofproto_parser.OFPActionEnqueue(port=out_port,queue_id=q_id)] > self.add_flow(datapath, msg.in_port, dst,vlan_pcp, _eth_type, > nw_src, actions) > elif out_port == ofproto.OFPP_FLOOD: > actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] > out = datapath.ofproto_parser.OFPPacketOut( > datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, > actions=actions) > datapath.send_msg(out) > # out = > datapath.ofproto_parser.OFPQueueGetConfigRequest(datapath=datapath,port=1) > # datapath.send_msg(out) > > > @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) > """ > This function handles port status messages from the switch. > """ > def _port_status_handler(self, ev): We don't need this hander, right? > msg = ev.msg > reason = msg.reason > port_no = msg.desc.port_no > > ofproto = msg.datapath.ofproto > if reason == ofproto.OFPPR_ADD: > self.logger.info("Port added %s", port_no) > elif reason == ofproto.OFPPR_DELETE: > self.logger.info("Port Deleted %s", port_no) > elif reason == ofproto.OFPPR_MODIFY: > self.logger.info("Port Modified %s", port_no) > else: > self.logger.info("Illegal Port State %s %s", port_no, reason) > > ------------------------------------------------------------------------------ Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
