Ejemplo n.º 1
0
 def __init__(self, conf, router):
     self.conf = conf
     self.id = router['id']
     self.router = router
     # TODO(cbrandily): deduplicate ns_name generation in metering/l3
     self.ns_name = NS_PREFIX + self.id
     self.iptables_manager = None
     self.snat_iptables_manager = None
     if self.router['distributed']:
         # If distributed routers then we need to apply the
         # metering agent label rules in the snat namespace as well.
         snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(
             self.id)
         # Check for namespace existence before we assign the
         # snat_iptables_manager
         if ip_lib.network_namespace_exists(snat_ns_name):
             self.snat_iptables_manager = iptables_manager.IptablesManager(
                 namespace=snat_ns_name,
                 binary_name=WRAP_NAME,
                 state_less=True,
                 use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     # Check of namespace existence before we assign the iptables_manager
     # NOTE(Swami): If distributed routers, all external traffic on a
     # compute node will flow through the rfp interface in the router
     # namespace.
     if ip_lib.network_namespace_exists(self.ns_name):
         self.iptables_manager = iptables_manager.IptablesManager(
             namespace=self.ns_name,
             binary_name=WRAP_NAME,
             state_less=True,
             use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     self.metering_labels = {}
Ejemplo n.º 2
0
 def __init__(self, conf, router):
     self.conf = conf
     self.id = router['id']
     self.router = router
     # TODO(cbrandily): deduplicate ns_name generation in metering/l3
     self.ns_name = NS_PREFIX + self.id
     self.iptables_manager = None
     self.snat_iptables_manager = None
     if self.router['distributed']:
         # If distributed routers then we need to apply the
         # metering agent label rules in the snat namespace as well.
         snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(self.id)
         # Check for namespace existence before we assign the
         # snat_iptables_manager
         if ip_lib.IPWrapper().netns.exists(snat_ns_name):
             self.snat_iptables_manager = iptables_manager.IptablesManager(
                 namespace=snat_ns_name,
                 binary_name=WRAP_NAME,
                 state_less=True,
                 use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     # Check of namespace existence before we assign the iptables_manager
     # NOTE(Swami): If distributed routers, all external traffic on a
     # compute node will flow through the rfp interface in the router
     # namespace.
     ip_wrapper = ip_lib.IPWrapper(namespace=self.ns_name)
     if ip_wrapper.netns.exists(self.ns_name):
         self.iptables_manager = iptables_manager.IptablesManager(
             namespace=self.ns_name,
             binary_name=WRAP_NAME,
             state_less=True,
             use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     self.metering_labels = {}
Ejemplo n.º 3
0
 def test_memoize(self):
     mo = self.useFixture(lib_fixtures.OpenFixture(self.proc_path,
                                                   '0')).mock_open
     ipv6_utils.is_enabled_and_bind_by_default()
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertTrue(enabled)
     mo.assert_called_once_with(self.proc_path, 'r')
Ejemplo n.º 4
0
 def __init__(self, namespace=None):
     self.iptables = iptables_manager.IptablesManager(state_less=True,
         use_ipv6=ipv6_utils.is_enabled_and_bind_by_default(),
         namespace=namespace)
     # TODO(majopela, shihanzhang): refactor out ipset to a separate
     # driver composed over this one
     self.ipset = ipset_manager.IpsetManager(namespace=namespace)
     # list of port which has security group
     self.filtered_ports = {}
     self.unfiltered_ports = {}
     self.ipconntrack = ip_conntrack.get_conntrack(
         self.iptables.get_rules_for_table, self.filtered_ports,
         self.unfiltered_ports, namespace=namespace)
     self._add_fallback_chain_v4v6()
     self._defer_apply = False
     self._pre_defer_filtered_ports = None
     self._pre_defer_unfiltered_ports = None
     # List of security group rules for ports residing on this host
     self.sg_rules = {}
     self.pre_sg_rules = None
     # List of security group member ips for ports residing on this host
     self.sg_members = collections.defaultdict(
         lambda: collections.defaultdict(list))
     self.pre_sg_members = None
     self.enable_ipset = cfg.CONF.SECURITYGROUP.enable_ipset
     self._enabled_netfilter_for_bridges = False
     self.updated_rule_sg_ids = set()
     self.updated_sg_members = set()
     self.devices_with_updated_sg_members = collections.defaultdict(list)
Ejemplo n.º 5
0
 def __init__(self, namespace=None):
     self.iptables = iptables_manager.IptablesManager(
         use_ipv6=ipv6_utils.is_enabled_and_bind_by_default(),
         namespace=namespace)
     # TODO(majopela, shihanzhang): refactor out ipset to a separate
     # driver composed over this one
     self.ipset = ipset_manager.IpsetManager(namespace=namespace)
     self.ipconntrack = ip_conntrack.IpConntrackManager(
         self.get_device_zone, namespace=namespace)
     self._populate_initial_zone_map()
     # list of port which has security group
     self.filtered_ports = {}
     self.unfiltered_ports = {}
     self._add_fallback_chain_v4v6()
     self._defer_apply = False
     self._pre_defer_filtered_ports = None
     self._pre_defer_unfiltered_ports = None
     # List of security group rules for ports residing on this host
     self.sg_rules = {}
     self.pre_sg_rules = None
     # List of security group member ips for ports residing on this host
     self.sg_members = collections.defaultdict(
         lambda: collections.defaultdict(list))
     self.pre_sg_members = None
     self.enable_ipset = cfg.CONF.SECURITYGROUP.enable_ipset
     self._enabled_netfilter_for_bridges = False
     self.updated_rule_sg_ids = set()
     self.updated_sg_members = set()
     self.devices_with_updated_sg_members = collections.defaultdict(list)
Ejemplo n.º 6
0
 def test_disabled_non_exists(self):
     mo = self.useFixture(lib_fixtures.OpenFixture(self.proc_path,
                                                   '1')).mock_open
     self.mock_exists.return_value = False
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertFalse(enabled)
     self.assertFalse(mo.called)
Ejemplo n.º 7
0
 def __init__(self, namespace=None):
     self.iptables = iptables_manager.IptablesManager(
         state_less=True,
         use_ipv6=ipv6_utils.is_enabled_and_bind_by_default(),
         namespace=namespace)
     # TODO(majopela, shihanzhang): refactor out ipset to a separate
     # driver composed over this one
     self.ipset = ipset_manager.IpsetManager(namespace=namespace)
     # list of port which has security group
     self.filtered_ports = {}
     self.unfiltered_ports = {}
     self.trusted_ports = []
     self.ipconntrack = ip_conntrack.get_conntrack(
         self.iptables.get_rules_for_table,
         self.filtered_ports,
         self.unfiltered_ports,
         namespace=namespace,
         zone_per_port=self.CONNTRACK_ZONE_PER_PORT)
     self._add_fallback_chain_v4v6()
     self._defer_apply = False
     self._pre_defer_filtered_ports = None
     self._pre_defer_unfiltered_ports = None
     # List of security group rules for ports residing on this host
     self.sg_rules = {}
     self.pre_sg_rules = None
     # List of security group member ips for ports residing on this host
     self.sg_members = collections.defaultdict(
         lambda: collections.defaultdict(list))
     self.pre_sg_members = None
     self.enable_ipset = cfg.CONF.SECURITYGROUP.enable_ipset
     self.updated_rule_sg_ids = set()
     self.updated_sg_members = set()
     self.devices_with_updated_sg_members = collections.defaultdict(list)
Ejemplo n.º 8
0
 def initialize(self):
     LOG.info("Initializing Linux bridge QoS extension")
     if self.agent_api:
         self.iptables_manager = self.agent_api.get_iptables_manager()
     if not self.iptables_manager:
         # If agent_api can't provide iptables_manager, it can be
         # created here for extension needs
         self.iptables_manager = iptables_manager.IptablesManager(
             state_less=True,
             use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     self.iptables_manager.initialize_mangle_table()
Ejemplo n.º 9
0
 def initialize(self):
     LOG.info("Initializing Linux bridge QoS extension")
     if self.agent_api:
         self.iptables_manager = self.agent_api.get_iptables_manager()
     if not self.iptables_manager:
         # If agent_api can't provide iptables_manager, it can be
         # created here for extension needs
         self.iptables_manager = iptables_manager.IptablesManager(
             state_less=True,
             use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     self.iptables_manager.initialize_mangle_table()
Ejemplo n.º 10
0
 def __init__(self, conf, router):
     self.conf = conf
     self.id = router['id']
     self.router = router
     # TODO(cbrandily): deduplicate ns_name generation in metering/l3
     self.ns_name = NS_PREFIX + self.id
     self.iptables_manager = iptables_manager.IptablesManager(
         namespace=self.ns_name,
         binary_name=WRAP_NAME,
         state_less=True,
         use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
     self.metering_labels = {}
Ejemplo n.º 11
0
 def __init__(self, conf, router):
     self.conf = conf
     self.id = router["id"]
     self.router = router
     # TODO(cbrandily): deduplicate ns_name generation in metering/l3
     self.ns_name = NS_PREFIX + self.id
     self.iptables_manager = iptables_manager.IptablesManager(
         namespace=self.ns_name,
         binary_name=WRAP_NAME,
         state_less=True,
         use_ipv6=ipv6_utils.is_enabled_and_bind_by_default(),
     )
     self.metering_labels = {}
Ejemplo n.º 12
0
    def create_iptables_managers(self):
        """Creates iptables managers if the are not already created

        Returns True if any manager is created
        """

        created = False

        if self.router['distributed'] and self.snat_iptables_manager is None:
            # If distributed routers then we need to apply the
            # metering agent label rules in the snat namespace as well.
            snat_ns_name = dvr_snat_ns.SnatNamespace.get_snat_ns_name(self.id)
            # Check for namespace existence before we assign the
            # snat_iptables_manager
            if ip_lib.network_namespace_exists(snat_ns_name):
                self.snat_iptables_manager = iptables_manager.IptablesManager(
                    namespace=snat_ns_name,
                    binary_name=WRAP_NAME,
                    state_less=True,
                    use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())

                created = True

        if self.iptables_manager is None:
            # Check of namespace existence before we assign the
            # iptables_manager
            # NOTE(Swami): If distributed routers, all external traffic on a
            # compute node will flow through the rfp interface in the router
            # namespace.
            if ip_lib.network_namespace_exists(self.ns_name):
                self.iptables_manager = iptables_manager.IptablesManager(
                    namespace=self.ns_name,
                    binary_name=WRAP_NAME,
                    state_less=True,
                    use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())

                created = True

        return created
Ejemplo n.º 13
0
 def test_disabled(self):
     self.useFixture(tools.OpenFixture(self.proc_path, '1'))
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertFalse(enabled)
Ejemplo n.º 14
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf,
            resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the list of service plugins from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.neutron_service_plugins = (
                    self.plugin_rpc.get_service_plugin_list(self.context))
            except oslo_messaging.RemoteError as e:
                with excutils.save_and_reraise_exception() as ctx:
                    ctx.reraise = False
                    LOG.warning(_LW('l3-agent cannot check service plugins '
                                    'enabled at the neutron server when '
                                    'startup due to RPC error. It happens '
                                    'when the server does not support this '
                                    'RPC API. If the error is '
                                    'UnsupportedVersion you can ignore this '
                                    'warning. Detail message: %s'), e)
                self.neutron_service_plugins = None
            except oslo_messaging.MessagingTimeout as e:
                with excutils.save_and_reraise_exception() as ctx:
                    ctx.reraise = False
                    LOG.warning(_LW('l3-agent cannot contact neutron server '
                                    'to retrieve service plugins enabled. '
                                    'Check connectivity to neutron server. '
                                    'Retrying... '
                                    'Detailed message: %(msg)s.'), {'msg': e})
                    continue
            break

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf,
            self.driver,
            self.metadata_driver)

        self._queue = queue.RouterProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update,
                                      self.conf)
Ejemplo n.º 15
0
 def test_enabled(self):
     self.useFixture(lib_fixtures.OpenFixture(self.proc_path, '0'))
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertTrue(enabled)
Ejemplo n.º 16
0
 def disable_ipv6(self):
     if not ipv6_utils.is_enabled_and_bind_by_default():
         return
     sysctl_name = re.sub(r'\.', '/', self.name)
     cmd = ['net.ipv6.conf.%s.disable_ipv6=1' % sysctl_name]
     return sysctl(cmd, namespace=self.namespace)
Ejemplo n.º 17
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf, resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the list of service plugins from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.neutron_service_plugins = (
                    self.plugin_rpc.get_service_plugin_list(self.context))
            except oslo_messaging.RemoteError as e:
                with excutils.save_and_reraise_exception() as ctx:
                    ctx.reraise = False
                    LOG.warning(
                        _LW('l3-agent cannot check service plugins '
                            'enabled at the neutron server when '
                            'startup due to RPC error. It happens '
                            'when the server does not support this '
                            'RPC API. If the error is '
                            'UnsupportedVersion you can ignore this '
                            'warning. Detail message: %s'), e)
                self.neutron_service_plugins = None
            except oslo_messaging.MessagingTimeout as e:
                with excutils.save_and_reraise_exception() as ctx:
                    ctx.reraise = False
                    LOG.warning(
                        _LW('l3-agent cannot contact neutron server '
                            'to retrieve service plugins enabled. '
                            'Check connectivity to neutron server. '
                            'Retrying... '
                            'Detailed message: %(msg)s.'), {'msg': e})
                    continue
            break

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf, self.driver, self.metadata_driver)

        self._queue = queue.RouterProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update, self.conf)
Ejemplo n.º 18
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf,
            resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the list of service plugins from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.neutron_service_plugins = (
                    self.plugin_rpc.get_service_plugin_list(self.context))
            except oslo_messaging.MessagingTimeout as e:
                LOG.warning('l3-agent cannot contact neutron server '
                            'to retrieve service plugins enabled. '
                            'Check connectivity to neutron server. '
                            'Retrying... '
                            'Detailed message: %(msg)s.', {'msg': e})
                continue
            break

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf,
            self.driver,
            self.metadata_driver)

        self._queue = queue.ResourceProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update,
                                      self.conf)

        # Consume network updates to trigger router resync
        consumers = [[topics.NETWORK, topics.UPDATE]]
        agent_rpc.create_consumers([self], topics.AGENT, consumers)

        # We set HA network port status to DOWN to let l2 agent update it
        # to ACTIVE after wiring. This allows us to spawn keepalived only
        # when l2 agent finished wiring the port.
        try:
            self.plugin_rpc.update_all_ha_network_port_statuses(self.context)
        except Exception:
            LOG.exception('update_all_ha_network_port_statuses failed')
Ejemplo n.º 19
0
class L3HATestCase(framework.L3AgentTestFramework):
    def test_ha_router_update_floatingip_statuses(self):
        self._test_update_floatingip_statuses(
            self.generate_router_info(enable_ha=True))

    def test_keepalived_state_change_notification(self):
        enqueue_mock = mock.patch.object(self.agent,
                                         'enqueue_state_change').start()
        router_info = self.generate_router_info(enable_ha=True)
        router = self.manage_router(self.agent, router_info)
        common_utils.wait_until_true(lambda: router.ha_state == 'master')

        self.fail_ha_router(router)
        common_utils.wait_until_true(lambda: router.ha_state == 'backup')

        common_utils.wait_until_true(lambda: enqueue_mock.call_count == 3)
        calls = [args[0] for args in enqueue_mock.call_args_list]
        self.assertEqual((router.router_id, 'backup'), calls[0])
        self.assertEqual((router.router_id, 'master'), calls[1])
        self.assertEqual((router.router_id, 'backup'), calls[2])

    def _expected_rpc_report(self, expected):
        calls = (args[0][1] for args in
                 self.agent.plugin_rpc.update_ha_routers_states.call_args_list)

        # Get the last state reported for each router
        actual_router_states = {}
        for call in calls:
            for router_id, state in call.items():
                actual_router_states[router_id] = state

        return actual_router_states == expected

    def test_keepalived_state_change_bulk_rpc(self):
        router_info = self.generate_router_info(enable_ha=True)
        router1 = self.manage_router(self.agent, router_info)
        self.fail_ha_router(router1)
        router_info = self.generate_router_info(enable_ha=True)
        router2 = self.manage_router(self.agent, router_info)

        common_utils.wait_until_true(lambda: router1.ha_state == 'backup')
        common_utils.wait_until_true(lambda: router2.ha_state == 'master')
        common_utils.wait_until_true(
            lambda: self._expected_rpc_report({
                router1.router_id: 'standby',
                router2.router_id: 'active'
            }))

    def test_ha_router_lifecycle(self):
        router_info = self._router_lifecycle(enable_ha=True)
        # ensure everything was cleaned up
        self._router_lifecycle(enable_ha=True, router_info=router_info)

    def test_conntrack_disassociate_fip_ha_router(self):
        self._test_conntrack_disassociate_fip(ha=True)

    def test_ipv6_ha_router_lifecycle(self):
        self._router_lifecycle(enable_ha=True, ip_version=6)

    def test_ipv6_ha_router_lifecycle_with_no_gw_subnet(self):
        self.agent.conf.set_override('ipv6_gateway', 'fe80::f816:3eff:fe2e:1')
        self._router_lifecycle(enable_ha=True,
                               ip_version=6,
                               v6_ext_gw_with_sub=False)

    def test_ipv6_ha_router_lifecycle_with_no_gw_subnet_for_router_advts(self):
        # Verify that router gw interface is configured to receive Router
        # Advts from upstream router when no external gateway is configured.
        self._router_lifecycle(enable_ha=True,
                               dual_stack=True,
                               v6_ext_gw_with_sub=False)

    def _test_ipv6_router_advts_and_fwd_helper(self, state, enable_v6_gw,
                                               expected_ra,
                                               expected_forwarding):
        # Schedule router to l3 agent, and then add router gateway. Verify
        # that router gw interface is configured to receive Router Advts and
        # IPv6 forwarding is enabled.
        router_info = l3_test_common.prepare_router_data(enable_snat=True,
                                                         enable_ha=True,
                                                         dual_stack=True,
                                                         enable_gw=False)
        router = self.manage_router(self.agent, router_info)
        common_utils.wait_until_true(lambda: router.ha_state == 'master')
        if state == 'backup':
            self.fail_ha_router(router)
            common_utils.wait_until_true(lambda: router.ha_state == 'backup')
        _ext_dev_name, ex_port = l3_test_common.prepare_ext_gw_test(
            mock.Mock(), router, dual_stack=enable_v6_gw)
        router_info['gw_port'] = ex_port
        router.process()
        self._assert_ipv6_accept_ra(router, expected_ra)
        self._assert_ipv6_forwarding(router, expected_forwarding)

    @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
                          "IPv6 is not enabled")
    def test_ipv6_router_advts_and_fwd_after_router_state_change_master(self):
        # Check that RA and forwarding are enabled when there's no IPv6
        # gateway.
        self._test_ipv6_router_advts_and_fwd_helper('master',
                                                    enable_v6_gw=False,
                                                    expected_ra=True,
                                                    expected_forwarding=True)
        # Check that RA is disabled and forwarding is enabled when an IPv6
        # gateway is configured.
        self._test_ipv6_router_advts_and_fwd_helper('master',
                                                    enable_v6_gw=True,
                                                    expected_ra=False,
                                                    expected_forwarding=True)

    @testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
                          "IPv6 is not enabled")
    def test_ipv6_router_advts_and_fwd_after_router_state_change_backup(self):
        # Check that both RA and forwarding are disabled on backup instances
        self._test_ipv6_router_advts_and_fwd_helper('backup',
                                                    enable_v6_gw=False,
                                                    expected_ra=False,
                                                    expected_forwarding=False)
        self._test_ipv6_router_advts_and_fwd_helper('backup',
                                                    enable_v6_gw=True,
                                                    expected_ra=False,
                                                    expected_forwarding=False)

    def test_keepalived_configuration(self):
        router_info = self.generate_router_info(enable_ha=True)
        router = self.manage_router(self.agent, router_info)
        expected = self.get_expected_keepalive_configuration(router)

        self.assertEqual(expected,
                         router.keepalived_manager.get_conf_on_disk())

        # Add a new FIP and change the GW IP address
        router.router = copy.deepcopy(router.router)
        existing_fip = '19.4.4.2'
        new_fip = '19.4.4.3'
        self._add_fip(router, new_fip)
        subnet_id = framework._uuid()
        fixed_ips = [{
            'ip_address': '19.4.4.10',
            'prefixlen': 24,
            'subnet_id': subnet_id
        }]
        subnets = [{
            'id': subnet_id,
            'cidr': '19.4.4.0/24',
            'gateway_ip': '19.4.4.5'
        }]
        router.router['gw_port']['subnets'] = subnets
        router.router['gw_port']['fixed_ips'] = fixed_ips

        router.process()

        # Get the updated configuration and assert that both FIPs are in,
        # and that the GW IP address was updated.
        new_config = router.keepalived_manager.config.get_config_str()
        old_gw = '0.0.0.0/0 via 19.4.4.1'
        new_gw = '0.0.0.0/0 via 19.4.4.5'
        old_external_device_ip = '19.4.4.4'
        new_external_device_ip = '19.4.4.10'
        self.assertIn(existing_fip, new_config)
        self.assertIn(new_fip, new_config)
        self.assertNotIn(old_gw, new_config)
        self.assertIn(new_gw, new_config)
        external_port = router.get_ex_gw_port()
        external_device_name = router.get_external_device_name(
            external_port['id'])
        self.assertNotIn(
            '%s/24 dev %s' % (old_external_device_ip, external_device_name),
            new_config)
        self.assertIn(
            '%s/24 dev %s' % (new_external_device_ip, external_device_name),
            new_config)

    def test_ha_router_conf_on_restarted_agent(self):
        router_info = self.generate_router_info(enable_ha=True)
        router1 = self.manage_router(self.agent, router_info)
        self._add_fip(router1, '192.168.111.12')
        restarted_agent = neutron_l3_agent.L3NATAgentWithStateReport(
            self.agent.host, self.agent.conf)
        self.manage_router(restarted_agent, router1.router)
        common_utils.wait_until_true(
            lambda: self.floating_ips_configured(router1))
        self.assertIn(
            router1._get_primary_vip(),
            self._get_addresses_on_device(router1.ns_name,
                                          router1.get_ha_device_name()))

    def test_ha_router_ipv6_radvd_status(self):
        router_info = self.generate_router_info(ip_version=6, enable_ha=True)
        router1 = self.manage_router(self.agent, router_info)
        common_utils.wait_until_true(lambda: router1.ha_state == 'master')
        common_utils.wait_until_true(lambda: router1.radvd.enabled)

        def _check_lla_status(router, expected):
            internal_devices = router.router[constants.INTERFACE_KEY]
            for device in internal_devices:
                lladdr = ip_lib.get_ipv6_lladdr(device['mac_address'])
                exists = ip_lib.device_exists_with_ips_and_mac(
                    router.get_internal_device_name(device['id']), [lladdr],
                    device['mac_address'], router.ns_name)
                self.assertEqual(expected, exists)

        _check_lla_status(router1, True)

        device_name = router1.get_ha_device_name()
        ha_device = ip_lib.IPDevice(device_name, namespace=router1.ns_name)
        ha_device.link.set_down()

        common_utils.wait_until_true(lambda: router1.ha_state == 'backup')
        common_utils.wait_until_true(lambda: not router1.radvd.enabled,
                                     timeout=10)
        _check_lla_status(router1, False)

    def test_ha_router_process_ipv6_subnets_to_existing_port(self):
        router_info = self.generate_router_info(enable_ha=True, ip_version=6)
        router = self.manage_router(self.agent, router_info)

        def verify_ip_in_keepalived_config(router, iface):
            config = router.keepalived_manager.config.get_config_str()
            ip_cidrs = common_utils.fixed_ip_cidrs(iface['fixed_ips'])
            for ip_addr in ip_cidrs:
                self.assertIn(ip_addr, config)

        interface_id = router.router[constants.INTERFACE_KEY][0]['id']
        slaac = constants.IPV6_SLAAC
        slaac_mode = {'ra_mode': slaac, 'address_mode': slaac}

        # Add a second IPv6 subnet to the router internal interface.
        self._add_internal_interface_by_subnet(router.router,
                                               count=1,
                                               ip_version=6,
                                               ipv6_subnet_modes=[slaac_mode],
                                               interface_id=interface_id)
        router.process()
        common_utils.wait_until_true(lambda: router.ha_state == 'master')

        # Verify that router internal interface is present and is configured
        # with IP address from both the subnets.
        internal_iface = router.router[constants.INTERFACE_KEY][0]
        self.assertEqual(2, len(internal_iface['fixed_ips']))
        self._assert_internal_devices(router)

        # Verify that keepalived config is properly updated.
        verify_ip_in_keepalived_config(router, internal_iface)

        # Remove one subnet from the router internal iface
        interfaces = copy.deepcopy(
            router.router.get(constants.INTERFACE_KEY, []))
        fixed_ips, subnets = [], []
        fixed_ips.append(interfaces[0]['fixed_ips'][0])
        subnets.append(interfaces[0]['subnets'][0])
        interfaces[0].update({'fixed_ips': fixed_ips, 'subnets': subnets})
        router.router[constants.INTERFACE_KEY] = interfaces
        router.process()

        # Verify that router internal interface has a single ipaddress
        internal_iface = router.router[constants.INTERFACE_KEY][0]
        self.assertEqual(1, len(internal_iface['fixed_ips']))
        self._assert_internal_devices(router)

        # Verify that keepalived config is properly updated.
        verify_ip_in_keepalived_config(router, internal_iface)

    def test_delete_external_gateway_on_standby_router(self):
        router_info = self.generate_router_info(enable_ha=True)
        router = self.manage_router(self.agent, router_info)

        self.fail_ha_router(router)
        common_utils.wait_until_true(lambda: router.ha_state == 'backup')

        # The purpose of the test is to simply make sure no exception is raised
        port = router.get_ex_gw_port()
        interface_name = router.get_external_device_name(port['id'])
        router.external_gateway_removed(port, interface_name)

    def test_removing_floatingip_immediately(self):
        router_info = self.generate_router_info(enable_ha=True)
        router = self.manage_router(self.agent, router_info)
        ex_gw_port = router.get_ex_gw_port()
        interface_name = router.get_external_device_interface_name(ex_gw_port)
        common_utils.wait_until_true(lambda: router.ha_state == 'master')
        self._add_fip(router, '172.168.1.20', fixed_address='10.0.0.3')
        router.process()
        router.router[constants.FLOATINGIP_KEY] = []
        # The purpose of the test is to simply make sure no exception is raised
        # Because router.process will consume the FloatingIpSetupException,
        # call the configure_fip_addresses directly here
        router.configure_fip_addresses(interface_name)

    def test_ha_port_status_update(self):
        router_info = self.generate_router_info(enable_ha=True)
        router_info[constants.HA_INTERFACE_KEY]['status'] = (
            constants.PORT_STATUS_DOWN)
        router1 = self.manage_router(self.agent, router_info)
        common_utils.wait_until_true(lambda: router1.ha_state == 'backup')

        router1.router[constants.HA_INTERFACE_KEY]['status'] = (
            constants.PORT_STATUS_ACTIVE)
        self.agent._process_updated_router(router1.router)
        common_utils.wait_until_true(lambda: router1.ha_state == 'master')

    def test_ha_router_namespace_has_ip_nonlocal_bind_disabled(self):
        router_info = self.generate_router_info(enable_ha=True)
        router = self.manage_router(self.agent, router_info)
        try:
            ip_nonlocal_bind_value = ip_lib.get_ip_nonlocal_bind(
                router.router_namespace.name)
        except RuntimeError as rte:
            stat_message = 'cannot stat /proc/sys/net/ipv4/ip_nonlocal_bind'
            if stat_message in str(rte):
                raise self.skipException(
                    "This kernel doesn't support %s in network namespaces." %
                    (ip_lib.IP_NONLOCAL_BIND))
            raise
        self.assertEqual(0, ip_nonlocal_bind_value)

    def test_ha_router_namespace_has_ipv6_forwarding_disabled(self):
        router_info = self.generate_router_info(enable_ha=True)
        router_info[constants.HA_INTERFACE_KEY]['status'] = (
            constants.PORT_STATUS_DOWN)
        router = self.manage_router(self.agent, router_info)
        external_port = router.get_ex_gw_port()
        external_device_name = router.get_external_device_name(
            external_port['id'])

        common_utils.wait_until_true(lambda: router.ha_state == 'backup')
        self.assertEqual(
            0,
            ip_lib.get_ipv6_forwarding(device=external_device_name,
                                       namespace=router.ns_name))

        router.router[constants.HA_INTERFACE_KEY]['status'] = (
            constants.PORT_STATUS_ACTIVE)
        self.agent._process_updated_router(router.router)
        common_utils.wait_until_true(lambda: router.ha_state == 'master')
        self.assertEqual(
            1,
            ip_lib.get_ipv6_forwarding(device=external_device_name,
                                       namespace=router.ns_name))
