Ejemplo n.º 1
0
    def _add_floating_ip_rule(self, floating_ip, fixed_ip):
        rule_pr = self.fip_ns.allocate_rule_priority(floating_ip)
        self.floating_ips_dict[floating_ip] = (fixed_ip, rule_pr)

        ip_lib.add_ip_rule(namespace=self.ns_name, ip=fixed_ip,
                           table=dvr_fip_ns.FIP_RT_TBL,
                           priority=int(str(rule_pr)))
Ejemplo n.º 2
0
    def _add_rtr_ext_route_rule_to_route_table(self, ri, fip_2_rtr,
                                               fip_2_rtr_name):
        """Creates external route table and adds routing rules."""
        # TODO(Swami): Rename the _get_snat_idx function to some
        # generic name that can be used for SNAT and FIP
        rt_tbl_index = ri._get_snat_idx(fip_2_rtr)
        interface_name = self.get_ext_device_name(
            self.agent_gateway_port['id'])
        try:
            # The lock is used to make sure another thread doesn't call to
            # update the gateway route before we are done initializing things.
            with self._fip_port_lock(interface_name):
                self._update_gateway_route(self.agent_gateway_port,
                                           interface_name,
                                           tbl_index=rt_tbl_index)
        except Exception:
            # If an exception occurs at this point, then it is
            # good to unsubscribe this external network so that
            # the next call will trigger the interface to be plugged.
            # We reraise the exception in order to resync the router.
            with excutils.save_and_reraise_exception():
                self.unsubscribe(self.agent_gateway_port['network_id'])
                self.agent_gateway_port = None
                LOG.exception('DVR: Gateway setup in FIP namespace ' 'failed')

        # Now add the filter match rule for the table.
        ip_lib.add_ip_rule(namespace=self.get_name(),
                           ip=str(fip_2_rtr.ip),
                           iif=fip_2_rtr_name,
                           table=rt_tbl_index,
                           priority=rt_tbl_index)
Ejemplo n.º 3
0
    def _add_floating_ip_rule(self, floating_ip, fixed_ip):
        rule_pr = self.fip_ns.allocate_rule_priority(floating_ip)
        self.floating_ips_dict[floating_ip] = (fixed_ip, rule_pr)

        ip_lib.add_ip_rule(namespace=self.ns_name, ip=fixed_ip,
                           table=dvr_fip_ns.FIP_RT_TBL,
                           priority=int(str(rule_pr)))
Ejemplo n.º 4
0
 def _add_interface_routing_rule_to_router_ns(self, router_port):
     for subnet in router_port['subnets']:
         rtr_port_cidr = subnet['cidr']
         ip_lib.add_ip_rule(namespace=self.ns_name,
                            ip=rtr_port_cidr,
                            table=dvr_fip_ns.FIP_RT_TBL,
                            priority=dvr_fip_ns.FAST_PATH_EXIT_PR)
Ejemplo n.º 5
0
    def _add_rtr_ext_route_rule_to_route_table(self, ri, fip_2_rtr,
                                               fip_2_rtr_name):
        """Creates external route table and adds routing rules."""
        # TODO(Swami): Rename the _get_snat_idx function to some
        # generic name that can be used for SNAT and FIP
        rt_tbl_index = ri._get_snat_idx(fip_2_rtr)
        interface_name = self.get_ext_device_name(
            self.agent_gateway_port['id'])
        try:
            # The lock is used to make sure another thread doesn't call to
            # update the gateway route before we are done initializing things.
            with self._fip_port_lock(interface_name):
                self._update_gateway_route(self.agent_gateway_port,
                                           interface_name,
                                           tbl_index=rt_tbl_index)
        except Exception:
            # If an exception occurs at this point, then it is
            # good to unsubscribe this external network so that
            # the next call will trigger the interface to be plugged.
            # We reraise the exception in order to resync the router.
            with excutils.save_and_reraise_exception():
                self.unsubscribe(self.agent_gateway_port['network_id'])
                self.agent_gateway_port = None
                LOG.exception('DVR: Gateway setup in FIP namespace '
                              'failed')

        # Now add the filter match rule for the table.
        ip_lib.add_ip_rule(namespace=self.get_name(), ip=str(fip_2_rtr.ip),
                           iif=fip_2_rtr_name, table=rt_tbl_index,
                           priority=rt_tbl_index)
