def _get_fixed_ip_rule_priority(self, namespace, fip):
     iprule = ip_lib.IPRule(namespace)
     lines = iprule.rule._as_root([4], ['show']).splitlines()
     for line in lines:
         if fip in line:
             info = iprule.rule._parse_line(4, line)
             return info['priority']
Exemple #2
0
 def floating_ip_added_dist(self, fip, fip_cidr):
     """Add floating IP to FIP namespace."""
     floating_ip = fip['floating_ip_address']
     fixed_ip = fip['fixed_ip_address']
     rule_pr = self.fip_ns.allocate_rule_priority(floating_ip)
     self.floating_ips_dict[floating_ip] = rule_pr
     fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
     ip_rule = ip_lib.IPRule(namespace=self.ns_name)
     ip_rule.rule.add(ip=fixed_ip,
                      table=dvr_fip_ns.FIP_RT_TBL,
                      priority=rule_pr)
     #Add routing rule in fip namespace
     fip_ns_name = self.fip_ns.get_name()
     if self.rtr_fip_subnet is None:
         self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
             self.router_id)
     rtr_2_fip, _ = self.rtr_fip_subnet.get_pair()
     device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)
     device.route.add_route(fip_cidr, str(rtr_2_fip.ip))
     interface_name = (self.fip_ns.get_ext_device_name(
         self.fip_ns.agent_gateway_port['id']))
     ip_lib.send_ip_addr_adv_notif(fip_ns_name, interface_name, floating_ip,
                                   self.agent_conf)
     # update internal structures
     self.dist_fip_count = self.dist_fip_count + 1
Exemple #3
0
    def floating_ip_removed_dist(self, fip_cidr):
        """Remove floating IP from FIP namespace."""
        floating_ip = fip_cidr.split('/')[0]
        rtr_2_fip_name = self.fip_ns.get_rtr_ext_device_name(self.router_id)
        fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
        if self.rtr_fip_subnet is None:
            self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
                self.router_id)

        rtr_2_fip, fip_2_rtr = self.rtr_fip_subnet.get_pair()
        fip_ns_name = self.fip_ns.get_name()
        if floating_ip in self.floating_ips_dict:
            rule_pr = self.floating_ips_dict[floating_ip]
            ip_rule = ip_lib.IPRule(namespace=self.ns_name)
            ip_rule.rule.delete(ip=floating_ip,
                                table=dvr_fip_ns.FIP_RT_TBL,
                                priority=rule_pr)
            self.fip_ns.deallocate_rule_priority(floating_ip)
            #TODO(rajeev): Handle else case - exception/log?

        device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)

        device.route.delete_route(fip_cidr, str(rtr_2_fip.ip))
        # check if this is the last FIP for this router
        self.dist_fip_count = self.dist_fip_count - 1
        if self.dist_fip_count == 0:
            #remove default route entry
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=self.ns_name)
            ns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            device.route.delete_gateway(str(fip_2_rtr.ip),
                                        table=dvr_fip_ns.FIP_RT_TBL)
            self.fip_ns.local_subnets.release(self.router_id)
            self.rtr_fip_subnet = None
            ns_ip.del_veth(fip_2_rtr_name)
            self.fip_ns.unsubscribe(self.router_id)