Ejemplo n.º 20
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf, resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the list of service plugins from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.neutron_service_plugins = (
                    self.plugin_rpc.get_service_plugin_list(self.context))
            except oslo_messaging.RemoteError as e:
                LOG.warning(
                    'l3-agent cannot check service plugins '
                    'enabled at the neutron server when '
                    'startup due to RPC error. It happens '
                    'when the server does not support this '
                    'RPC API. If the error is '
                    'UnsupportedVersion you can ignore this '
                    'warning. Detail message: %s', e)
                self.neutron_service_plugins = None
            except oslo_messaging.MessagingTimeout as e:
                LOG.warning(
                    'l3-agent cannot contact neutron server '
                    'to retrieve service plugins enabled. '
                    'Check connectivity to neutron server. '
                    'Retrying... '
                    'Detailed message: %(msg)s.', {'msg': e})
                continue
            break

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf, self.driver, self.metadata_driver)

        self._queue = queue.RouterProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update, self.conf)

        # Consume network updates to trigger router resync
        consumers = [[topics.NETWORK, topics.UPDATE]]
        agent_rpc.create_consumers([self], topics.AGENT, consumers)

        # We set HA network port status to DOWN to let l2 agent update it
        # to ACTIVE after wiring. This allows us to spawn keepalived only
        # when l2 agent finished wiring the port.
        try:
            self.plugin_rpc.update_all_ha_network_port_statuses(self.context)
        except Exception:
            LOG.exception('update_all_ha_network_port_statuses failed')
