Example #1
0
 def _delete_interface_routing_rule_in_router_ns(self, router_port):
     for subnet in router_port['subnets']:
         rtr_port_cidr = subnet['cidr']
         ip_lib.delete_ip_rule(self.ns_name,
                               ip=rtr_port_cidr,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=dvr_fip_ns.FAST_PATH_EXIT_PR)
Example #2
0
 def _remove_floating_ip_rule(self, floating_ip):
     if floating_ip in self.floating_ips_dict:
         fixed_ip, rule_pr = self.floating_ips_dict[floating_ip]
         ip_lib.delete_ip_rule(self.ns_name, ip=fixed_ip,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=int(str(rule_pr)))
         self.fip_ns.deallocate_rule_priority(floating_ip)
Example #3
0
 def _remove_floating_ip_rule(self, floating_ip):
     if floating_ip in self.floating_ips_dict:
         fixed_ip, rule_pr = self.floating_ips_dict[floating_ip]
         ip_lib.delete_ip_rule(self.ns_name, ip=fixed_ip,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=int(str(rule_pr)))
         self.fip_ns.deallocate_rule_priority(floating_ip)
 def _remove_floating_ip_rule(self, floating_ip):
     if floating_ip in self.floating_ips_dict:
         fixed_ip, rule_pr = self.floating_ips_dict[floating_ip]
         ip_lib.delete_ip_rule(self.ns_name, ip=fixed_ip,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=int(str(rule_pr)))
         self.fip_ns.deallocate_rule_priority(floating_ip)
     else:
         LOG.error("Unable to find necessary information to complete "
                   "removal of floating ip rules for %s - will require "
                   "manual cleanup (see LP 1891673 for details).",
                   floating_ip)
Example #5
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)
                    # 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]
                    ip_lib.delete_ip_rule(fip_ns_name,
                                          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)
Example #6
0
 def _remove_floating_ip_rule(self, floating_ip):
     if floating_ip in self.floating_ips_dict:
         fixed_ip, rule_pr = self.floating_ips_dict[floating_ip]
         ip_lib.delete_ip_rule(self.ns_name,
                               ip=fixed_ip,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=int(str(rule_pr)))
         self.fip_ns.deallocate_rule_priority(floating_ip)
     else:
         LOG.error(
             'Floating IP %s not stored in this agent. Because of '
             'the initilization method "_load_used_fip_information", '
             'all floating IPs should be memoized in the local '
             'memory.', floating_ip)
Example #7
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)
                    # 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]
                    ip_lib.delete_ip_rule(fip_ns_name, 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)
Example #8
0
 def _stale_ip_rule_cleanup(self, namespace, ns_ipd, ip_version):
     ip_rules_list = ip_lib.list_ip_rules(namespace, ip_version)
     snat_table_list = []
     for ip_rule in ip_rules_list:
         snat_table = ip_rule['table']
         priority = ip_rule['priority']
         if snat_table in ['local', 'default', 'main']:
             continue
         if (ip_version == lib_constants.IP_VERSION_4 and
             snat_table in range(dvr_fip_ns.FIP_PR_START,
                                 dvr_fip_ns.FIP_PR_END)):
             continue
         gateway_cidr = ip_rule['from']
         ip_lib.delete_ip_rule(namespace, ip=gateway_cidr, table=snat_table,
                               priority=priority)
         snat_table_list.append(snat_table)
     for tb in snat_table_list:
         ns_ipd.route.flush(ip_version, table=tb)
Example #9
0
 def _stale_ip_rule_cleanup(self, namespace, ns_ipd, ip_version):
     ip_rules_list = ip_lib.list_ip_rules(namespace, ip_version)
     snat_table_list = []
     for ip_rule in ip_rules_list:
         snat_table = ip_rule['table']
         priority = ip_rule['priority']
         if snat_table in ['local', 'default', 'main']:
             continue
         if (ip_version == lib_constants.IP_VERSION_4 and
             snat_table in range(dvr_fip_ns.FIP_PR_START,
                                 dvr_fip_ns.FIP_PR_END)):
             continue
         gateway_cidr = ip_rule['from']
         ip_lib.delete_ip_rule(namespace, ip=gateway_cidr, table=snat_table,
                               priority=priority)
         snat_table_list.append(snat_table)
     for tb in snat_table_list:
         ns_ipd.route.flush(ip_version, table=tb)
