Example #1
0
    def test_north_south_traffic(self):
        # This function creates an external network which is connected to
        # central_external_bridge and spawns an external_vm on it.
        # The external_vm is configured with the gateway_ip (both v4 & v6
        # addresses) of external subnet. Later, it creates a tenant router,
        # a tenant network and two tenant subnets (v4 and v6). The tenant
        # router is associated with tenant network and external network to
        # provide north-south connectivity to the VMs.
        # We validate the following in this testcase.
        # 1. SNAT support: using ping from tenant VM to external_vm
        # 2. Floating IP support: using ping from external_vm to VM floating ip
        # 3. IPv6 ext connectivity: using ping6 from tenant vm to external_vm.
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        external_vm = self.useFixture(
            machine_fixtures.FakeMachine(
                self.environment.central_external_bridge,
                common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24)))
        # Create an IPv6 subnet in the external network
        v6network = self.useFixture(
            ip_network.ExclusiveIPNetwork(
                "2001:db8:1234::1", "2001:db8:1234::10", "64")).network
        ext_v6sub = self.safe_client.create_subnet(
            tenant_id, ext_net['id'], v6network)

        router = self.safe_client.create_router(tenant_id,
                                                external_network=ext_net['id'])

        # Configure the gateway_ip of external v6subnet on the external_vm.
        external_vm.ipv6_cidr = common_utils.ip_to_cidr(
            ext_v6sub['gateway_ip'], 64)

        # Configure an IPv6 downstream route to the v6Address of router gw port
        for fixed_ip in router['external_gateway_info']['external_fixed_ips']:
            if netaddr.IPNetwork(fixed_ip['ip_address']).version == 6:
                external_vm.set_default_gateway(fixed_ip['ip_address'])

        vm = self._create_net_subnet_and_vm(
            tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'],
            self.environment.hosts[1], router)

        # ping external vm to test snat
        vm.block_until_ping(external_vm.ip)

        fip = self.safe_client.create_floatingip(
            tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id'])

        # ping floating ip from external vm
        external_vm.block_until_ping(fip['floating_ip_address'])

        # Verify VM is able to reach the router interface.
        vm.block_until_ping(vm.gateway_ipv6)
        # Verify north-south connectivity using ping6 to external_vm.
        vm.block_until_ping(external_vm.ipv6)
Example #2
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(sn_port_cidr, snat_idx, snat_idx)
                         ns_ipwrapr.netns.execute(["sysctl", "-w", "net.ipv4.conf.%s.send_redirects=0" % sn_int])
                     else:
                         self._snat_delete_device_gateway(ns_ipd, gw_ip_addr, snat_idx)
                         ns_ipr.rule.delete(sn_port_cidr, snat_idx, snat_idx)
                     break
     except Exception:
         if is_add:
             exc = _LE("DVR: error adding redirection logic")
         else:
             exc = _LE("DVR: removed snat failed")
         LOG.exception(exc)
    def test_ha_router_restart_agents_no_packet_lost(self):
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        router = self.safe_client.create_router(tenant_id, ha=True,
                                                external_network=ext_net['id'])

        external_vm = self.useFixture(
            machine_fixtures.FakeMachine(
                self.environment.central_external_bridge,
                common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24)))

        common_utils.wait_until_true(
            lambda:
            len(self.client.list_l3_agent_hosting_routers(
                router['id'])['agents']) == 2,
            timeout=90)

        common_utils.wait_until_true(
            functools.partial(
                self._is_ha_router_active_on_one_agent,
                router['id']),
            timeout=90)

        router_ip = router['external_gateway_info'][
            'external_fixed_ips'][0]['ip_address']
        l3_agents = [host.agents['l3'] for host in self.environment.hosts]

        self._assert_ping_during_agents_restart(
            l3_agents, external_vm.namespace, [router_ip], count=60)
 def add(self, device, cidr):
     table = device.route.table(self.name)
     cidr = netaddr.IPNetwork(cidr)
     # Get the network cidr (e.g. 192.168.5.135/23 -> 192.168.4.0/23)
     net = utils.ip_to_cidr(cidr.network, cidr.prefixlen)
     self._keep.add((net, device.name))
     table.add_onlink_route(net)
Example #5
0
    def test_floating_ip_added_dist(self, mIPRule, mIPDevice, mock_adv_notif):
        router = mock.MagicMock()
        ri = self._create_router(router)
        ext_net_id = _uuid()
        subnet_id = _uuid()
        agent_gw_port = {'fixed_ips': [{'ip_address': '20.0.0.30',
                                        'prefixlen': 24,
                                        'subnet_id': subnet_id}],
                         'subnets': [{'id': subnet_id,
                                      'cidr': '20.0.0.0/24',
                                      'gateway_ip': '20.0.0.1'}],
                         'id': _uuid(),
                         'network_id': ext_net_id,
                         'mac_address': 'ca:fe:de:ad:be:ef'}

        fip = {'id': _uuid(),
               'host': HOSTNAME,
               'floating_ip_address': '15.1.2.3',
               'fixed_ip_address': '192.168.0.1',
               'floating_network_id': ext_net_id,
               'port_id': _uuid()}
        ri.fip_ns = mock.Mock()
        ri.fip_ns.agent_gateway_port = agent_gw_port
        ri.fip_ns.allocate_rule_priority.return_value = FIP_PRI
        ri.rtr_fip_subnet = lla.LinkLocalAddressPair('169.254.30.42/31')
        ri.dist_fip_count = 0
        ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
        ri.floating_ip_added_dist(fip, ip_cidr)
        mIPRule().rule.add.assert_called_with('192.168.0.1', 16, FIP_PRI)
        self.assertEqual(1, ri.dist_fip_count)
    def _ip_prefix_arg(self, direction, ip_prefix):

        if not(ip_prefix):
            return []

        args = ['-%s' % direction, '%s' % utils.ip_to_cidr(ip_prefix)]
        return args