Ejemplo n.º 21
0
class TestWSGIServer(base.BaseTestCase):
    """WSGI server tests."""
    def test_start_random_port(self):
        server = wsgi.Server("test_random_port")
        server.start(None, 0, host="127.0.0.1")
        self.assertNotEqual(0, server.port)
        server.stop()
        server.wait()

    @mock.patch('oslo_service.service.ProcessLauncher')
    def test_start_multiple_workers(self, ProcessLauncher):
        launcher = ProcessLauncher.return_value

        server = wsgi.Server("test_multiple_processes")
        server.start(None, 0, host="127.0.0.1", workers=2)
        launcher.launch_service.assert_called_once_with(mock.ANY, workers=2)

        server.stop()
        launcher.stop.assert_called_once_with()

        server.wait()
        launcher.wait.assert_called_once_with()

    @testtools.skipIf(not ipv6_utils.is_enabled_and_bind_by_default(),
                      'IPv6 support disabled on host')
    def test_start_random_port_with_ipv6(self):
        server = wsgi.Server("test_random_port")
        server.start(None, 0, host="::1")
        self.assertEqual("::1", server.host)
        self.assertNotEqual(0, server.port)
        server.stop()
        server.wait()

    def test_ipv6_listen_called_with_scope(self):
        server = wsgi.Server("test_app")

        with mock.patch.object(wsgi.eventlet, 'listen') as mock_listen:
            with mock.patch.object(socket, 'getaddrinfo') as mock_get_addr:
                mock_get_addr.return_value = [
                    (socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP,
                     '', ('fe80::204:acff:fe96:da87%eth0', 1234, 0, 2))
                ]
                with mock.patch.object(server, 'pool') as mock_pool:
                    server.start(None,
                                 1234,
                                 host="fe80::204:acff:fe96:da87%eth0")

                    mock_get_addr.assert_called_once_with(
                        "fe80::204:acff:fe96:da87%eth0", 1234,
                        socket.AF_UNSPEC, socket.SOCK_STREAM)

                    mock_listen.assert_called_once_with(
                        ('fe80::204:acff:fe96:da87%eth0', 1234, 0, 2),
                        family=socket.AF_INET6,
                        backlog=cfg.CONF.backlog)

                    mock_pool.spawn.assert_has_calls([
                        mock.call(server._run, None,
                                  mock_listen.return_value.dup.return_value)
                    ])

    def test_app(self):
        greetings = b'Hello, World!!!'

        def hello_world(env, start_response):
            if env['PATH_INFO'] != '/':
                start_response('404 Not Found',
                               [('Content-Type', 'text/plain')])
                return ['Not Found\r\n']
            start_response('200 OK', [('Content-Type', 'text/plain')])
            return [greetings]

        server = wsgi.Server("test_app")
        server.start(hello_world, 0, host="127.0.0.1")

        response = open_no_proxy('http://127.0.0.1:%d/' % server.port)

        self.assertEqual(greetings, response.read())

        server.stop()

    def test_disable_ssl(self):
        CONF.set_default('use_ssl', True)

        greetings = 'Hello, World!!!'

        def hello_world(env, start_response):
            if env['PATH_INFO'] != '/':
                start_response('404 Not Found',
                               [('Content-Type', 'text/plain')])
                return ['Not Found\r\n']
            start_response('200 OK', [('Content-Type', 'text/plain')])
            return [greetings]

        server = wsgi.Server("test_app", disable_ssl=True)
        server.start(hello_world, 0, host="127.0.0.1")

        response = open_no_proxy('http://127.0.0.1:%d/' % server.port)

        self.assertEqual(greetings.encode('utf-8'), response.read())

        server.stop()

    @mock.patch.object(wsgi, 'eventlet')
    def test__run(self, eventlet_mock):
        server = wsgi.Server('test')
        server._run("app", "socket")
        eventlet_mock.wsgi.server.assert_called_once_with(
            'socket',
            'app',
            max_size=server.num_threads,
            log=mock.ANY,
            keepalive=CONF.wsgi_keep_alive,
            log_format=CONF.wsgi_log_format,
            socket_timeout=server.client_socket_timeout)