Ejemplo n.º 6
0
 def test_list_rules_ipv6(self):
     ip_lib.add_ip_rule(self.namespace, '2001:db8::1/64', table=20)
     rules_ipv6 = priv_ip_lib.list_ip_rules(self.namespace, 6)
     for rule in rules_ipv6:
         if rule['table'] == 20:
             self.assertEqual('2001:db8::1', rule['attrs']['FRA_SRC'])
             self.assertEqual(64, rule['src_len'])
             break
     else:
         self.fail('Rule added (2001:db8::1/64, table 20) not found')
Ejemplo n.º 7
0
 def test_list_rules_ipv4(self):
     ip_lib.add_ip_rule(self.namespace, '192.168.0.1/24', table=10)
     rules_ipv4 = priv_ip_lib.list_ip_rules(self.namespace, 4)
     for rule in rules_ipv4:
         if rule['table'] == 10:
             self.assertEqual('192.168.0.1', rule['attrs']['FRA_SRC'])
             self.assertEqual(24, rule['src_len'])
             break
     else:
         self.fail('Rule added (192.168.0.1/24, table 10) not found')
Ejemplo n.º 8
0
 def test_list_rules_ipv6(self):
     ip_lib.add_ip_rule(self.namespace, '2001:db8::1/64', table=20)
     rules_ipv6 = priv_ip_lib.list_ip_rules(self.namespace, 6)
     for rule in rules_ipv6:
         if rule['table'] == 20:
             self.assertEqual('2001:db8::1', rule['attrs']['FRA_SRC'])
             self.assertEqual(64, rule['src_len'])
             break
     else:
         self.fail('Rule added (2001:db8::1/64, table 20) not found')
Ejemplo n.º 9
0
 def test_list_rules_ipv4(self):
     ip_lib.add_ip_rule(self.namespace, '192.168.0.1/24', table=10)
     rules_ipv4 = priv_ip_lib.list_ip_rules(self.namespace, 4)
     for rule in rules_ipv4:
         if rule['table'] == 10:
             self.assertEqual('192.168.0.1', rule['attrs']['FRA_SRC'])
             self.assertEqual(24, rule['src_len'])
             break
     else:
         self.fail('Rule added (192.168.0.1/24, table 10) not found')
Ejemplo n.º 10
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)
Ejemplo n.º 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)
Ejemplo n.º 12
0
    def _load_used_fip_information(self):
        """Load FIP from the FipRulePriorityAllocator state file.

        If, for any reason, the FIP is not stored in the state file, this
        method reads the namespace "ip rule" list and search for the
        corresponding fixed IP of the FIP. If present, this "ip rule" is
        (1) deleted, (2) a new rule priority is allocated and (3) the "ip rule"
        is written again with the new assigned priority.

        At the end of the method, all existing "ip rule" registers in
        FIP_RT_TBL table (where FIP rules are stored) that don't match with
        any register memoized in self._rule_priorities is deleted.
        """
        ex_gw_port = self.get_ex_gw_port()
        if not ex_gw_port:
            return

        fip_ns = self.agent.get_fip_ns(ex_gw_port['network_id'])
        for fip in self.get_floating_ips():
            floating_ip = fip['floating_ip_address']
            fixed_ip = fip['fixed_ip_address']
            if not fixed_ip:
                continue

            rule_pr = fip_ns.lookup_rule_priority(floating_ip)
            if rule_pr:
                self.floating_ips_dict[floating_ip] = (fixed_ip, rule_pr)
                continue

            rule_pr = fip_ns.allocate_rule_priority(floating_ip)
            ip_lib.add_ip_rule(self.ns_name,
                               fixed_ip,
                               table=dvr_fip_ns.FIP_RT_TBL,
                               priority=rule_pr)
            self.floating_ips_dict[floating_ip] = (fixed_ip, rule_pr)

        self._cleanup_unused_fip_ip_rules()
Ejemplo n.º 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)
Ejemplo n.º 14
0
 def _add_interface_routing_rule_to_router_ns(self, router_port):
     for subnet in router_port['subnets']:
         rtr_port_cidr = subnet['cidr']
         ip_lib.add_ip_rule(namespace=self.ns_name, ip=rtr_port_cidr,
                            table=dvr_fip_ns.FIP_RT_TBL,
                            priority=dvr_fip_ns.FAST_PATH_EXIT_PR)
Ejemplo n.º 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)