Exemple #4
0
 def _delete_interface_routing_rule_in_router_ns(self, router_port):
     ip_rule = ip_lib.IPRule(namespace=self.ns_name)
     for subnet in router_port['subnets']:
         rtr_port_cidr = subnet['cidr']
         ip_rule.rule.delete(ip=rtr_port_cidr,
                             table=dvr_fip_ns.FIP_RT_TBL,
                             priority=dvr_fip_ns.FAST_PATH_EXIT_PR)
    def test_dvr_router_gateway_redirect_cleanup_on_agent_restart(self):
        """Test to validate the router namespace gateway redirect rule cleanup.

        This test checks for the non existence of the gateway redirect
        rules in the router namespace after the agent restarts while the
        gateway is removed for the router.
        """
        self.agent.conf.agent_mode = 'dvr_snat'
        router_info = self.generate_dvr_router_info()
        router1 = self.manage_router(self.agent, router_info)
        self._assert_snat_namespace_exists(router1)
        self.assertTrue(self._namespace_exists(router1.ns_name))
        restarted_agent = neutron_l3_agent.L3NATAgentWithStateReport(
            self.agent.host, self.agent.conf)
        router1.router['gw_port'] = ""
        router1.router['gw_port_host'] = ""
        router1.router['external_gateway_info'] = ""
        restarted_router = self.manage_router(restarted_agent, router1.router)
        self.assertTrue(self._namespace_exists(restarted_router.ns_name))
        ns_ipr = ip_lib.IPRule(namespace=router1.ns_name)
        ip4_rules_list = ns_ipr.rule.list_rules(lib_constants.IP_VERSION_4)
        ip6_rules_list = ns_ipr.rule.list_rules(lib_constants.IP_VERSION_6)
        # Just make sure the basic set of rules are there in the router
        # namespace
        self.assertEqual(3, len(ip4_rules_list))
        self.assertEqual(2, len(ip6_rules_list))