Ejemplo n.º 22
0
 def test_memoize(self):
     mo = self.useFixture(tools.OpenFixture(self.proc_path, '0')).mock_open
     ipv6_utils.is_enabled_and_bind_by_default()
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertTrue(enabled)
     mo.assert_called_once_with(self.proc_path, 'r')
Ejemplo n.º 23
0
 def test_disabled_non_exists(self):
     mo = self.useFixture(tools.OpenFixture(self.proc_path, '1')).mock_open
     self.mock_exists.return_value = False
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertFalse(enabled)
     self.assertFalse(mo.called)
Ejemplo n.º 24
0
 def disable_ipv6(self):
     if not ipv6_utils.is_enabled_and_bind_by_default():
         return
     sysctl_name = re.sub(r'\.', '/', self.name)
     cmd = ['net.ipv6.conf.%s.disable_ipv6=1' % sysctl_name]
     return sysctl(cmd, namespace=self.namespace)
Ejemplo n.º 25
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf,
            resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the HA router count from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.ha_router_count = int(
                    self.plugin_rpc.get_host_ha_router_count(self.context))
            except oslo_messaging.MessagingTimeout as e:
                LOG.warning('l3-agent cannot contact neutron server '
                            'to retrieve HA router count. '
                            'Check connectivity to neutron server. '
                            'Retrying... '
                            'Detailed message: %(msg)s.', {'msg': e})
                continue
            break
        LOG.info("Agent HA routers count %s", self.ha_router_count)

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf,
            self.driver,
            self.metadata_driver)

        # L3 agent router processing green pool
        self._pool = eventlet.GreenPool(size=ROUTER_PROCESS_GREENLET_MIN)
        self._queue = queue.ResourceProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update,
                                      self.conf)

        # Consume network updates to trigger router resync
        consumers = [[topics.NETWORK, topics.UPDATE]]
        agent_rpc.create_consumers([self], topics.AGENT, consumers)

        self._check_ha_router_process_status()
