Hi Taha,

I couldn't launch your Ryu application on my environment...


(py27) $ ryu-manager shared_arp.py
loading app shared_arp.py
Traceback (most recent call last):
  File "/home/iwase/ryu/.tox/py27/bin/ryu-manager", line 11, in <module>
    load_entry_point('ryu==4.23', 'console_scripts', 'ryu-manager')()
File "/home/iwase/ryu/.tox/py27/local/lib/python2.7/site-packages/ryu/cmd/manager.py", line 98, in main
    app_mgr.load_apps(app_lists)
File "/home/iwase/ryu/.tox/py27/local/lib/python2.7/site-packages/ryu/base/app_manager.py", line 415, in load_apps
    cls = self.load_app(app_cls_name)
File "/home/iwase/ryu/.tox/py27/local/lib/python2.7/site-packages/ryu/base/app_manager.py", line 392, in load_app
    mod = utils.import_module(name)
File "/home/iwase/ryu/.tox/py27/local/lib/python2.7/site-packages/ryu/utils.py", line 104, in import_module
    return importlib.import_module(modname)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/iwase/ryu/shared_arp.py", line 171
    switch_list = get_switch(self.topology_api_app, None)
    ^
IndentationError: unexpected indent


I tried to fix this indentation error, similar errors ware shown.
I recommend to sort out indentations. "autopep8" is very helpful!

After my fixation, I couldn't reproduce the issue you mentioned.
Ryu was running on the stable state as following.


$ ryu-manager shared_arp.py
loading app shared_arp.py
loading app ryu.topology.switches
loading app ryu.controller.ofp_handler
instantiating app None of DPSet
creating context dpset
instantiating app ryu.topology.switches of Switches
instantiating app shared_arp.py of SimpleSwitch14
instantiating app ryu.controller.ofp_handler of OFPHandler
dpid Join SW {6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
Switch_Enter : EventSwitchEnter<dpid=6, 3 ports>
Switch_port_table :{6: set([1, 2, 3])}
datpath_list {6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} 
=
dpid Join SW {5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
dpid Join SW {3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
dpid Join SW {3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
dpid Join SW {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
Switch_Enter : EventSwitchEnter<dpid=5, 3 ports>
Switch_port_table :{1: set([1, 2, 3]), 6: set([1, 2, 3])}
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 6: set([1, 2, 3])}
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} datpath_list {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} =
Switch_Enter : EventSwitchEnter<dpid=3, 3 ports>
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} datpath_list {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} =
Switch_Enter : EventSwitchEnter<dpid=4, 3 ports>
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} datpath_list {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} =
Switch_Enter : EventSwitchEnter<dpid=1, 3 ports>
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} datpath_list {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} = dpid Join SW {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 2: <ryu.controller.controller.Datapath object at 0x7f0b725bcd90>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>}
port state change event triggered
Switch_Enter : EventSwitchEnter<dpid=2, 3 ports>
Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])} Switch_port_table :{1: set([1, 2, 3]), 2: set([1, 2, 3]), 3: set([1, 2, 3]), 4: set([1, 2, 3]), 5: set([1, 2, 3]), 6: set([1, 2, 3])}
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=1,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.1', 'in_port': 3, 'ipv4_dst': '10.0.0.2'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=3,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.2', 'in_port': 1, 'ipv4_dst': '10.0.0.1'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=2,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.1', 'in_port': 1, 'ipv4_dst': '10.0.0.2'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=1,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.2', 'in_port': 2, 'ipv4_dst': '10.0.0.1'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=2,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.1', 'in_port': 1, 'ipv4_dst': '10.0.0.2'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=1,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.2', 'in_port': 2, 'ipv4_dst': '10.0.0.1'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=3,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.1', 'in_port': 1, 'ipv4_dst': '10.0.0.2'}),out_group=0,out_port=0,priority=1,table_id=0)
flow_mod message called
mod version=None,msg_type=None,msg_len=None,xid=None,OFPFlowMod(buffer_id=4294967295,command=0,cookie=0,cookie_mask=0,flags=0,hard_timeout=0,idle_timeout=0,instructions=[OFPInstructionActions(actions=[OFPActionOutput(len=16,max_len=65509,port=1,type=0)],type=4)],match=OFPMatch(oxm_fields={'eth_type': 2048, 'ipv4_src': '10.0.0.2', 'in_port': 3, 'ipv4_dst': '10.0.0.1'}),out_group=0,out_port=0,priority=1,table_id=0) datpath_list {1: <ryu.controller.controller.Datapath object at 0x7f0b72443350>, 2: <ryu.controller.controller.Datapath object at 0x7f0b725bcd90>, 3: <ryu.controller.controller.Datapath object at 0x7f0b72443410>, 4: <ryu.controller.controller.Datapath object at 0x7f0b7293b790>, 5: <ryu.controller.controller.Datapath object at 0x7f0b72443850>, 6: <ryu.controller.controller.Datapath object at 0x7f0b7293b2d0>} =
...(No more log message while 10 minutes)...