Exemple #6
0
    def _add_rtr_ext_route_rule_to_route_table(self, ri, fip_2_rtr,
                                               fip_2_rtr_name):
        """Creates external route table and adds routing rules."""
        # TODO(Swami): Rename the _get_snat_idx function to some
        # generic name that can be used for SNAT and FIP
        rt_tbl_index = ri._get_snat_idx(fip_2_rtr)
        interface_name = self.get_ext_device_name(
            self.agent_gateway_port['id'])
        try:
            # The lock is used to make sure another thread doesn't call to
            # update the gateway route before we are done initializing things.
            with self._fip_port_lock(interface_name):
                self._update_gateway_route(self.agent_gateway_port,
                                           interface_name,
                                           tbl_index=rt_tbl_index)
        except Exception:
            # If an exception occurs at this point, then it is
            # good to unsubscribe this external network so that
            # the next call will trigger the interface to be plugged.
            # We reraise the exception in order to resync the router.
            with excutils.save_and_reraise_exception():
                self.unsubscribe(self.agent_gateway_port['network_id'])
                # Reset the fip count so that the create_rtr_2_fip_link
                # is called again in this context
                ri.dist_fip_count = 0
                LOG.exception(_LE('DVR: Gateway update route in FIP namespace '
                                  'failed'))

        # Now add the filter match rule for the table.
        ip_rule = ip_lib.IPRule(namespace=self.get_name())
        ip_rule.rule.add(ip=str(fip_2_rtr.ip),
                         iif=fip_2_rtr_name,
                         table=rt_tbl_index,
                         priority=rt_tbl_index)
 def test_dvr_gateway_move_does_not_remove_redirect_rules(self):
     """Test to validate snat redirect rules not cleared with snat move."""
     self.agent.conf.agent_mode = 'dvr_snat'
     router_info = self.generate_dvr_router_info(enable_snat=True)
     router_info[l3_constants.FLOATINGIP_KEY] = []
     router_info[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = []
     router1 = self.manage_router(self.agent, router_info)
     router1.router['gw_port_host'] = ""
     self.agent._process_updated_router(router1.router)
     router_updated = self.agent.router_info[router1.router['id']]
     self.assertTrue(self._namespace_exists(router_updated.ns_name))
     ns_ipr = ip_lib.IPRule(namespace=router1.ns_name)
     ip4_rules_list = ns_ipr.rule.list_rules(l3_constants.IP_VERSION_4)
     self.assertEqual(5, len(ip4_rules_list))
     # IPRule list should have 5 entries.
     # Three entries from 'default', 'main' and 'local' table.
     # The remaining 2 is for the two router interfaces(csnat ports).
     default_rules_list_count = 0
     interface_rules_list_count = 0
     for ip_rule in ip4_rules_list:
         tbl_index = ip_rule['table']
         if tbl_index in ['local', 'default', 'main']:
             default_rules_list_count = default_rules_list_count + 1
         else:
             interface_rules_list_count = interface_rules_list_count + 1
     self.assertEqual(3, default_rules_list_count)
     self.assertEqual(2, interface_rules_list_count)
Exemple #8
0
 def _add_floating_ip_rule(self, floating_ip, fixed_ip):
     rule_pr = self.fip_ns.allocate_rule_priority(floating_ip)
     self.floating_ips_dict[floating_ip] = rule_pr
     ip_rule = ip_lib.IPRule(namespace=self.ns_name)
     ip_rule.rule.add(ip=fixed_ip,
                      table=dvr_fip_ns.FIP_RT_TBL,
                      priority=rule_pr)
Exemple #9
0
 def _remove_floating_ip_rule(self, floating_ip):
     if floating_ip in self.floating_ips_dict:
         rule_pr = self.floating_ips_dict[floating_ip]
         ip_rule = ip_lib.IPRule(namespace=self.ns_name)
         ip_rule.rule.delete(ip=floating_ip,
                             table=dvr_fip_ns.FIP_RT_TBL,
                             priority=rule_pr)
         self.fip_ns.deallocate_rule_priority(floating_ip)
    def _fixed_ip_rule_exists(self, namespace, ip):
        iprule = ip_lib.IPRule(namespace)
        lines = iprule.rule._as_root([4], ['show']).splitlines()
        for line in lines:
            if ip in line:
                info = iprule.rule._parse_line(4, line)
                if info['from'] == ip:
                    return True

        return False
Exemple #11
0
 def get_fip_table_indexes(self, ip_version):
     ns_ipr = ip_lib.IPRule(namespace=self.get_name())
     ip_rules_list = ns_ipr.rule.list_rules(ip_version)
     tbl_index_list = []
     for ip_rule in ip_rules_list:
         tbl_index = ip_rule['table']
         if tbl_index in ['local', 'default', 'main']:
             continue
         tbl_index_list.append(tbl_index)
     return tbl_index_list
Exemple #12
0
    def floating_ip_removed_dist(self, fip_cidr):
        """Remove floating IP from FIP namespace."""
        floating_ip = fip_cidr.split('/')[0]
        rtr_2_fip_name = self.fip_ns.get_rtr_ext_device_name(self.router_id)
        fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
        if self.rtr_fip_subnet is None:
            self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
                self.router_id)

        rtr_2_fip, fip_2_rtr = self.rtr_fip_subnet.get_pair()
        fip_ns_name = self.fip_ns.get_name()
        if floating_ip in self.floating_ips_dict:
            rule_pr = self.floating_ips_dict[floating_ip]
            ip_rule = ip_lib.IPRule(namespace=self.ns_name)
            ip_rule.rule.delete(ip=floating_ip,
                                table=dvr_fip_ns.FIP_RT_TBL,
                                priority=rule_pr)
            self.fip_ns.deallocate_rule_priority(floating_ip)
            #TODO(rajeev): Handle else case - exception/log?

        device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)

        device.route.delete_route(fip_cidr, str(rtr_2_fip.ip))
        # check if this is the last FIP for this router
        self.dist_fip_count = self.dist_fip_count - 1
        if self.dist_fip_count == 0:
            #remove default route entry
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=self.ns_name)
            ns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            device.route.delete_gateway(str(fip_2_rtr.ip),
                                        table=dvr_fip_ns.FIP_RT_TBL)
            self.fip_ns.local_subnets.release(self.router_id)
            self.rtr_fip_subnet = None
            ns_ip.del_veth(fip_2_rtr_name)
            is_last = self.fip_ns.unsubscribe(self.router_id)
            if is_last:
                # TODO(Carl) I can't help but think that another router could
                # come in and want to start using this namespace while this is
                # destroying it.  The two could end up conflicting on
                # creating/destroying interfaces and such.  I think I'd like a
                # semaphore to sync creation/deletion of this namespace.

                # NOTE (Swami): Since we are deleting the namespace here we
                # should be able to delete the floatingip agent gateway port
                # for the provided external net since we don't need it anymore.
                if self.fip_ns.agent_gateway_port:
                    LOG.debug(
                        'Removed last floatingip, so requesting the '
                        'server to delete Floatingip Agent Gateway port:'
                        '%s', self.fip_ns.agent_gateway_port)
                    self.agent.plugin_rpc.delete_agent_gateway_port(
                        self.agent.context,
                        self.fip_ns.agent_gateway_port['network_id'])
                self.fip_ns.delete()
                self.fip_ns = None
