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 e5ef819..73f8bb7 100644 --- a/ryu/controller/dpset.py +++ b/ryu/controller/dpset.py @@ -20,7 +20,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') @@ -37,17 +39,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_ @@ -61,17 +103,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] @@ -103,6 +146,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 ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Ryu-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ryu-devel
