예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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'])
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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'])
예제 #8
0
 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)
예제 #9
0
 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)
예제 #10
0
 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)
예제 #11
0
 def _get_device_ipv6_lladdr(self, device):
     lladdr_cidr = ip_lib.get_ipv6_lladdr(device.link.address)
     return utils.cidr_to_ip(lladdr_cidr)
예제 #12
0
 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)