Thanks,
Iwase


On 2018年03月05日 03:55, Taha Khan wrote:
Hi Iwase,

Even I don't know, why is that happening.
When I added the separate handler for EventLinkDelete it is getting triggered when I see no reason to for it to trigger.
I think there is a bug in EventLinkDelete handler.
You can reproduce it by running two files attached.
Could you please suggest what might be wrong here. It would be great lead .

Thanks!
Taha.


On Tue, Feb 27, 2018 at 11:45 PM, Iwase Yusuke <iwase.yusu...@gmail.com <mailto:iwase.yusu...@gmail.com>> wrote:

    Hi Taha,

    I couldn't investigate why, but on your attached log messages,
    "EventSwitchLeave" are shown. Datapath might be disconnected for some 
reason,
    then "EventLinkDelete" occurred.

    Thanks,
    Iwase


    On 2018年02月28日 00:13, Taha Khan wrote:


        Hi,

        I added EventLinkDelete in my code. And noticed EventLinkDelete is
        getting triggered, while discovering the topology, although I am
        installing flow rules in the switch those are getting installed
        successfully.
        I am confused why the delete event is getting triggered at the first
        place or should I ignore it.

        I am sending this email second time because I received HTTP error 550
        earlier.

        Thanks!
        Taha



        
------------------------------------------------------------------------------
        Check out the vibrant tech community on one of the world's most
        engaging tech sites, Slashdot.org! http://sdm.link/slashdot



        _______________________________________________
        Ryu-devel mailing list
        Ryu-devel@lists.sourceforge.net <mailto:Ryu-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/ryu-devel
        <https://lists.sourceforge.net/lists/listinfo/ryu-devel>




------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot



_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation.
#
# 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.

from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
import logging
import struct
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER, CONFIG_DISPATCHER
from ryu.lib.packet import ipv4
from ryu.lib import mac
from ryu.lib.packet import arp
from ryu.topology import event, switches
from ryu.topology.api import get_switch, get_link
from ryu.controller import dpset
from ryu.lib import dpid
from ryu.controller import handler
from threading import Timer


