diff options
author | Victor Orlikowski <vjo@duke.edu> | 2015-12-25 06:11:56 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-12-30 14:21:01 +0900 |
commit | 27ca64c72604a3bf5a89f55929ad7617dce80c2a (patch) | |
tree | 517a41d2f7ecbbd417a51bf7859f0ff66969ffd1 | |
parent | 6945ad3ef16e0dd11d7bbec9de19cae4844fe96d (diff) |
Generate new datapath event for switch connecting multiple times
If a switch connects multiple times, there are a number of potential
causes. A potential cause is that the OF agent on the switch crashed,
and was re-launched - but, because of the crash, Ryu believes that the
switch is still connected.
Should this occur, the newly re-launched OF agent on the switch often
clears the flow tables on the switch, before connecting to the
controller. When the switch agent re-connects to Ryu, the state of
the flow tables on the switch may not match what Ryu expects.
As a result, I suggest generating a new event: EventDPReconnected
Extending the existing EventDP would change semantics, and would break
apps others have written that rely on those semantics.
Applications registering a handler for EventDPReconnected would then
be able to choose whether to wipe the flow tables on the switch and
re-send flow rules, or whether to probe the switch with a flow-stats
message, and re-send rules more carefully.
Adding EventDPReconnected is the best solution to not break existing
apps, and to implement the following portion of section 6.3.3
(“Connection Interruption”) of the OpenFlow 1.3.4 specification, for
switches that have connected multiple times:
" When the OpenFlow channel is reestablished, the flow entries present
in the flow tables at that time are preserved and normal OpenFlow
operation resumes. If desired, the controller has then the option of
reading all flow entries with a flow-stats request (see 7.3.5.2), to
re-synchronise its state with the switch state. Alternatively, the
controller then has the option of deleting all flow entries with a
flow-mod request (see 6.4), to start from a clean state on the switch.
"
Signed-off-by: Victor J. Orlikowski <vjo@duke.edu>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/controller/dpset.py | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/ryu/controller/dpset.py b/ryu/controller/dpset.py index 4eca0467..0d65d747 100644 --- a/ryu/controller/dpset.py +++ b/ryu/controller/dpset.py @@ -53,6 +53,11 @@ class EventDP(EventDPBase): self.ports = [] # port list when enter or leave +class EventDPReconnected(EventDPBase): + def __init__(self, dp): + super(EventDPReconnected, self).__init__(dp) + + class EventPortBase(EventDPBase): def __init__(self, dp, port): super(EventPortBase, self).__init__(dp) @@ -113,12 +118,14 @@ class DPSet(app_manager.RyuApp): # - forget the older connection as it likely will disappear soon # - do not send EventDP leave/enter events # - keep the PortState for the dpid + send_dp_reset = False if dp.id in self.dps: self.logger.warning('DPSET: Multiple connections from %s', dpid_to_str(dp.id)) self.logger.debug('DPSET: Forgetting datapath %s', self.dps[dp.id]) (self.dps[dp.id]).close() self.logger.debug('DPSET: New datapath %s', dp) + send_dp_reset = True self.dps[dp.id] = dp if dp.id not in self.port_state: self.port_state[dp.id] = PortState() @@ -129,6 +136,9 @@ class DPSet(app_manager.RyuApp): self._port_added(dp, port) ev.ports.append(port) self.send_event_to_observers(ev) + if send_dp_reset: + ev = EventDPReconnected(dp) + self.send_event_to_observers(ev) def _unregister(self, dp): # see the comment in _register(). |