Example #10
0
    def _cleanup_unused_fip_ip_rules(self):
        if not self.router_namespace.exists():
            # It could be a new router, thus the namespace is not created yet.
            return

        ip_rules = ip_lib.list_ip_rules(self.ns_name,
                                        lib_constants.IP_VERSION_4)
        ip_rules = [
            ipr for ipr in ip_rules if ipr['table'] == dvr_fip_ns.FIP_RT_TBL
        ]
        for ip_rule in ip_rules:
            for fixed_ip, rule_pr in self.floating_ips_dict.values():
                if (ip_rule['from'] == fixed_ip
                        and ip_rule['priority'] == rule_pr):
                    break
            else:
                ip_lib.delete_ip_rule(self.ns_name,
                                      ip_rule['from'],
                                      table=dvr_fip_ns.FIP_RT_TBL,
                                      priority=ip_rule['priority'])
Example #11
0
 def _snat_redirect_modify(self, gateway, sn_port, sn_int, is_add):
     """Adds or removes rules and routes for SNAT redirection."""
     cmd = ['net.ipv4.conf.%s.send_redirects=0' % sn_int]
     try:
         ns_ipd = ip_lib.IPDevice(sn_int, namespace=self.ns_name)
         for port_fixed_ip in sn_port['fixed_ips']:
             # Iterate and find the gateway IP address matching
             # the 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)
                         ip_lib.add_ip_rule(namespace=self.ns_name,
                                            ip=sn_port_cidr,
                                            table=snat_idx,
                                            priority=snat_idx)
                         ip_lib.sysctl(cmd, namespace=self.ns_name)
                     else:
                         self._delete_gateway_device_if_exists(ns_ipd,
                                                               gw_ip_addr,
                                                               snat_idx)
                         ip_lib.delete_ip_rule(self.ns_name,
                                               ip=sn_port_cidr,
                                               table=snat_idx,
                                               priority=snat_idx)
     except Exception:
         if is_add:
             exc = 'DVR: error adding redirection logic'
         else:
             exc = ('DVR: snat remove failed to clear the rule '
                    'and device')
         LOG.exception(exc)
Example #12
0
 def _snat_redirect_modify(self, gateway, sn_port, sn_int, is_add):
     """Adds or removes rules and routes for SNAT redirection."""
     cmd = ['net.ipv4.conf.%s.send_redirects=0' % sn_int]
     try:
         ns_ipd = ip_lib.IPDevice(sn_int, namespace=self.ns_name)
         for port_fixed_ip in sn_port['fixed_ips']:
             # Iterate and find the gateway IP address matching
             # the 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)
                         ip_lib.add_ip_rule(namespace=self.ns_name,
                                            ip=sn_port_cidr,
                                            table=snat_idx,
                                            priority=snat_idx)
                         ip_lib.sysctl(cmd, namespace=self.ns_name)
                     else:
                         self._delete_gateway_device_if_exists(ns_ipd,
                                                               gw_ip_addr,
                                                               snat_idx)
                         ip_lib.delete_ip_rule(self.ns_name,
                                               ip=sn_port_cidr,
                                               table=snat_idx,
                                               priority=snat_idx)
     except Exception:
         if is_add:
             exc = 'DVR: error adding redirection logic'
         else:
             exc = ('DVR: snat remove failed to clear the rule '
                    'and device')
         LOG.exception(exc)
Example #13
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',
            }]
        }

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

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

            for rule in test_case:
                ip_lib.delete_ip_rule(device.namespace,
                                      table=TABLE,
                                      priority=PRIORITY,
                                      **rule)

            rules = priv_ip_lib.list_ip_rules(device.namespace, ip_version)
            for expected_rule in expected_rules[ip_version]:
                self.assertNotIn(expected_rule, rules)
Example #14
0
 def _delete_interface_routing_rule_in_router_ns(self, router_port):
     for subnet in router_port['subnets']:
         rtr_port_cidr = subnet['cidr']
         ip_lib.delete_ip_rule(self.ns_name, ip=rtr_port_cidr,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=dvr_fip_ns.FAST_PATH_EXIT_PR)
Example #15
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',
                }
            ]
        }

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

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

            for rule in test_case:
                ip_lib.delete_ip_rule(device.namespace, table=TABLE,
                                      priority=PRIORITY, **rule)

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