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)
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)
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)
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)
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)
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)
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'])
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)
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)
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)