Search code examples
python-2.7ryu

Datapath#ports is kept for compatibility


I am trying to get ryu to run, especially the topology discovery.

Now I am running the demo application for that under ryu/topology/dumper.py, which is supposed to dump all topology events. I am in the ryu/topology direcory and run it using ryu-manager dumper.py. The version of ryu-manager is 2.23.2.

Shortly after starting it gives me this error:

/usr/local/lib/python2.7/dist-packages/ryu/topology/switches.py:478: UserWarning:
 Datapath#ports is kept for compatibility with the previous openflow versions (< 1.3).
 This not be updated by EventOFPPortStatus message. If you want to be updated,
 you can use 'ryu.controller.dpset' or 'ryu.topology.switches'.
  for port in dp.ports.values():

What's really weird to me is that it recommends to use ryu.topology.switches, but that error is triggered by line 478 of that very file!

The function in question is this:

class Switches(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION, ofproto_v1_2.OFP_VERSION,
                    ofproto_v1_3.OFP_VERSION, ofproto_v1_4.OFP_VERSION]
    _EVENTS = [event.EventSwitchEnter, event.EventSwitchLeave,
               event.EventPortAdd, event.EventPortDelete,
               event.EventPortModify,
               event.EventLinkAdd, event.EventLinkDelete]

    DEFAULT_TTL = 120  # unused. ignored.
    LLDP_PACKET_LEN = len(LLDPPacket.lldp_packet(0, 0, DONTCARE_STR, 0))

    LLDP_SEND_GUARD = .05
    LLDP_SEND_PERIOD_PER_PORT = .9
    TIMEOUT_CHECK_PERIOD = 5.
    LINK_TIMEOUT = TIMEOUT_CHECK_PERIOD * 2
    LINK_LLDP_DROP = 5
#...
    def _register(self, dp):
        assert dp.id is not None

        self.dps[dp.id] = dp
        if dp.id not in self.port_state:
            self.port_state[dp.id] = PortState()
            for port in dp.ports.values():    # THIS LINE
                self.port_state[dp.id].add(port.port_no, port)

Has anyone else encountered this problem before? How can I fix it?


Solution

  • I ran into the same issue (depending on your application, maybe it's not a problem, just a warning that you can ignore). Here is what I figured out after a find . -type f | xargs grep "ports is kept"

    This warning is triggered in ryu.topology.switches, by a call to _get_ports() in class Datapath of file ryu/controller/controller.py.

    class Datapath(ofproto_protocol.ProtocolDesc):
        #......
        def _get_ports(self):
            if (self.ofproto_parser is not None and
                    self.ofproto_parser.ofproto.OFP_VERSION >= 0x04):
                message = (
                    'Datapath#ports is kept for compatibility with the previous '
                    'openflow versions (< 1.3). '
                    'This not be updated by EventOFPPortStatus message. '
                    'If you want to be updated, you can use '
                    '\'ryu.controller.dpset\' or \'ryu.topology.switches\'.'
                )
                warnings.warn(message, stacklevel=2)
            return self._ports
    
        def _set_ports(self, ports):
            self._ports = ports
    
        # To show warning when Datapath#ports is read
        ports = property(_get_ports, _set_ports)
    

    My understanding is that if the warning is from ryu.topology.switches or ryu.controller.dpset, you can ignore it; because those two classes handle the event for you. But if you use Datapath directly, port status is not updated automatically. Anyone correct me if I'm wrong.

    class Switches(app_manager.RyuApp):
        #......
        @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
        def port_status_handler(self, ev):