Example #7
0
 def _list_floating_ip_cidrs(self):
     # Compute a list of addresses this router is supposed to have.
     # This avoids unnecessarily removing those addresses and
     # causing a momentarily network outage.
     floating_ips = self.get_floating_ips()
     return [common_utils.ip_to_cidr(ip['floating_ip_address'])
             for ip in floating_ips]
Example #8
0
    def test_get_ip_addresses(self):
        namespace = 'ns_test-' + uuidutils.generate_uuid()
        priv_ip_lib.create_netns(namespace)
        self.addCleanup(self._remove_ns, namespace)
        interfaces = {
            '20': {'cidr': '192.168.10.20/24', 'scope': 'link',
                   'add_broadcast': True},
            '30': {'cidr': '2001::1/64', 'scope': 'global',
                   'add_broadcast': False}}

        for int_name, int_parameters in interfaces.items():
            priv_ip_lib.create_interface(int_name, namespace, 'dummy',
                                         index=int(int_name))
            ip_lib.add_ip_address(
                int_parameters['cidr'], int_name, namespace,
                int_parameters['scope'], int_parameters['add_broadcast'])

        ip_addresses = priv_ip_lib.get_ip_addresses(namespace)
        for ip_address in ip_addresses:
            int_name = str(ip_address['index'])
            ip = _get_attr(ip_address, 'IFA_ADDRESS')
            mask = ip_address['prefixlen']
            cidr = common_utils.ip_to_cidr(ip, mask)
            self.assertEqual(interfaces[int_name]['cidr'], cidr)
            self.assertEqual(interfaces[int_name]['scope'],
                             ip_lib.IP_ADDRESS_SCOPE[ip_address['scope']])