class SimpleSwitch14(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
    _CONTEXTS = {'dpset': dpset.DPSet}

    def __init__(self, *args, **kwargs):
        super(SimpleSwitch14, self).__init__(*args, **kwargs)
        self.topology_api_app = self
        self.mac_to_port = {}
        self.switch_port_table = {}
        self.link_to_port = {}
        self.interior_ports = {}
        self.dpid_port_set = set()
        self.ip_mac_table = {}
        self.ip_dpidport = {}
        self.datapath_list = {}
        self.link_ids = {}
        self.key = []
        self.value = []

        ######################################################################################
        self.flow_info = ['10.0.0.1', '10.0.0.2']
        self.path_rule = {1: {'in_port': 3, 'out_port': 1}, 2: {'in_port': 1, 'out_port': 2},
                          3: {'in_port': 1, 'out_port': 2}, 4: {'in_port': 1, 'out_port': 3}}

    #######################################################################################

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # install table-miss flow entry
        #
        # We specify NO BUFFER to max_len of the output action due to
        # OVS bug. At this moment, if we specify a lesser number, e.g.,
        # 128, OVS will send Packet-In with invalid buffer_id and
        # truncated packet data. In that case, we cannot output packets
        # correctly.  The bug has been fixed in OVS v2.1.0.
        match = parser.OFPMatch()
        actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                          ofproto.OFPCML_NO_BUFFER)]
        self.add_flow(datapath, 0, match, actions)

        # ##############################End_of_Group_Mod_Action#####################################

    @set_ev_cls(ofp_event.EventOFPStateChange,
                [MAIN_DISPATCHER, DEAD_DISPATCHER])
    def _state_change_handler(self, ev):
        dp = ev.datapath
        ofproto = dp.ofproto
        parser = dp.ofproto_parser
        if ev.state == handler.MAIN_DISPATCHER:
            self.datapath_list[dp.id] = dp
            msg = 'Join SW'
        elif ev.state == handler.DEAD_DISPATCHER:
            ret = self.datapath_list.pop(dp.id, None)
            if ret is None:
                msg = 'Leave unknown SW'

            else:
                msg = 'Leave sw'
        self.logger.info('dpid {} {} '.format(msg, self.datapath_list))
        self.logger.info("port state change event triggered")

    # ###########  End of Incoming ports at switch 1,4 at port (1) #####################

    def create_port_map(self, switch_list):
        """
            Create interior_port table and access_port table.
        """
        for sw in switch_list:
            dpid = sw.dp.id
            self.switch_port_table.setdefault(dpid, set())
            self.interior_ports.setdefault(dpid, set())

            for p in sw.ports:
                self.switch_port_table[dpid].add(p.port_no)
            self.logger.info('Switch_port_table :{}'.format(
                self.switch_port_table))

    def create_interior_links(self, link_list):
        """
            Get links`srouce port to dst port  from link_list,
            link_to_port:(src_dpid,dst_dpid)->(src_port,dst_port)
        """

        for link in link_list:
            src = link.src
            dst = link.dst
            self.link_to_port[(src.dpid, dst.dpid)] = (
                src.port_no, dst.port_no)

            # Find the access ports and interior ports
            if link.src.dpid in self.switches:
                self.interior_ports[link.src.dpid].add(link.src.port_no)
            if link.dst.dpid in self.switches:
                self.interior_ports[link.dst.dpid].add(link.dst.port_no)

            if len(self.link_to_port) == 16:  # Update this constant

                for i in self.link_to_port.keys():
                    self.key.append(i)
                for i in self.link_to_port.values():
                    self.value.append(i)
                for i in range(len(self.link_to_port)):
                    self.link_ids[i + 1] = self.key[i] + self.value[i]
        self.logger.info('Link_ids {}'.format(self.link_ids))
        self.logger.info('Link_to_Port {}'.format(self.link_to_port))
        self.logger.info('Interior_Ports {}'.format(self.interior_ports))

    def create_access_ports(self):
        """
            Get ports without link into access_ports
        """
        self.dpid_port_set.clear()
        for sw in self.switch_port_table:
            all_port_table = self.switch_port_table[sw]
            interior_port = self.interior_ports[sw]
            for port in list(all_port_table - interior_port):
                self.logger.info('port:{}'.format(port))
                dpid_port_pair = (sw, port)
                self.dpid_port_set.add(dpid_port_pair)

        self.logger.info('Access_ports : {}'.format(self.dpid_port_set))

    events = [event.EventSwitchEnter,
              event.EventSwitchLeave]

    @set_ev_cls(events)
    def get_switches(self, ev):
        """
            Get topology info and store it.
        """
        self.logger.info("Switch_Enter : {}".format(ev))
        switch_list = get_switch(self.topology_api_app, None)
        self.create_port_map(switch_list)
        self.switches = self.switch_port_table.keys()
        if len(self.datapath_list) == 6:
            self.path_installer()
        self.logger.info("datpath_list {} =".format(self.datapath_list))

    @set_ev_cls(event.EventLinkAdd)
    def get_links(self, ev):
        self.logger.info("event : {}".format(ev))
        links = get_link(self.topology_api_app, None)
        self.create_interior_links(links)
        self.create_access_ports()
        self.logger.info(
            "********************from get_links*********************")
        # self.path_installer()  Throws Error and program terminates

    @set_ev_cls(event.EventLinkDelete)
    def port_lost(self, ev):
        self.logger.info(
            "*********Event Link Delete port lost Called**************")
        msg = ev.link.to_dict()

    def add_flow(self, datapath, priority, match, actions):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]

        mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
                                match=match, instructions=inst)
        datapath.send_msg(mod)

    def _build_packet_out(self, datapath, buffer_id, src_port, dst_port, data):
        """
            Build packet out object.
        """
        actions = []
        if dst_port:
            actions.append(datapath.ofproto_parser.OFPActionOutput(dst_port))

        msg_data = None
        if buffer_id == datapath.ofproto.OFP_NO_BUFFER:
            if data is None:
                return None
            msg_data = data

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=buffer_id,
            data=msg_data, in_port=src_port, actions=actions)
        return out

    def _register_host_entry(self, arp_src_ip, arp_src_mac, datapathID, port):
        self.ip_mac_table[arp_src_ip] = arp_src_mac
        dpid_port = (datapathID, port)
        self.ip_dpidport[arp_src_ip] = dpid_port

    def arp_forwarding(self, msg, arp_header, from_datapath, ether, ethernet_src, ethernet_dst, in_port):
        ofproto = from_datapath.ofproto
        arp_src_ip = arp_header.src_ip
        arp_dst_ip = arp_header.dst_ip
        arp_src_mac = arp_header.src_mac
        arp_dst_mac = arp_header.dst_mac

        if ethernet_dst == mac.BROADCAST_STR:  # Handle ARP broadcast
            # self.logger.info('This is ARP broadcast received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}'.format(in_port, from_datapath.id,
            # arp_src_ip, arp_src_mac, ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst))

            # No src ip found, so storing it in the table
            if self.ip_mac_table.get(arp_src_ip) is None:
                self.logger.info(
                    "****No mac entry found for IP. adding entry.....****")
                self._register_host_entry(
                    arp_src_ip, arp_src_mac, from_datapath.id, in_port)

            # dst_ip exist in ip_mac_table, so proxy it
            if self.ip_mac_table.get(arp_dst_ip) is not None:
                ARP_Reply = packet.Packet()
                mac_from_table = self.ip_mac_table.get(arp_dst_ip)
                ARP_Reply.add_protocol(
                    ethernet.ethernet(ethertype=ether.ethertype, dst=ethernet_src, src=mac_from_table))
                ARP_Reply.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=mac_from_table, src_ip=arp_dst_ip,
                                               dst_mac=arp_src_mac, dst_ip=arp_src_ip))
                ARP_Reply.serialize()
                from_datapath.send_msg(
                    self._build_packet_out(from_datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER,
                                           in_port, ARP_Reply.data))
                self.logger.info("****Found mac entry for IP. Proxy-ing****")

            else:  # no dst_ip in ip_mac_table, flood
                for dpid_port_tup in self.dpid_port_set:
                    if dpid_port_tup not in self.ip_dpidport.values():
                        self.logger.info(
                            "********Flooding {}***********".format(dpid_port_tup))
                        datapath = self.datapath_list[dpid_port_tup[0]]
                        datapath.send_msg(self._build_packet_out(datapath, ofproto.OFP_NO_BUFFER,
                                                                 ofproto.OFPP_CONTROLLER, dpid_port_tup[1], msg.data))

        else:  # if ARP packet and its a reply
            # self.logger.info('This is ARP reply received at port {} of switch {} from IP {}, ARP Src Mac {}, ethernet src {} to IP {}, ARP Destn Mac {}, ethernet dst {}'.format(
            # in_port, from_datapath.id, arp_src_ip, arp_src_mac, ethernet_src, arp_dst_ip, arp_dst_mac, ethernet_dst))
            self._register_host_entry(
                arp_src_ip, arp_src_mac, from_datapath.id, in_port)
            dpid_inport = self.ip_dpidport.get(arp_dst_ip)
            datapath = self.datapath_list[dpid_inport[0]]
            datapath.send_msg(self._build_packet_out(datapath, ofproto.OFP_NO_BUFFER,
                                                     ofproto.OFPP_CONTROLLER, dpid_inport[1], msg.data))

        self.logger.info(
            "*********************************************************************************************")
        return

    # ####################################Path_installer######################################
    def _send_flow_mod(self, datapath, flow_info, in_port, out_port):
        self.logger.info('flow_mod message called')
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        actions = []
        actions.append(parser.OFPActionOutput(out_port))
        match = parser.OFPMatch(
            in_port=in_port, eth_type=0x0800, ipv4_src=flow_info[0], ipv4_dst=flow_info[1])
        inst = [parser.OFPInstructionActions(
            ofproto.OFPIT_APPLY_ACTIONS, actions)]
        mod = parser.OFPFlowMod(
            datapath=datapath, priority=1, match=match, instructions=inst)
        self.logger.info('mod {}'.format(mod))
        datapath.send_msg(mod)
        return

    def path_installer(self):
        invert_flow_info = (self.flow_info[1], self.flow_info[0])
        for dp in self.path_rule.keys():  # ---For switch 1,2,3,4---#########
            self._send_flow_mod(
                self.datapath_list[dp], self.flow_info, self.path_rule[dp]['in_port'], self.path_rule[dp]['out_port'])
            self._send_flow_mod(self.datapath_list[dp], invert_flow_info,
                                self.path_rule[dp]['out_port'], self.path_rule[dp]['in_port'])

    # #####################################End of path_installer################################

    @set_ev_cls(ofp_event.EventOFPPacketIn, [MAIN_DISPATCHER, CONFIG_DISPATCHER, DEAD_DISPATCHER])
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        in_port = msg.match['in_port']
        datapath = msg.datapath
        pkt = packet.Packet(msg.data)
        parser = datapath.ofproto_parser
        ethernet_header = pkt.get_protocol(ethernet.ethernet)
        ethernet_dst = ethernet_header.dst
        ethernet_src = ethernet_header.src
        arp_header = pkt.get_protocol(arp.arp)

        if ethernet_header.ethertype == ether_types.ETH_TYPE_LLDP:  # ignore lldp packet
            return

        if ethernet_dst[:5] == "33:33":  # ignore IPV6 multicast packet
            match = parser.OFPMatch(in_port=in_port, eth_dst=ethernet_dst)
            actions = []
            self.add_flow(datapath, 1, match, actions)
            return

        self.logger.info("packet in {} {} {} {}".format(
            datapath.id, ethernet_src, ethernet_dst, in_port))

        if arp_header:  # handle arp packets
            self.logger.info("******ARP Processing********")
            self.arp_forwarding(
                msg, arp_header, datapath, ethernet_header, ethernet_src, ethernet_dst, in_port)
        return
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to