Ejemplo n.º 26
0
    def __init__(self, host, conf=None):
        if conf:
            self.conf = conf
        else:
            self.conf = cfg.CONF
        self.router_info = {}

        self._check_config_params()

        self.process_monitor = external_process.ProcessMonitor(
            config=self.conf,
            resource_type='router')

        self.driver = common_utils.load_interface_driver(self.conf)

        self._context = n_context.get_admin_context_without_session()
        self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host)
        self.fullsync = True
        self.sync_routers_chunk_size = SYNC_ROUTERS_MAX_CHUNK_SIZE

        # Get the list of service plugins from Neutron Server
        # This is the first place where we contact neutron-server on startup
        # so retry in case its not ready to respond.
        while True:
            try:
                self.neutron_service_plugins = (
                    self.plugin_rpc.get_service_plugin_list(self.context))
            except oslo_messaging.MessagingTimeout as e:
                LOG.warning('l3-agent cannot contact neutron server '
                            'to retrieve service plugins enabled. '
                            'Check connectivity to neutron server. '
                            'Retrying... '
                            'Detailed message: %(msg)s.', {'msg': e})
                continue
            break

        self.init_extension_manager(self.plugin_rpc)

        self.metadata_driver = None
        if self.conf.enable_metadata_proxy:
            self.metadata_driver = metadata_driver.MetadataDriver(self)

        self.namespaces_manager = namespace_manager.NamespaceManager(
            self.conf,
            self.driver,
            self.metadata_driver)

        self._queue = queue.RouterProcessingQueue()
        super(L3NATAgent, self).__init__(host=self.conf.host)

        self.target_ex_net_id = None
        self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()

        self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
                                      self.driver,
                                      self.plugin_rpc.process_prefix_update,
                                      self.create_pd_router_update,
                                      self.conf)

        # Consume network updates to trigger router resync
        consumers = [[topics.NETWORK, topics.UPDATE]]
        agent_rpc.create_consumers([self], topics.AGENT, consumers)
Ejemplo n.º 27
0
 def test_disabled(self):
     self.useFixture(tools.OpenFixture(self.proc_path, '1'))
     enabled = ipv6_utils.is_enabled_and_bind_by_default()
     self.assertFalse(enabled)