Example #9
0
    def test_snat_and_floatingip(self):
        # This function creates external network and boots an extrenal vm
        # on it with gateway ip and connected to central_external_bridge.
        # Later it creates a tenant vm on tenant network, with tenant router
        # connected to tenant network and external network.
        # To test snat and floatingip, try ping between tenant and external vms
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        external_vm = self.useFixture(
            machine_fixtures.FakeMachine(
                self.environment.central_external_bridge,
                common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24)))

        router = self.safe_client.create_router(tenant_id,
                                                external_network=ext_net['id'])
        vm = self._create_net_subnet_and_vm(
            tenant_id, '20.0.0.0/24',
            self.environment.hosts[1], router)

        # ping external vm to test snat
        vm.block_until_ping(external_vm.ip)

        fip = self.safe_client.create_floatingip(
            tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id'])

        # ping floating ip from external vm
        external_vm.block_until_ping(fip['floating_ip_address'])
Example #10
0
    def add_floating_ip(self, fip, interface_name, device):
        if not self._add_fip_addr_to_device(fip, device):
            return l3_constants.FLOATINGIP_STATUS_ERROR

        # Special Handling for DVR - update FIP namespace
        ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
        self.floating_ip_added_dist(fip, ip_cidr)
        return l3_constants.FLOATINGIP_STATUS_ACTIVE
Example #11
0
 def _list_centralized_floating_ip_cidrs(self):
     # Compute a list of addresses this gw is supposed to have.
     # This avoids unnecessarily removing those addresses and
     # causing a momentarily network outage.
     floating_ips = self.get_floating_ips()
     return [common_utils.ip_to_cidr(ip['floating_ip_address'])
             for ip in floating_ips
             if ip.get(lib_constants.DVR_SNAT_BOUND)]
Example #12
0
    def connect_to_internal_network_via_tunneling(self):
        veth_1, veth_2 = self.useFixture(
            net_helpers.VethFixture()).ports

        # NOTE: This sets an IP address on the host's root namespace
        # which is cleaned up when the device is deleted.
        veth_1.addr.add(common_utils.ip_to_cidr(self.local_ip, 32))

        veth_1.link.set_up()
        veth_2.link.set_up()
Example #13
0
    def _configure_port_for_rabbitmq(self):
        self.env_desc.network_range = self._get_network_range()
        if not self.env_desc.network_range:
            return "127.0.0.1"
        rabbitmq_ip = str(self.env_desc.network_range[1])
        rabbitmq_port = ip_lib.IPDevice(self.central_data_bridge.br_name)
        rabbitmq_port.addr.add(common_utils.ip_to_cidr(rabbitmq_ip, 24))
        rabbitmq_port.link.set_up()

        return rabbitmq_ip
Example #14
0
 def _get_gw_ips_cidr(self):
     gw_cidrs = set()
     ex_gw_port = self.get_ex_gw_port()
     if ex_gw_port:
         for ip_addr in ex_gw_port['fixed_ips']:
             ex_gw_ip = ip_addr['ip_address']
             addr = netaddr.IPAddress(ex_gw_ip)
             if addr.version == lib_constants.IP_VERSION_4:
                 gw_cidrs.add(common_utils.ip_to_cidr(ex_gw_ip))
     return gw_cidrs
Example #15
0
    def get_expected_keepalive_configuration(self, router):
        router_id = router.router_id
        ha_device_name = router.get_ha_device_name()
        ha_device_cidr = self._port_first_ip_cidr(router.ha_port)
        external_port = router.get_ex_gw_port()
        ex_port_ipv6 = ip_lib.get_ipv6_lladdr(external_port['mac_address'])
        external_device_name = router.get_external_device_name(
            external_port['id'])
        external_device_cidr = self._port_first_ip_cidr(external_port)
        internal_port = router.router[l3_constants.INTERFACE_KEY][0]
        int_port_ipv6 = ip_lib.get_ipv6_lladdr(internal_port['mac_address'])
        internal_device_name = router.get_internal_device_name(
            internal_port['id'])
        internal_device_cidr = self._port_first_ip_cidr(internal_port)
        floating_ip_cidr = common_utils.ip_to_cidr(
            router.get_floating_ips()[0]['floating_ip_address'])
        default_gateway_ip = external_port['subnets'][0].get('gateway_ip')

        return """vrrp_instance VR_1 {
    state BACKUP
    interface %(ha_device_name)s
    virtual_router_id 1
    priority 50
    nopreempt
    advert_int 2
    track_interface {
        %(ha_device_name)s
    }
    virtual_ipaddress {
        169.254.0.1/24 dev %(ha_device_name)s
    }
    virtual_ipaddress_excluded {
        %(floating_ip_cidr)s dev %(external_device_name)s
        %(external_device_cidr)s dev %(external_device_name)s
        %(internal_device_cidr)s dev %(internal_device_name)s
        %(ex_port_ipv6)s dev %(external_device_name)s scope link
        %(int_port_ipv6)s dev %(internal_device_name)s scope link
    }
    virtual_routes {
        0.0.0.0/0 via %(default_gateway_ip)s dev %(external_device_name)s
        8.8.8.0/24 via 19.4.4.4
    }
}""" % {
            'router_id': router_id,
            'ha_device_name': ha_device_name,
            'ha_device_cidr': ha_device_cidr,
            'external_device_name': external_device_name,
            'external_device_cidr': external_device_cidr,
            'internal_device_name': internal_device_name,
            'internal_device_cidr': internal_device_cidr,
            'floating_ip_cidr': floating_ip_cidr,
            'default_gateway_ip': default_gateway_ip,
            'int_port_ipv6': int_port_ipv6,
            'ex_port_ipv6': ex_port_ipv6
        }
Example #16
0
 def _create_external_vm(self, network, subnet):
     vm = self.useFixture(
         machine_fixtures.FakeMachine(
             self.environment.central_bridge,
             common_utils.ip_to_cidr(subnet['gateway_ip'], 24)))
     # NOTE(slaweq): as ext_net is 'vlan' network type external_vm needs to
     # send packets with proper vlan also
     vm.bridge.set_db_attribute(
         "Port", vm.port.name,
         "tag", network.get("provider:segmentation_id"))
     return vm
Example #17
0
 def _internal_network_updated(self, port, subnet_id, prefix, old_prefix, updated_cidrs):
     interface_name = self.get_internal_device_name(port["id"])
     if prefix != l3_constants.PROVISIONAL_IPV6_PD_PREFIX:
         fixed_ips = port["fixed_ips"]
         for fixed_ip in fixed_ips:
             if fixed_ip["subnet_id"] == subnet_id:
                 v6addr = common_utils.ip_to_cidr(fixed_ip["ip_address"], fixed_ip.get("prefixlen"))
                 if v6addr not in updated_cidrs:
                     self.driver.add_ipv6_addr(interface_name, v6addr, self.ns_name)
     else:
         self.driver.delete_ipv6_addr_with_prefix(interface_name, old_prefix, self.ns_name)
Example #18
0
 def _add_fip_addr_to_device(self, fip, device):
     """Configures the floating ip address on the device.
     """
     try:
         ip_cidr = common_utils.ip_to_cidr(fip["floating_ip_address"])
         device.addr.add(ip_cidr)
         return True
     except RuntimeError:
         # any exception occurred here should cause the floating IP
         # to be set in error state
         LOG.warn(_LW("Unable to configure IP address for " "floating IP: %s"), fip["id"])
Example #19
0
 def external_gateway_removed(self, ex_gw_port, interface_name):
     LOG.debug("External gateway removed: port(%s), interface(%s)",
               ex_gw_port, interface_name)
     device = ip_lib.IPDevice(interface_name, namespace=self.ns_name)
     for ip_addr in ex_gw_port['fixed_ips']:
         self.remove_external_gateway_ip(device,
                                         common_utils.ip_to_cidr(
                                             ip_addr['ip_address'],
                                             ip_addr['prefixlen']))
     self.driver.unplug(interface_name,
                        bridge=self.agent_conf.external_network_bridge,
                        namespace=self.ns_name,
                        prefix=EXTERNAL_DEV_PREFIX)
Example #20
0
 def _ip_prefix_arg(self, direction, ip_prefix):
     #NOTE (nati) : source_group_id is converted to list of source_
     # ip_prefix in server side
     if ip_prefix:
         if '/' not in ip_prefix:
             # we need to convert it into a prefix to match iptables
             ip_prefix = c_utils.ip_to_cidr(ip_prefix)
         elif ip_prefix.endswith('/0'):
             # an allow for every address is not a constraint so
             # iptables drops it
             return []
         return ['-%s' % direction, ip_prefix]
     return []
Example #21
0
    def process_floating_ip_addresses(self, interface_name):
        """Configure IP addresses on router's external gateway interface.

        Ensures addresses for existing floating IPs and cleans up
        those that should not longer be configured.
        """

        fip_statuses = {}
        if interface_name is None:
            LOG.debug('No Interface for floating IPs router: %s',
                      self.router['id'])
            return fip_statuses

        device = ip_lib.IPDevice(interface_name, namespace=self.ns_name)
        existing_cidrs = self.get_router_cidrs(device)
        new_cidrs = set()
        gw_cidrs = self._get_gw_ips_cidr()

        floating_ips = self.get_floating_ips()
        # Loop once to ensure that floating ips are configured.
        for fip in floating_ips:
            fip_ip = fip['floating_ip_address']
            ip_cidr = common_utils.ip_to_cidr(fip_ip)
            new_cidrs.add(ip_cidr)
            fip_statuses[fip['id']] = lib_constants.FLOATINGIP_STATUS_ACTIVE
            if ip_cidr not in existing_cidrs:
                fip_statuses[fip['id']] = self.add_floating_ip(
                    fip, interface_name, device)
                LOG.debug('Floating ip %(id)s added, status %(status)s',
                          {'id': fip['id'],
                           'status': fip_statuses.get(fip['id'])})
            elif (fip_ip in self.fip_map and
                  self.fip_map[fip_ip] != fip['fixed_ip_address']):
                LOG.debug("Floating IP was moved from fixed IP "
                          "%(old)s to %(new)s",
                          {'old': self.fip_map[fip_ip],
                           'new': fip['fixed_ip_address']})
                fip_statuses[fip['id']] = self.move_floating_ip(fip)
            elif fip_statuses[fip['id']] == fip['status']:
                # mark the status as not changed. we can't remove it because
                # that's how the caller determines that it was removed
                fip_statuses[fip['id']] = FLOATINGIP_STATUS_NOCHANGE
        fips_to_remove = (
            ip_cidr for ip_cidr in existing_cidrs - new_cidrs - gw_cidrs
            if common_utils.is_cidr_host(ip_cidr))
        for ip_cidr in fips_to_remove:
            LOG.debug("Removing floating ip %s from interface %s in "
                      "namespace %s", ip_cidr, interface_name, self.ns_name)
            self.remove_floating_ip(device, ip_cidr)

        return fip_statuses
    def test_floating_ip_added_dist(self, mock_add_ip_rule, mIPDevice,
                                    mock_adv_notif):
        router = mock.MagicMock()
        ri = self._create_router(router)
        ri.ex_gw_port = ri.router['gw_port']
        ext_net_id = _uuid()
        subnet_id = _uuid()
        agent_gw_port = {'fixed_ips': [{'ip_address': '20.0.0.30',
                                        'prefixlen': 24,
                                        'subnet_id': subnet_id}],
                         'subnets': [{'id': subnet_id,
                                      'cidr': '20.0.0.0/24',
                                      'gateway_ip': '20.0.0.1'}],
                         'id': _uuid(),
                         'network_id': ext_net_id,
                         'mac_address': 'ca:fe:de:ad:be:ef'}

        fip = {'id': _uuid(),
               'host': HOSTNAME,
               'floating_ip_address': '15.1.2.3',
               'fixed_ip_address': '192.168.0.1',
               'floating_network_id': ext_net_id,
               'port_id': _uuid()}
        ri.fip_ns = mock.Mock()
        ri.fip_ns.agent_gateway_port = agent_gw_port
        ri.create_dvr_external_gateway_on_agent(ri.ex_gw_port)
        ri._check_rtr_2_fip_connect = mock.Mock()
        ri.connect_rtr_2_fip()
        self.assertTrue(ri.rtr_fip_connect)
        ri.fip_ns.allocate_rule_priority.return_value = FIP_PRI
        subnet = lla.LinkLocalAddressPair('169.254.30.42/31')
        ri.rtr_fip_subnet = subnet
        ri.fip_ns.local_subnets = mock.Mock()
        ri.fip_ns.local_subnets.allocate.return_value = subnet
        ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
        ri.floating_ip_added_dist(fip, ip_cidr)
        mock_add_ip_rule.assert_called_with(
            namespace=ri.router_namespace.name, ip='192.168.0.1',
            table=16, priority=FIP_PRI)
        ri.fip_ns.local_subnets.allocate.assert_not_called()

        # Validate that fip_ns.local_subnets is called when
        # ri.rtr_fip_subnet is None
        ri.rtr_fip_subnet = None
        ri.floating_ip_added_dist(fip, ip_cidr)
        mock_add_ip_rule.assert_called_with(
            namespace=ri.router_namespace.name, ip='192.168.0.1',
            table=16, priority=FIP_PRI)
        ri.fip_ns.local_subnets.allocate.assert_called_once_with(ri.router_id)
Example #23
0
 def _setup_spoof_filter_chain(self, port, table, mac_ip_pairs, rules):
     if mac_ip_pairs:
         chain_name = self._port_chain_name(port, SPOOF_FILTER)
         table.add_chain(chain_name)
         for mac, ip in mac_ip_pairs:
             if ip is None:
                 # If fixed_ips is [] this rule will be added to the end
                 # of the list after the allowed_address_pair rules.
                 table.add_rule(chain_name, "-m mac --mac-source %s -j RETURN" % mac.upper(), comment=ic.PAIR_ALLOW)
             else:
                 # we need to convert it into a prefix to match iptables
                 ip = c_utils.ip_to_cidr(ip)
                 table.add_rule(
                     chain_name, "-s %s -m mac --mac-source %s -j RETURN" % (ip, mac.upper()), comment=ic.PAIR_ALLOW
                 )
         table.add_rule(chain_name, "-j DROP", comment=ic.PAIR_DROP)
         rules.append("-j $%s" % chain_name)
Example #24
0
    def _test_gateway_ip_changed(self):
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        external_vm = self.useFixture(
            machine_fixtures.FakeMachine(
                self.environment.central_bridge,
                common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24)))

        router = self.safe_client.create_router(tenant_id,
                                                external_network=ext_net['id'])

        vm = self._create_net_subnet_and_vm(
            tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'],
            self.environment.hosts[1], router)
        # ping external vm to test snat
        vm.block_until_ping(external_vm.ip)

        fip = self.safe_client.create_floatingip(
            tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id'])
        # ping floating ip from external vm
        external_vm.block_until_ping(fip['floating_ip_address'])

        # ping router gateway IP
        old_gw_ip = router['external_gateway_info'][
            'external_fixed_ips'][0]['ip_address']
        external_vm.block_until_ping(old_gw_ip)

        gateway_port = self.safe_client.list_ports(
            device_id=router['id'],
            device_owner=constants.DEVICE_OWNER_ROUTER_GW)[0]
        ip_1 = str(netaddr.IPNetwork(
            ext_sub['gateway_ip']).next(100)).split('/')[0]
        ip_2 = str(netaddr.IPNetwork(
            ext_sub['gateway_ip']).next(101)).split('/')[0]
        self.safe_client.update_port(gateway_port['id'], fixed_ips=[
            {'ip_address': ip_1},
            {'ip_address': ip_2}])
        # ping router gateway new IPs
        external_vm.block_until_ping(ip_1)
        external_vm.block_until_ping(ip_2)

        # ping router old gateway IP, should fail now
        external_vm.block_until_no_ping(old_gw_ip)
Example #25
0
    def process_floating_ip_addresses(self, interface_name):
        """Configure IP addresses on router's external gateway interface.

        Ensures addresses for existing floating IPs and cleans up
        those that should not longer be configured.
        """

        fip_statuses = {}
        if interface_name is None:
            LOG.debug("No Interface for floating IPs router: %s", self.router["id"])
            return fip_statuses

        device = ip_lib.IPDevice(interface_name, namespace=self.ns_name)
        existing_cidrs = self.get_router_cidrs(device)
        new_cidrs = set()

        floating_ips = self.get_floating_ips()
        # Loop once to ensure that floating ips are configured.
        for fip in floating_ips:
            fip_ip = fip["floating_ip_address"]
            ip_cidr = common_utils.ip_to_cidr(fip_ip)
            new_cidrs.add(ip_cidr)
            fip_statuses[fip["id"]] = l3_constants.FLOATINGIP_STATUS_ACTIVE
            if ip_cidr not in existing_cidrs:
                fip_statuses[fip["id"]] = self.add_floating_ip(fip, interface_name, device)
                LOG.debug(
                    "Floating ip %(id)s added, status %(status)s",
                    {"id": fip["id"], "status": fip_statuses.get(fip["id"])},
                )

                # mark the status as not changed. we can't remove it because
                # that's how the caller determines that it was removed
                if fip_statuses[fip["id"]] == fip["status"]:
                    fip_statuses[fip["id"]] = FLOATINGIP_STATUS_NOCHANGE
        fips_to_remove = (ip_cidr for ip_cidr in existing_cidrs - new_cidrs if common_utils.is_cidr_host(ip_cidr))
        for ip_cidr in fips_to_remove:
            LOG.debug(
                "Removing floating ip %s from interface %s in " "namespace %s", ip_cidr, interface_name, self.ns_name
            )
            self.remove_floating_ip(device, ip_cidr)

        return fip_statuses
Example #26
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']:
             # 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)
                         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)
     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)