Exemple #13
0
 def _snat_redirect_remove(self, gateway, sn_port, sn_int):
     """Removes rules and routes for SNAT redirection."""
     try:
         ip_cidr = sn_port['ip_cidr']
         snat_idx = self._get_snat_idx(ip_cidr)
         ns_ipr = ip_lib.IPRule(namespace=self.ns_name)
         ns_ipd = ip_lib.IPDevice(sn_int, namespace=self.ns_name)
         ns_ipd.route.delete_gateway(gateway, table=snat_idx)
         ns_ipr.rule.delete(ip_cidr, snat_idx, snat_idx)
     except Exception:
         LOG.exception(_LE('DVR: removed snat failed'))
Exemple #14
0
    def test_metadata_proxy_exit_clear_ip_rule(self):
        df_metadata_service.environment_setup()
        ip_rule = ip_lib.IPRule().rule
        rules = ip_rule.list_rules(4)
        rules_source = [r['from'] for r in rules if 'from' in r]
        self.assertIn(self.metadata_ip, rules_source)

        df_metadata_service.environment_destroy()
        self.isTornDown = True
        rules = ip_rule.list_rules(4)
        rules_source = [r['from'] for r in rules if 'from' in r]
        self.assertNotIn(self.metadata_ip, rules_source)
Exemple #15
0
    def delete_rtr_2_fip_link(self, ri):
        """Delete the interface between router and FloatingIP namespace."""
        LOG.debug("Delete FIP link interfaces for router: %s", ri.router_id)
        rtr_2_fip_name = self.get_rtr_ext_device_name(ri.router_id)
        fip_2_rtr_name = self.get_int_device_name(ri.router_id)
        fip_ns_name = self.get_name()

        # remove default route entry
        if ri.rtr_fip_subnet is None:
            # see if there is a local subnet in the cache
            ri.rtr_fip_subnet = self.local_subnets.lookup(ri.router_id)

        if ri.rtr_fip_subnet:
            rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair()
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=ri.ns_name)
            if device.exists():
                device.route.delete_gateway(str(fip_2_rtr.ip),
                                            table=FIP_RT_TBL)
            if self.agent_gateway_port:
                interface_name = self.get_ext_device_name(
                    self.agent_gateway_port['id'])
                fg_device = ip_lib.IPDevice(
                    interface_name, namespace=fip_ns_name)
                if fg_device.exists():
                    # Remove the fip namespace rules and routes associated to
                    # fpr interface route table.
                    tbl_index = ri._get_snat_idx(fip_2_rtr)
                    fip_rt_rule = ip_lib.IPRule(namespace=fip_ns_name)
                    # Flush the table
                    fg_device.route.flush(lib_constants.IP_VERSION_4,
                                          table=tbl_index)
                    fg_device.route.flush(lib_constants.IP_VERSION_6,
                                          table=tbl_index)
                    # Remove the rule lookup
                    # /0 addresses for IPv4 and IPv6 are used to pass
                    # IP protocol version information based on a
                    # link-local address IP version. Using any of those
                    # is equivalent to using 'from all' for iproute2.
                    rule_ip = lib_constants.IP_ANY[fip_2_rtr.ip.version]
                    fip_rt_rule.rule.delete(ip=rule_ip,
                                            iif=fip_2_rtr_name,
                                            table=tbl_index,
                                            priority=tbl_index)
            self.local_subnets.release(ri.router_id)
            ri.rtr_fip_subnet = None

        # Check for namespace before deleting the device
        if not self.destroyed:
            fns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            if fns_ip.device(fip_2_rtr_name).exists():
                fns_ip.del_veth(fip_2_rtr_name)
