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 | 78 ++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 74 insertions(+), 4 deletions(-) diff --git a/ryu/controller/dpset.py b/ryu/controller/dpset.py index 80ffb6f..b0c594e 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') @@ -42,7 +44,44 @@ 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 @@ -55,8 +94,10 @@ class DPSet(object): self.dp_types = {} self.dps = {} # datapath_id => class Datapath + self.port_state = {} # datapath_id => ports self.ev_q = dispatcher.EventQueue(QUEUE_NAME_DPSET, DPSET_EV_DISPATCHER) + handler.register_instance(self) def register(self, dp): @@ -67,17 +108,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] @@ -108,3 +150,31 @@ class DPSet(object): elif ev.new_dispatcher.name == handler.DISPATCHER_NAME_OFP_DEAD: 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) -- 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