Example #27
0
    def get_router_cidrs(self, device):
        """As no floatingip will be set on the rfp device. Get floatingip from
        the route of fip namespace.
        """
        if not self.fip_ns:
            return set()

        fip_ns_name = self.fip_ns.get_name()
        fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
        device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)
        if not device.exists():
            return set()

        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()
        exist_routes = device.route.list_routes(
            lib_constants.IP_VERSION_4, via=str(rtr_2_fip.ip))
        return {common_utils.ip_to_cidr(route['cidr'])
                for route in exist_routes}
Example #28
0
    def external_gateway_updated(self, ri, ex_gw_port, interface_name):
        preserve_ips = []
        if ri.router['distributed']:
            if (self.conf.agent_mode == l3_constants.L3_AGENT_MODE_DVR_SNAT and
                self.get_gw_port_host(ri.router) == self.host):
                ns_name = self.get_snat_ns_name(ri.router['id'])
            else:
                # no centralized SNAT gateway for this node/agent
                LOG.debug("not hosting snat for router: %s", ri.router['id'])
                return
        else:
            ns_name = ri.ns_name
            floating_ips = ri.get_floating_ips()
            preserve_ips = [common_utils.ip_to_cidr(ip['floating_ip_address'])
                            for ip in floating_ips]

        self._external_gateway_added(ri, ex_gw_port, interface_name,
                                     ns_name, preserve_ips)

        if ri.is_ha:
            ri._ha_external_gateway_updated(ex_gw_port, interface_name)