Exemple #16
0
    def floating_ip_removed_dist(self, fip_cidr):
        """Remove floating IP from FIP namespace."""
        floating_ip = fip_cidr.split('/')[0]
        rtr_2_fip_name = self.fip_ns.get_rtr_ext_device_name(self.router_id)
        fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
        if self.rtr_fip_subnet is None:
            self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
                self.router_id)

        rtr_2_fip, fip_2_rtr = self.rtr_fip_subnet.get_pair()
        fip_ns_name = self.fip_ns.get_name()
        self._remove_floating_ip_rule(floating_ip)

        device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)

        device.route.delete_route(fip_cidr, str(rtr_2_fip.ip))
        # check if this is the last FIP for this router
        self.dist_fip_count = self.dist_fip_count - 1
        if self.dist_fip_count == 0:
            #remove default route entry
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=self.ns_name)
            ns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            device.route.delete_gateway(str(fip_2_rtr.ip),
                                        table=dvr_fip_ns.FIP_RT_TBL)
            if self.fip_ns.agent_gateway_port:
                interface_name = self.fip_ns.get_ext_device_name(
                    self.fip_ns.agent_gateway_port['id'])
                fg_device = ip_lib.IPDevice(interface_name,
                                            namespace=fip_ns_name)
                if fg_device.exists():
                    # Remove the fip namespace rules and routes associated to
                    # fpr interface route table.
                    tbl_index = self._get_snat_idx(fip_2_rtr)
                    fip_rt_rule = ip_lib.IPRule(namespace=fip_ns_name)
                    # Flush the table
                    fg_device.route.flush(lib_constants.IP_VERSION_4,
                                          table=tbl_index)
                    fg_device.route.flush(lib_constants.IP_VERSION_6,
                                          table=tbl_index)
                    # Remove the rule lookup
                    # IP is ignored in delete, but we still require it
                    # for getting the ip_version.
                    fip_rt_rule.rule.delete(ip=fip_2_rtr.ip,
                                            iif=fip_2_rtr_name,
                                            table=tbl_index,
                                            priority=tbl_index)
            self.fip_ns.local_subnets.release(self.router_id)
            self.rtr_fip_subnet = None
            ns_ip.del_veth(fip_2_rtr_name)
Exemple #17
0
    def delete_rtr_2_fip_link(self, ri):
        """Delete the interface between router and FloatingIP namespace."""
        LOG.debug("Delete FIP link interfaces for router: %s", ri.router_id)
        rtr_2_fip_name = self.get_rtr_ext_device_name(ri.router_id)
        fip_2_rtr_name = self.get_int_device_name(ri.router_id)
        fip_ns_name = self.get_name()

        # remove default route entry
        if ri.rtr_fip_subnet is None:
            # see if there is a local subnet in the cache
            ri.rtr_fip_subnet = self.local_subnets.lookup(ri.router_id)

        if ri.rtr_fip_subnet:
            rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair()
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=ri.ns_name)
            if device.exists():
                device.route.delete_gateway(str(fip_2_rtr.ip),
                                            table=FIP_RT_TBL)
            if self.agent_gateway_port:
                interface_name = self.get_ext_device_name(
                    self.agent_gateway_port['id'])
                fg_device = ip_lib.IPDevice(interface_name,
                                            namespace=fip_ns_name)
                if fg_device.exists():
                    # Remove the fip namespace rules and routes associated to
                    # fpr interface route table.
                    tbl_index = ri._get_snat_idx(fip_2_rtr)
                    fip_rt_rule = ip_lib.IPRule(namespace=fip_ns_name)
                    # Flush the table
                    fg_device.route.flush(lib_constants.IP_VERSION_4,
                                          table=tbl_index)
                    fg_device.route.flush(lib_constants.IP_VERSION_6,
                                          table=tbl_index)
                    # Remove the rule lookup
                    # IP is ignored in delete, but we still require it
                    # for getting the ip_version.
                    fip_rt_rule.rule.delete(ip=fip_2_rtr.ip,
                                            iif=fip_2_rtr_name,
                                            table=tbl_index,
                                            priority=tbl_index)
            self.local_subnets.release(ri.router_id)
            ri.rtr_fip_subnet = None

        # Check for namespace before deleting the device
        if not self.destroyed:
            fns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            if fns_ip.device(fip_2_rtr_name).exists():
                fns_ip.del_veth(fip_2_rtr_name)
