dragonflow/dragonflow/switch/drivers/ovs/df_ovs_driver.py

118 lines
4.6 KiB
Python

# Copyright (c) 2018 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from os_ken.app.ofctl import service as of_service
from os_ken.base import app_manager
from os_ken import cfg as os_ken_cfg
from dragonflow import conf as cfg
from dragonflow.controller import datapath_layout
from dragonflow.db.models import l2
from dragonflow.db.models import switch
from dragonflow.ovsdb import vswitch_impl
from dragonflow.switch.drivers import df_switch_driver
from dragonflow.switch.drivers.ovs import datapath
from dragonflow.switch.drivers.ovs import os_ken_base_app
class DfOvsDriver(df_switch_driver.DfSwitchDriver):
def __init__(self, nb_api, ip):
super(DfOvsDriver, self).__init__(nb_api)
init_os_ken_config()
self.vswitch_api = vswitch_impl.OvsApi(ip)
self.app_mgr = app_manager.AppManager.get_instance()
self.open_flow_app = None
self.open_flow_service = None
self.neutron_notifier = None
self._datapath = datapath.Datapath(
datapath_layout.get_datapath_layout())
def initialize(self, db_change_callback, neutron_notifier):
super(DfOvsDriver, self).initialize(db_change_callback,
neutron_notifier)
self._initialize_app()
# The OfctlService is needed to support the 'get_flows' method
self._initialize_service()
def _initialize_app(self):
if self.open_flow_app:
self.app_mgr.uninstantiate(self.open_flow_app.name)
self.open_flow_app = self.app_mgr.instantiate(
os_ken_base_app.OsKenDFAdapter,
nb_api=self.nb_api,
switch_backend=self,
neutron_server_notifier=self.neutron_notifier,
db_change_callback=self.db_change_callback
)
def _initialize_service(self):
if self.open_flow_service:
self.app_mgr.uninstantiate(self.open_flow_service.name)
self.open_flow_service = self.app_mgr.instantiate(
of_service.OfctlService)
def setup_datapath(self, df_app):
self._datapath.set_up(df_app, self,
self.nb_api, self.neutron_notifier)
@property
def datapath(self):
return self._datapath
def start(self):
self.vswitch_api.initialize(self.db_change_callback)
# both set_controller and del_controller will delete flows.
# for reliability, here we should check if controller is set for OVS,
# if yes, don't set controller and don't delete controller.
# if no, set controller
targets = ('tcp:' + cfg.CONF.df_os_ken.of_listen_address + ':' +
str(cfg.CONF.df_os_ken.of_listen_port))
is_controller_set = self.vswitch_api.check_controller(targets)
integration_bridge = cfg.CONF.df.integration_bridge
if not is_controller_set:
self.vswitch_api.set_controller(integration_bridge, [targets])
is_fail_mode_set = self.vswitch_api.check_controller_fail_mode(
'secure')
if not is_fail_mode_set:
self.vswitch_api.set_controller_fail_mode(integration_bridge,
'secure')
self.open_flow_service.start()
self.open_flow_app.start()
def stop(self):
pass
def switch_sync_started(self):
self.open_flow_app.notify_switch_sync_started()
def switch_sync_finished(self):
self.open_flow_app.notify_switch_sync_finished()
def sync_ignore_models(self):
return [switch.SwitchPort, ]
def notify_port_status(self, switch_port, status):
if self.neutron_notifier:
table_name = l2.LogicalPort.table_name
iface_id = switch_port.lport
self.neutron_notifier.notify_neutron_server(table_name, iface_id,
'update', status)
def init_os_ken_config():
os_ken_cfg.CONF(project='os_ken', args=[])
os_ken_cfg.CONF.ofp_listen_host = cfg.CONF.df_os_ken.of_listen_address
os_ken_cfg.CONF.ofp_tcp_listen_port = cfg.CONF.df_os_ken.of_listen_port