Example #29
0
    def test_ha_router_restart_agents_no_packet_lost(self):
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        router = self.safe_client.create_router(tenant_id, ha=True,
                                                external_network=ext_net['id'])

        external_vm = self.useFixture(
            machine_fixtures.FakeMachine(
                self.environment.central_bridge,
                common_utils.ip_to_cidr(ext_sub['gateway_ip'], 24)))

        common_utils.wait_until_true(
            lambda:
            len(self.client.list_l3_agent_hosting_routers(
                router['id'])['agents']) == 2,
            timeout=90)

        common_utils.wait_until_true(
            functools.partial(
                self._is_ha_router_active_on_one_agent,
                router['id']),
            timeout=90)

        router_ip = router['external_gateway_info'][
            'external_fixed_ips'][0]['ip_address']
        # Let's check first if connectivity from external_vm to router's
        # external gateway IP is possible before we restart agents
        external_vm.block_until_ping(router_ip)

        l3_agents = [host.agents['l3'] for host in self.environment.hosts]
        l3_standby_agents = self._get_l3_agents_with_ha_state(
            l3_agents, router['id'], 'standby')
        l3_active_agents = self._get_l3_agents_with_ha_state(
            l3_agents, router['id'], 'active')

        self._assert_ping_during_agents_restart(
            l3_standby_agents, external_vm.namespace, [router_ip], count=60)

        self._assert_ping_during_agents_restart(
            l3_active_agents, external_vm.namespace, [router_ip], count=60)