Exemple #18
0
 def _snat_redirect_add(self, gateway, sn_port, sn_int):
     """Adds rules and routes for SNAT redirection."""
     try:
         ip_cidr = sn_port['ip_cidr']
         snat_idx = self._get_snat_idx(ip_cidr)
         ns_ipr = ip_lib.IPRule(namespace=self.ns_name)
         ns_ipd = ip_lib.IPDevice(sn_int, namespace=self.ns_name)
         ns_ipwrapr = ip_lib.IPWrapper(namespace=self.ns_name)
         ns_ipd.route.add_gateway(gateway, table=snat_idx)
         ns_ipr.rule.add(ip_cidr, snat_idx, snat_idx)
         ns_ipwrapr.netns.execute([
             'sysctl', '-w',
             'net.ipv4.conf.%s.'
             'send_redirects=0' % sn_int
         ])
     except Exception:
         LOG.exception(_LE('DVR: error adding redirection logic'))
    def floating_ip_removed_dist(self, fip_cidr):
        """Remove floating IP from FIP namespace."""
        floating_ip = fip_cidr.split('/')[0]
        rtr_2_fip_name = self.fip_ns.get_rtr_ext_device_name(self.router_id)
        fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
        if self.rtr_fip_subnet is None:
            self.rtr_fip_subnet = self.fip_ns.local_subnets.allocate(
                self.router_id)

        rtr_2_fip, fip_2_rtr = self.rtr_fip_subnet.get_pair()
        fip_ns_name = self.fip_ns.get_name()
        if floating_ip in self.floating_ips_dict:
            rule_pr = self.floating_ips_dict[floating_ip]
            ip_rule = ip_lib.IPRule(namespace=self.ns_name)
            ip_rule.rule.delete(ip=floating_ip,
                                table=dvr_fip_ns.FIP_RT_TBL,
                                priority=rule_pr)
            self.fip_ns.deallocate_rule_priority(rule_pr)
            #TODO(rajeev): Handle else case - exception/log?

        device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)

        device.route.delete_route(fip_cidr, str(rtr_2_fip.ip))
        # check if this is the last FIP for this router
        self.dist_fip_count = self.dist_fip_count - 1
        if self.dist_fip_count == 0:
            #remove default route entry
            device = ip_lib.IPDevice(rtr_2_fip_name, namespace=self.ns_name)
            ns_ip = ip_lib.IPWrapper(namespace=fip_ns_name)
            device.route.delete_gateway(str(fip_2_rtr.ip),
                                        table=dvr_fip_ns.FIP_RT_TBL)
            self.fip_ns.local_subnets.release(self.router_id)
            self.rtr_fip_subnet = None
            ns_ip.del_veth(fip_2_rtr_name)
            is_last = self.fip_ns.unsubscribe(self.router_id)
            if is_last:
                # TODO(Carl) I can't help but think that another router could
                # come in and want to start using this namespace while this is
                # destroying it.  The two could end up conflicting on
                # creating/destroying interfaces and such.  I think I'd like a
                # semaphore to sync creation/deletion of this namespace.
                self.fip_ns.delete()
                self.fip_ns = None
Exemple #20
0
 def _snat_redirect_modify(self, gateway, sn_port, sn_int, is_add):
     """Adds or removes rules and routes for SNAT redirection."""
     try:
         ns_ipr = ip_lib.IPRule(namespace=self.ns_name)
         ns_ipd = ip_lib.IPDevice(sn_int, namespace=self.ns_name)
         if is_add:
             ns_ipwrapr = ip_lib.IPWrapper(namespace=self.ns_name)
         for port_fixed_ip in sn_port['fixed_ips']:
             # Find the first gateway IP address matching this IP version
             port_ip_addr = port_fixed_ip['ip_address']
             port_ip_vers = netaddr.IPAddress(port_ip_addr).version
             for gw_fixed_ip in gateway['fixed_ips']:
                 gw_ip_addr = gw_fixed_ip['ip_address']
                 if netaddr.IPAddress(gw_ip_addr).version == port_ip_vers:
                     sn_port_cidr = common_utils.ip_to_cidr(
                         port_ip_addr, port_fixed_ip['prefixlen'])
                     snat_idx = self._get_snat_idx(sn_port_cidr)
                     if is_add:
                         ns_ipd.route.add_gateway(gw_ip_addr,
                                                  table=snat_idx)
                         ns_ipr.rule.add(ip=sn_port_cidr,
                                         table=snat_idx,
                                         priority=snat_idx)
                         ns_ipwrapr.netns.execute([
                             'sysctl', '-w',
                             'net.ipv4.conf.%s.send_redirects=0' % sn_int
                         ])
                     else:
                         self._delete_gateway_device_if_exists(
                             ns_ipd, gw_ip_addr, snat_idx)
                         ns_ipr.rule.delete(ip=sn_port_cidr,
                                            table=snat_idx,
                                            priority=snat_idx)
                     break
     except Exception:
         if is_add:
             exc = _LE('DVR: error adding redirection logic')
         else:
             exc = _LE('DVR: snat remove failed to clear the rule '
                       'and device')
         LOG.exception(exc)
