def _test_create_rtr_2_fip_link(self, dev_exists, addr_exists, IPDevice, IPWrapper): ri = mock.Mock() ri.router_id = _uuid() ri.rtr_fip_subnet = None ri.ns_name = mock.sentinel.router_ns ri.get_ex_gw_port.return_value = {'mtu': 2000} fip_ns_name = self.fip_ns.get_name() self.fip_ns.local_subnets = allocator = mock.Mock() pair = lla.LinkLocalAddressPair('169.254.31.28/31') allocator.allocate.return_value = pair addr_pair = pair.get_pair() ip_wrapper = IPWrapper() ip_wrapper.add_veth.return_value = (IPDevice(), IPDevice()) device = IPDevice() device.exists.return_value = dev_exists device.addr.list.return_value = addr_exists ri._get_snat_idx = mock.Mock() self.fip_ns._add_rtr_ext_route_rule_to_route_table = mock.Mock() self.fip_ns.create_rtr_2_fip_link(ri) if not dev_exists: ip_wrapper.add_veth.assert_called_with(device.name, device.name, fip_ns_name) self.assertEqual(2, device.link.set_up.call_count) device.link.set_mtu.assert_called_with(2000) self.assertEqual(2, device.link.set_mtu.call_count) if not addr_exists: expected = [ mock.call(str(addr_pair[0]), add_broadcast=False), mock.call(str(addr_pair[1]), add_broadcast=False) ] device.addr.add.assert_has_calls(expected) self.assertEqual(2, device.addr.add.call_count) expected = [ mock.call(n_utils.cidr_to_ip(addr_pair[1]), mock.ANY), mock.call(n_utils.cidr_to_ip(addr_pair[0]), mock.ANY) ] device.neigh.add.assert_has_calls(expected) self.assertEqual(2, device.neigh.add.call_count) expected_calls = [ mock.call('169.254.31.29', table=16), mock.call(self.lladdr) ] self.assertEqual(expected_calls, device.route.add_gateway.mock_calls) self.assertTrue( self.fip_ns._add_rtr_ext_route_rule_to_route_table.called)
def _test_create_rtr_2_fip_link(self, dev_exists, addr_exists, IPDevice, IPWrapper): ri = mock.Mock() ri.router_id = _uuid() ri.rtr_fip_subnet = None ri.ns_name = mock.sentinel.router_ns ri.get_ex_gw_port.return_value = {'mtu': 2000} rtr_2_fip_name = self.fip_ns.get_rtr_ext_device_name(ri.router_id) fip_2_rtr_name = self.fip_ns.get_int_device_name(ri.router_id) fip_ns_name = self.fip_ns.get_name() self.fip_ns.local_subnets = allocator = mock.Mock() pair = lla.LinkLocalAddressPair('169.254.31.28/31') allocator.allocate.return_value = pair addr_pair = pair.get_pair() ip_wrapper = IPWrapper() ip_wrapper.add_veth.return_value = (IPDevice(), IPDevice()) device = IPDevice() device.exists.return_value = dev_exists device.addr.list.return_value = addr_exists ri._get_snat_idx = mock.Mock() self.fip_ns._add_rtr_ext_route_rule_to_route_table = mock.Mock() self.fip_ns.create_rtr_2_fip_link(ri) if not dev_exists: ip_wrapper.add_veth.assert_called_with(rtr_2_fip_name, fip_2_rtr_name, fip_ns_name) self.assertEqual(2, device.link.set_up.call_count) device.link.set_mtu.assert_called_with(2000) self.assertEqual(2, device.link.set_mtu.call_count) if not addr_exists: expected = [mock.call(str(addr_pair[0]), add_broadcast=False), mock.call(str(addr_pair[1]), add_broadcast=False)] device.addr.add.assert_has_calls(expected) self.assertEqual(2, device.addr.add.call_count) expected = [mock.call(n_utils.cidr_to_ip(addr_pair[1]), mock.ANY), mock.call(n_utils.cidr_to_ip(addr_pair[0]), mock.ANY)] device.neigh.add.assert_has_calls(expected) self.assertEqual(2, device.neigh.add.call_count) device.route.add_gateway.assert_called_once_with( '169.254.31.29', table=16) self.assertTrue( self.fip_ns._add_rtr_ext_route_rule_to_route_table.called)
def _update_interface_ip_details(self, destination, source, ips, gateway): dst_device = self.ip.device(destination) src_device = self.ip.device(source) # Append IP's to bridge if necessary if ips: for ip in ips: # If bridge ip address already exists, then don't add # otherwise will report error to = utils.cidr_to_ip(ip['cidr']) if not dst_device.addr.list(to=to): dst_device.addr.add(cidr=ip['cidr']) if gateway: # Ensure that the gateway can be updated by changing the metric metric = 100 ip_version = utils.get_ip_version(gateway['cidr']) if gateway['metric'] != ip_lib.IP_ROUTE_METRIC_DEFAULT[ip_version]: metric = gateway['metric'] - 1 dst_device.route.add_gateway(gateway=gateway['via'], metric=metric) src_device.route.delete_gateway(gateway=gateway['via']) # Remove IP's from interface if ips: for ip in ips: src_device.addr.delete(cidr=ip['cidr'])
def _update_interface_ip_details(self, destination, source, ips, gateway): dst_device = self.ip.device(destination) src_device = self.ip.device(source) # Append IP's to bridge if necessary if ips: for ip in ips: # If bridge ip address already exists, then don't add # otherwise will report error to = utils.cidr_to_ip(ip['cidr']) if not dst_device.addr.list(to=to): dst_device.addr.add(cidr=ip['cidr']) if gateway: # Ensure that the gateway can be updated by changing the metric metric = 100 if 'metric' in gateway: metric = gateway['metric'] - 1 dst_device.route.add_gateway(gateway=gateway['gateway'], metric=metric) src_device.route.delete_gateway(gateway=gateway['gateway']) # Remove IP's from interface if ips: for ip in ips: src_device.addr.delete(cidr=ip['cidr'])
def create_rtr_2_fip_link(self, ri): """Create interface between router and Floating IP namespace.""" LOG.debug("Create FIP link interfaces for router %s", ri.router_id) fip_ns_name = self.get_name() # add link local IP to interface if ri.rtr_fip_subnet is None: ri.rtr_fip_subnet = self.local_subnets.allocate(ri.router_id) rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair() rtr_2_fip_dev = self.get_rtr_2_fip_device(ri) fip_2_rtr_dev = self.get_fip_2_rtr_device(ri) if not rtr_2_fip_dev.exists(): ip_wrapper = ip_lib.IPWrapper(namespace=ri.ns_name) rtr_2_fip_dev, fip_2_rtr_dev = ip_wrapper.add_veth( rtr_2_fip_dev.name, fip_2_rtr_dev.name, fip_ns_name) rtr_2_fip_dev.link.set_up() fip_2_rtr_dev.link.set_up() mtu = ri.get_ex_gw_port().get('mtu') if mtu: rtr_2_fip_dev.link.set_mtu(mtu) fip_2_rtr_dev.link.set_mtu(mtu) self._add_cidr_to_device(rtr_2_fip_dev, str(rtr_2_fip)) self._add_cidr_to_device(fip_2_rtr_dev, str(fip_2_rtr)) # Add permanant ARP entries on each side of veth pair rtr_2_fip_dev.neigh.add(common_utils.cidr_to_ip(fip_2_rtr), fip_2_rtr_dev.link.address) fip_2_rtr_dev.neigh.add(common_utils.cidr_to_ip(rtr_2_fip), rtr_2_fip_dev.link.address) self._add_rtr_ext_route_rule_to_route_table(ri, fip_2_rtr, fip_2_rtr_dev.name) # add default route for the link local interface rtr_2_fip_dev.route.add_gateway(str(fip_2_rtr.ip), table=FIP_RT_TBL) v6_gateway = common_utils.cidr_to_ip( ip_lib.get_ipv6_lladdr(fip_2_rtr_dev.link.address)) rtr_2_fip_dev.route.add_gateway(v6_gateway)
def create_rtr_2_fip_link(self, ri): """Create interface between router and Floating IP namespace.""" LOG.debug("Create 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() # add link local IP to interface if ri.rtr_fip_subnet is None: ri.rtr_fip_subnet = self.local_subnets.allocate(ri.router_id) rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair() rtr_2_fip_dev = ip_lib.IPDevice(rtr_2_fip_name, namespace=ri.ns_name) fip_2_rtr_dev = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) if not rtr_2_fip_dev.exists(): ip_wrapper = ip_lib.IPWrapper(namespace=ri.ns_name) rtr_2_fip_dev, fip_2_rtr_dev = ip_wrapper.add_veth(rtr_2_fip_name, fip_2_rtr_name, fip_ns_name) rtr_2_fip_dev.link.set_up() fip_2_rtr_dev.link.set_up() mtu = ri.get_ex_gw_port().get('mtu') if mtu: rtr_2_fip_dev.link.set_mtu(mtu) fip_2_rtr_dev.link.set_mtu(mtu) self._add_cidr_to_device(rtr_2_fip_dev, str(rtr_2_fip)) self._add_cidr_to_device(fip_2_rtr_dev, str(fip_2_rtr)) # Add permanant ARP entries on each side of veth pair rtr_2_fip_dev.neigh.add(common_utils.cidr_to_ip(fip_2_rtr), fip_2_rtr_dev.link.address) fip_2_rtr_dev.neigh.add(common_utils.cidr_to_ip(rtr_2_fip), rtr_2_fip_dev.link.address) self._add_rtr_ext_route_rule_to_route_table(ri, fip_2_rtr, fip_2_rtr_name) # add default route for the link local interface rtr_2_fip_dev.route.add_gateway(str(fip_2_rtr.ip), table=FIP_RT_TBL)
def _set_subnet_arp_info(self, subnet): """Set ARP info retrieved from Plugin for existing ports.""" # TODO(Carl) Can we eliminate the need to make this RPC while # processing a router. subnet_ports = self.agent.get_ports_by_subnet(subnet['id']) ignored_device_owners = ( lib_constants.ROUTER_INTERFACE_OWNERS + tuple(common_utils.get_dvr_allowed_address_pair_device_owners())) device, device_exists = self.get_arp_related_dev(subnet['id']) subnet_ip_version = netaddr.IPNetwork(subnet['cidr']).version for p in subnet_ports: if p['device_owner'] not in ignored_device_owners: for fixed_ip in p['fixed_ips']: if fixed_ip['subnet_id'] == subnet['id']: self._update_arp_entry(fixed_ip['ip_address'], p['mac_address'], subnet['id'], 'add', device=device, device_exists=device_exists) for allowed_address_pair in p.get('allowed_address_pairs', []): if ('/' not in str(allowed_address_pair['ip_address']) or common_utils.is_cidr_host( allowed_address_pair['ip_address'])): ip_address = common_utils.cidr_to_ip( allowed_address_pair['ip_address']) ip_version = common_utils.get_ip_version(ip_address) if ip_version == subnet_ip_version: self._update_arp_entry( ip_address, allowed_address_pair['mac_address'], subnet['id'], 'add', device=device, device_exists=device_exists) # subnet_ports does not have snat port if the port is still unbound # by the time this function is called. So ensure to add arp entry # for snat port if port details are updated in router info. for p in self.get_snat_interfaces(): for fixed_ip in p['fixed_ips']: if fixed_ip['subnet_id'] == subnet['id']: self._update_arp_entry(fixed_ip['ip_address'], p['mac_address'], subnet['id'], 'add', device=device, device_exists=device_exists) self._process_arp_cache_for_internal_port(subnet['id'])
def _add_cidr_to_device(self, device, ip_cidr): to = common_utils.cidr_to_ip(ip_cidr) if not device.addr.list(to=to): device.addr.add(ip_cidr, add_broadcast=False)
def remove_floating_ip(self, device, ip_cidr): self._remove_vip(ip_cidr) to = common_utils.cidr_to_ip(ip_cidr) if device.addr.list(to=to): super(HaRouter, self).remove_floating_ip(device, ip_cidr)
def _get_device_ipv6_lladdr(self, device): lladdr_cidr = ip_lib.get_ipv6_lladdr(device.link.address) return utils.cidr_to_ip(lladdr_cidr)