Example #30
0
    def sync_port_forwarding_fip(self, context, routers):
        if not routers:
            return

        router_ids = [router.get('id') for router in routers]
        router_pf_fip_set = collections.defaultdict(set)
        fip_pfs = collections.defaultdict(set)
        router_fip = collections.defaultdict(set)
        item_pf_fields = pf.PortForwarding.get_port_forwarding_obj_by_routers(
            context, router_ids)

        for router_id, fip_addr, pf_id, fip_id in item_pf_fields:
            router_pf_fip_set[router_id].add(utils.ip_to_cidr(fip_addr, 32))
            fip_pfs[fip_id].add(pf_id)
            router_fip[router_id].add(fip_id)

        for router in routers:
            if router['id'] in router_fip:
                router['port_forwardings_fip_set'] = router_pf_fip_set[
                    router['id']]
                router['fip_managed_by_port_forwardings'] = router_fip[
                    router['id']]
Example #31
0
 def add_floating_ip(self, fip, interface_name, device):
     fip_ip = fip['floating_ip_address']
     ip_cidr = common_utils.ip_to_cidr(fip_ip)
     self._add_vip(ip_cidr, interface_name)
Example #32
0
 def add_floating_ip(self, fip, interface_name, device):
     # Special Handling for DVR - update FIP namespace
     ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
     return self.floating_ip_added_dist(fip, ip_cidr)
