kytos / flow_manager

MIT License
1 stars 16 forks source link

When Kytos controller reconnect to the switch, the flows should be preserved #115

Closed italovalcy closed 3 years ago

italovalcy commented 3 years ago

Hi,

When the Kytos controller disconnects from the switch and then reconnects, all the flows are removed and recreated, causing a traffic disruption. When the switch is reconnected to the controller, the consistency check should work only in the inconsistencies and not remove all to create.

The following end-to-end test is failing:

_______ TestE2EFlowManager.test_030_restart_kytos_should_preserve_flows ________

self = <tests.test_e2e_21_flow_manager.TestE2EFlowManager instance at 0x7fbbe41b9d88>

   def test_030_restart_kytos_should_preserve_flows(self):
       """Test if, after kytos restart, the flows are preserved on the switch
          flow table."""
       self.net.restart_kytos_clean()
       time.sleep(5)

       payload = {
           "flows": [
               {
               "priority": 10,
               "match": {
                   "in_port": 1,
                   "dl_vlan": 999
               },
               "actions": [
                   {
                   "action_type": "output",
                   "port": 2
                   }
               ]
               }
           ]
       }

       api_url = KYTOS_API + '/flow_manager/v2/flows/00:00:00:00:00:00:00:01'
       response = requests.post(api_url, data=json.dumps(payload),
                                headers={'Content-type': 'application/json'})
       assert response.status_code == 200
       data = response.json()
       assert 'FlowMod Messages Sent' in data['response']

       # wait for the flow to be installed
       wait_time = 20
       time.sleep(wait_time)

       # restart controller keeping configuration
       t1 = time.time()
       self.net.start_controller()
       self.net.wait_switches_connect()
       delta = time.time() - t1

       # wait for the flow to be installed
       time.sleep(wait_time)
       wait_time += wait_time

       s1 = self.net.net.get('s1')
       flows_s1 = s1.dpctl('dump-flows')
       assert len(flows_s1.split('\r\n ')) == 2
       for flow in flows_s1.split('\r\n '):
           match = re.search("duration=([0-9.]+)", flow)
           duration = float(match.group(1))
         assert duration >= wait_time + delta
E           assert 21.996 >= (40 + 10.281726837158203)

This issue can also be related to steps taken from Kytos when the switch connects. Many openflow controllers used to delete all flows when the switch has a ConnectionUP (not sure if this is the case for kytos)

italovalcy commented 3 years ago

Hi folks,

This issue is related to #124, more specifically because flow_manager is not aware of the actually installed flows when the switch connects and the send a FLOW_MOD to install all flows according to the stored_flows.

Kytos log will have some like:

2021-04-22 18:19:27,483 - INFO [kytos.napps.kytos/flow_manager] (Thread-29) Flows resent to Switch 00:00:00:00:00:00:00:01

One suggestion to solve this issue is to refactor the way Kytos deal with the recently connected switch and pushes the flows. As suggested in #124, the resend_stored_flows() should only request a new flow_stats and then run the consistency check instead of forcing the FLOW_MOD install command (no matter what is in the switch's flow table).