Exemple #21
0
 def setUp(self):
     super(ListIpRulesTestCase, self).setUp()
     self.namespace = 'ns_test-' + uuidutils.generate_uuid()
     self.ns = priv_ip_lib.create_netns(self.namespace)
     self.ip_rule = ip_lib.IPRule(namespace=self.namespace)
     self.addCleanup(self._remove_ns)
Exemple #22
0
 def gateway_redirect_cleanup(self, rtr_interface):
     ns_ipr = ip_lib.IPRule(namespace=self.ns_name)
     ns_ipd = ip_lib.IPDevice(rtr_interface, namespace=self.ns_name)
     self._stale_ip_rule_cleanup(ns_ipr, ns_ipd, lib_constants.IP_VERSION_4)
     self._stale_ip_rule_cleanup(ns_ipr, ns_ipd, lib_constants.IP_VERSION_6)
Exemple #23
0
    def test_rules_lifecycle(self):
        PRIORITY = 32768
        TABLE = 16
        attr = self.generate_device_details()
        device = self.manage_device(attr)

        test_cases = {
            constants.IP_VERSION_4: [
                {
                    'ip': '1.1.1.1',
                    'to': '8.8.8.0/24'
                },
                {
                    'ip': '1.1.1.1',
                    'iif': device.name,
                    'to': '7.7.7.0/24'
                }
            ],
            constants.IP_VERSION_6: [
                {
                    'ip': 'abcd::1',
                    'to': '1234::/64'
                },
                {
                    'ip': 'abcd::1',
                    'iif': device.name,
                    'to': '4567::/64'
                }
            ]
        }
        expected_rules = {
            constants.IP_VERSION_4: [
                {
                    'from': '1.1.1.1',
                    'to': '8.8.8.0/24',
                    'priority': str(PRIORITY),
                    'table': str(TABLE),
                    'type': 'unicast'
                }, {
                    'from': '0.0.0.0/0',
                    'to': '7.7.7.0/24',
                    'iif': device.name,
                    'priority': str(PRIORITY),
                    'table': str(TABLE),
                    'type': 'unicast'
                }
            ],
            constants.IP_VERSION_6: [
                {
                    'from': 'abcd::1',
                    'to': '1234::/64',
                    'priority': str(PRIORITY),
                    'table': str(TABLE),
                    'type': 'unicast'
                },
                {
                    'from': '::/0',
                    'to': '4567::/64',
                    'iif': device.name,
                    'priority': str(PRIORITY),
                    'table': str(TABLE),
                    'type': 'unicast',
                }
            ]
        }

        ip_rule = ip_lib.IPRule(namespace=device.namespace)
        for ip_version, test_case in test_cases.items():
            for rule in test_case:
                ip_rule.rule.add(table=TABLE, priority=PRIORITY, **rule)

            rules = ip_lib.list_ip_rules(ip_rule.namespace, ip_version)
            for expected_rule in expected_rules[ip_version]:
                self.assertIn(expected_rule, rules)

            for rule in test_case:
                ip_rule.rule.delete(table=TABLE, priority=PRIORITY, **rule)

            rules = priv_ip_lib.list_ip_rules(ip_rule.namespace, ip_version)
            for expected_rule in expected_rules[ip_version]:
                self.assertNotIn(expected_rule, rules)