Example #33
0
 def get_expected_keepalive_configuration(self, router):
     ha_device_name = router.get_ha_device_name()
     external_port = router.get_ex_gw_port()
     ex_port_ipv6 = ip_lib.get_ipv6_lladdr(external_port['mac_address'])
     ex_device_name = router.get_external_device_name(
         external_port['id'])
     external_device_cidr = self._port_first_ip_cidr(external_port)
     internal_port = router.router[constants.INTERFACE_KEY][0]
     int_port_ipv6 = ip_lib.get_ipv6_lladdr(internal_port['mac_address'])
     internal_device_name = router.get_internal_device_name(
         internal_port['id'])
     internal_device_cidr = self._port_first_ip_cidr(internal_port)
     floating_ip_cidr = common_utils.ip_to_cidr(
         router.get_floating_ips()[0]['floating_ip_address'])
     default_gateway_ip = external_port['subnets'][0].get('gateway_ip')
     extra_subnet_cidr = external_port['extra_subnets'][0].get('cidr')
     return textwrap.dedent("""\
         global_defs {
             notification_email_from %(email_from)s
             router_id %(router_id)s
         }
         vrrp_instance VR_1 {
             state BACKUP
             interface %(ha_device_name)s
             virtual_router_id 1
             priority 50
             garp_master_delay 60
             nopreempt
             advert_int 2
             track_interface {
                 %(ha_device_name)s
             }
             virtual_ipaddress {
                 169.254.0.1/24 dev %(ha_device_name)s
             }
             virtual_ipaddress_excluded {
                 %(floating_ip_cidr)s dev %(ex_device_name)s
                 %(external_device_cidr)s dev %(ex_device_name)s
                 %(internal_device_cidr)s dev %(internal_device_name)s
                 %(ex_port_ipv6)s dev %(ex_device_name)s scope link
                 %(int_port_ipv6)s dev %(internal_device_name)s scope link
             }
             virtual_routes {
                 0.0.0.0/0 via %(default_gateway_ip)s dev %(ex_device_name)s
                 8.8.8.0/24 via 19.4.4.4
                 %(extra_subnet_cidr)s dev %(ex_device_name)s scope link
             }
         }""") % {
         'email_from': keepalived.KEEPALIVED_EMAIL_FROM,
         'router_id': keepalived.KEEPALIVED_ROUTER_ID,
         'ha_device_name': ha_device_name,
         'ex_device_name': ex_device_name,
         'external_device_cidr': external_device_cidr,
         'internal_device_name': internal_device_name,
         'internal_device_cidr': internal_device_cidr,
         'floating_ip_cidr': floating_ip_cidr,
         'default_gateway_ip': default_gateway_ip,
         'int_port_ipv6': int_port_ipv6,
         'ex_port_ipv6': ex_port_ipv6,
         'extra_subnet_cidr': extra_subnet_cidr,
     }
Example #34
0
 def migrate_centralized_floating_ip(self, fip, interface_name, device):
     # Remove the centralized fip first and then add fip to the host
     ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
     self.floating_ip_removed_dist(ip_cidr)
     # Now add the floating_ip to the current host
     self.floating_ip_added_dist(fip, ip_cidr)
Example #35
0
 def test_ip_to_cidr_ipv6_prefix(self):
     self.assertEqual('::1/64', utils.ip_to_cidr('::1', 64))
Example #36
0
    def test_north_south_traffic(self):
        # This function creates an external network which is connected to
        # central_bridge and spawns an external_vm on it.
        # The external_vm is configured with the gateway_ip (both v4 & v6
        # addresses) of external subnet. Later, it creates a tenant router,
        # a tenant network and two tenant subnets (v4 and v6). The tenant
        # router is associated with tenant network and external network to
        # provide north-south connectivity to the VMs.
        # We validate the following in this testcase.
        # 1. SNAT support: using ping from tenant VM to external_vm
        # 2. Floating IP support: using ping from external_vm to VM floating ip
        # 3. IPv6 ext connectivity: using ping6 from tenant vm to external_vm.
        tenant_id = uuidutils.generate_uuid()
        ext_net, ext_sub = self._create_external_network_and_subnet(tenant_id)
        external_vm = self._create_external_vm(ext_net, ext_sub)
        # Create an IPv6 subnet in the external network
        v6network = self.useFixture(
            ip_network.ExclusiveIPNetwork(
                "2001:db8:1234::1", "2001:db8:1234::10", "64")).network
        ext_v6sub = self.safe_client.create_subnet(
            tenant_id, ext_net['id'], v6network)

        router = self.safe_client.create_router(tenant_id,
                                                external_network=ext_net['id'])

        # Configure the gateway_ip of external v6subnet on the external_vm.
        external_vm.ipv6_cidr = common_utils.ip_to_cidr(
            ext_v6sub['gateway_ip'], 64)

        # Configure an IPv6 downstream route to the v6Address of router gw port
        for fixed_ip in router['external_gateway_info']['external_fixed_ips']:
            if netaddr.IPNetwork(fixed_ip['ip_address']).version == 6:
                external_vm.set_default_gateway(fixed_ip['ip_address'])

        vm = self._create_net_subnet_and_vm(
            tenant_id, ['20.0.0.0/24', '2001:db8:aaaa::/64'],
            self.environment.hosts[1], router)

        # ping external vm to test snat
        vm.block_until_ping(external_vm.ip)

        fip = self.safe_client.create_floatingip(
            tenant_id, ext_net['id'], vm.ip, vm.neutron_port['id'])

        # ping floating ip from external vm
        external_vm.block_until_ping(fip['floating_ip_address'])

        # Verify VM is able to reach the router interface.
        vm.block_until_ping(vm.gateway_ipv6)
        # Verify north-south connectivity using ping6 to external_vm.
        vm.block_until_ping(external_vm.ipv6)

        # Now let's remove and create again phys bridge and check connectivity
        # once again
        br_phys = self.environment.hosts[0].br_phys
        br_phys.destroy()
        br_phys.create()
        self.environment.hosts[0].connect_to_central_network_via_vlans(
            br_phys)

        # ping floating ip from external vm
        external_vm.block_until_ping(fip['floating_ip_address'])

        # Verify VM is able to reach the router interface.
        vm.block_until_ping(vm.gateway_ipv6)
        # Verify north-south connectivity using ping6 to external_vm.
        vm.block_until_ping(external_vm.ipv6)
