For discovery, it's interested only in datapath/port appearance/disappearance. With this, discovery app would not have to handle OFP events directly.
Signed-off-by: Isaku Yamahata <[email protected]> --- ryu/controller/dpset.py | 79 ++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 75 insertions(+), 4 deletions(-) diff --git a/ryu/controller/dpset.py b/ryu/controller/dpset.py index fe42b95..b4d2e45 100644 --- a/ryu/controller/dpset.py +++ b/ryu/controller/dpset.py @@ -19,7 +19,9 @@ from ryu.controller import event from ryu.controller import dispatcher from ryu.controller import dp_type from ryu.controller import handler +from ryu.controller import ofp_event from ryu.controller.handler import set_ev_cls +import ryu.exception as ryu_exc LOG = logging.getLogger('ryu.controller.dpset') @@ -36,17 +38,57 @@ class EventDP(EventDPBase): # True: dp entered # False: dp leaving super(EventDP, self).__init__(dp) - self.enter = enter_leave + self.enter_leave = enter_leave + + +class EventPortBase(EventDPBase): + def __init__(self, dp, port): + super(EventPortBase, self).__init__(dp) + self.port = port + + +class EventPortAdd(EventPortBase): + def __init__(self, dp, port): + super(EventPortAdd, self).__init__(dp, port) + + +class EventPortDelete(EventPortBase): + def __init__(self, dp, port): + super(EventPortDelete, self).__init__(dp, port) + + +class EventPortModify(EventPortBase): + def __init__(self, dp, new_port): + super(EventPortModify, self).__init__(dp, new_port) + + +class PortState(dict): + def __init__(self, dp): + super(PortState, self).__init__() + for port in dp.ports.values(): + self.add(port.port_no, port.state) + + def add(self, port_no, state): + self[port_no] = state + + def remove(self, port_no): + del self[port_no] + + def modify(self, port_no, state): + self[port_no] = state # this depends on controller::Datapath and dispatchers in handler class DPSet(object): def __init__(self, ev_q, dispatcher_): + super(DPSet, self).__init__() + # dp registration and type setting can be occur in any order # Sometimes the sw_type is set before dp connection self.dp_types = {} self.dps = {} # datapath_id => class Datapath + self.port_state = {} # datapath_id => ports self.ev_q = ev_q self.dispatcher = dispatcher_ @@ -60,17 +102,18 @@ class DPSet(object): if dp_type_ is not None: dp.dp_type = dp_type_ - self.ev_q.queue(EventDP(dp, True)) self.dps[dp.id] = dp + self.port_state[dp.id] = PortState(dp) + self.ev_q.queue(EventDP(dp, True)) def unregister(self, dp): if dp.id in self.dps: + self.ev_q.queue(EventDP(dp, False)) del self.dps[dp.id] + del self.port_state[dp.id] assert dp.id not in self.dp_types self.dp_types[dp.id] = getattr(dp, 'dp_type', dp_type.UNKNOWN) - self.ev_q.queue(EventDP(dp, False)) - def set_type(self, dp_id, dp_type_=dp_type.UNKNOWN): if dp_id in self.dps: dp = self.dps[dp_id] @@ -102,6 +145,34 @@ class DPSet(object): LOG.debug('DPSET: unregister datapath %s', datapath) self.unregister(datapath) + @set_ev_cls(ofp_event.EventOFPPortStatus, handler.MAIN_DISPATCHER) + def port_status_handler(self, ev): + msg = ev.msg + reason = msg.reason + datapath = msg.datapath + port = msg.desc + ofproto = datapath.ofproto + + LOG.debug('port status %s', reason) + + if reason == ofproto.OFPPR_ADD: + self.port_state[datapath.id].add(port.port_no, port.state) + self.ev_q.queue(EventPortAdd(datapath, port)) + elif reason == ofproto.OFPPR_DELETE: + self.port_state[datapath.id].remove(port.port_no) + self.ev_q.queue(EventPortDelete(datapath, port)) + else: + assert reason == ofproto.OFPPR_MODIFY + self.port_state[datapath.id].modify(port.port_no, port.state) + self.ev_q.queue(EventPortModify(datapath, port)) + + def get_port_state(self, dpid, port_no): + try: + return self.port_state[dpid][port_no] + except KeyError: + raise ryu_exc.PortNotFound(dpid=dpid, port=port_no, + network_id=None) + DISPATCHER_NAME_DPSET = 'dpset' DPSET_EV_DISPATCHER = dispatcher.EventDispatcher(DISPATCHER_NAME_DPSET) -- 1.7.1.1 ------------------------------------------------------------------------------ Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