Example #37
0
 def test_ip_to_cidr_ipv6_default(self):
     self.assertEqual('::1/128', utils.ip_to_cidr('::1'))
Example #38
0
 def test_ip_to_cidr_ipv4_netaddr(self):
     ip_address = netaddr.IPAddress('15.1.2.3')
     self.assertEqual('15.1.2.3/32', utils.ip_to_cidr(ip_address))
Example #39
0
 def add_floating_ip(self, fip, interface_name, device):
     fip_ip = fip['floating_ip_address']
     ip_cidr = common_utils.ip_to_cidr(fip_ip)
     self._add_vip(ip_cidr, interface_name)
     return n_consts.FLOATINGIP_STATUS_ACTIVE
    def test_floating_ip_added_dist(self, mock_add_ip_rule, mIPDevice,
                                    mock_adv_notif):
        router = mock.MagicMock()
        ri = self._create_router(router)
        ri.ex_gw_port = ri.router['gw_port']
        ext_net_id = _uuid()
        subnet_id = _uuid()
        agent_gw_port = {
            'fixed_ips': [{
                'ip_address': '20.0.0.30',
                'prefixlen': 24,
                'subnet_id': subnet_id
            }],
            'subnets': [{
                'id': subnet_id,
                'cidr': '20.0.0.0/24',
                'gateway_ip': '20.0.0.1'
            }],
            'id':
            _uuid(),
            'network_id':
            ext_net_id,
            'mac_address':
            'ca:fe:de:ad:be:ef'
        }

        fip = {
            'id': _uuid(),
            'host': HOSTNAME,
            'floating_ip_address': '15.1.2.3',
            'fixed_ip_address': '192.168.0.1',
            'floating_network_id': ext_net_id,
            'port_id': _uuid()
        }
        ri.fip_ns = mock.Mock()
        ri.fip_ns.agent_gateway_port = agent_gw_port
        ri.create_dvr_external_gateway_on_agent(ri.ex_gw_port)
        ri._check_rtr_2_fip_connect = mock.Mock()
        ri.connect_rtr_2_fip()
        self.assertTrue(ri.rtr_fip_connect)
        ri.fip_ns.allocate_rule_priority.return_value = FIP_PRI
        subnet = lla.LinkLocalAddressPair('169.254.30.42/31')
        ri.rtr_fip_subnet = subnet
        ri.fip_ns.local_subnets = mock.Mock()
        ri.fip_ns.local_subnets.allocate.return_value = subnet
        ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
        ri.floating_ip_added_dist(fip, ip_cidr)
        mock_add_ip_rule.assert_called_with(namespace=ri.router_namespace.name,
                                            ip='192.168.0.1',
                                            table=16,
                                            priority=FIP_PRI)
        ri.fip_ns.local_subnets.allocate.assert_not_called()

        # Validate that fip_ns.local_subnets is called when
        # ri.rtr_fip_subnet is None
        ri.rtr_fip_subnet = None
        ri.floating_ip_added_dist(fip, ip_cidr)
        mock_add_ip_rule.assert_called_with(namespace=ri.router_namespace.name,
                                            ip='192.168.0.1',
                                            table=16,
                                            priority=FIP_PRI)
        ri.fip_ns.local_subnets.allocate.assert_called_once_with(ri.router_id)
Example #41
0
 def test_ip_to_cidr_ipv4_prefix(self):
     self.assertEqual('15.1.2.3/24', utils.ip_to_cidr('15.1.2.3', 24))
Example #42
0
 def connect_namespace_to_control_network(self):
     self.host_port = self._connect_ovs_port(
         common_utils.ip_to_cidr(self.local_ip, 24))
     self.host_port.link.set_up()
Example #43
0
 def _port_first_ip_cidr(port):
     fixed_ip = port['fixed_ips'][0]
     return common_utils.ip_to_cidr(fixed_ip['ip_address'],
                                    fixed_ip['prefixlen'])
 def add_floating_ip(self, fip, interface_name, device):
     # Special Handling for DVR - update FIP namespace
     ip_cidr = common_utils.ip_to_cidr(fip['floating_ip_address'])
     self.floating_ip_added_dist(fip, ip_cidr)
     return l3_constants.FLOATINGIP_STATUS_ACTIVE
Example #45
0
    def _ip_prefix_arg(self, direction, ip_prefix):
        if not (ip_prefix):
            return []

        args = ['-%s' % direction, '%s' % utils.ip_to_cidr(ip_prefix)]
        return args
Example #46
0
 def connect_namespace_to_control_network(self):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
     self.host_port = self._connect_ovs_port(
         common_utils.ip_to_cidr(self.local_ip, 24)
     )
     self.host_port.link.set_up()
Example #47
0
 def test_ip_to_cidr_ipv4_default(self):
     self.assertEqual('15.1.2.3/32', utils.ip_to_cidr('15.1.2.3'))