Example #1
0
    def _process_metering_rule_action_based_on_ns(self, router, action,
                                                  ext_dev, im):
        '''Process metering rule actions based specific namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)

                exists = rm.metering_labels.get(label_id)
                if action == 'create' and not exists:
                    self._create_metering_label_chain(rm, label_chain,
                                                      rules_chain)
                    rm.metering_labels[label_id] = label

                rule = label.get('rule')
                if rule:
                    if action == 'create':
                        self._process_metering_label_rule_add(
                            rule, ext_dev, label_chain, rules_chain, im)
                    elif action == 'delete':
                        self._process_metering_label_rule_delete(
                            rule, ext_dev, label_chain, rules_chain, im)
Example #2
0
    def _enable_policy_chain(self, fwid, ipt_if_prefix):
        bname = iptables_manager.binary_name
        ipt_mgr = ipt_if_prefix['ipt']
        if_prefix = ipt_if_prefix['if_prefix']

        for (ver, tbl) in [(IPV4, ipt_mgr.ipv4['filter']),
                           (IPV6, ipt_mgr.ipv6['filter'])]:
            for direction in [INGRESS_DIRECTION, EGRESS_DIRECTION]:
                chain_name = self._get_chain_name(fwid, ver, direction)
                chain_name = iptables_manager.get_chain_name(chain_name)
                if chain_name in tbl.chains:
                    jump_rule = ['%s %s+ -j %s-%s' % (IPTABLES_DIR[direction],
                        if_prefix, bname, chain_name)]
                    self._add_rules_to_chain(ipt_mgr,
                        ver, 'FORWARD', jump_rule)

        #jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ['-o %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)

        #jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ['-i %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)
Example #3
0
    def _enable_policy_chain(self, fwid, ipt_if_prefix):
        bname = iptables_manager.binary_name
        ipt_mgr = ipt_if_prefix['ipt']
        if_prefix = ipt_if_prefix['if_prefix']

        for (ver, tbl) in [(IPV4, ipt_mgr.ipv4['filter']),
                           (IPV6, ipt_mgr.ipv6['filter'])]:
            for direction in [INGRESS_DIRECTION, EGRESS_DIRECTION]:
                chain_name = self._get_chain_name(fwid, ver, direction)
                chain_name = iptables_manager.get_chain_name(chain_name)
                if chain_name in tbl.chains:
                    jump_rule = [
                        '%s %s+ -j %s-%s' %
                        (IPTABLES_DIR[direction], if_prefix, bname, chain_name)
                    ]
                    self._add_rules_to_chain(ipt_mgr, ver, 'FORWARD',
                                             jump_rule)

        #jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ['-o %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)

        #jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ['-i %s+ -j %s-%s' % (if_prefix, bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, 'FORWARD', jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, 'FORWARD', jump_rule)
Example #4
0
    def _process_associate_metering_label(self, router):
        self._update_router(router)
        rm = self.routers.get(router['id'])

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)
                rm.iptables_manager.ipv4['filter'].add_chain(label_chain,
                                                             wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)
                rm.iptables_manager.ipv4['filter'].add_chain(rules_chain,
                                                             wrap=False)
                rm.iptables_manager.ipv4['filter'].add_rule(TOP_CHAIN,
                                                            '-j ' +
                                                            rules_chain,
                                                            wrap=False)

                rm.iptables_manager.ipv4['filter'].add_rule(label_chain,
                                                            '',
                                                            wrap=False)

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(rm, rules, label_chain,
                                                       rules_chain)

                rm.metering_labels[label_id] = label
Example #5
0
    def _process_disassociate_metering_label(self, router):
        rm = self.routers.get(router['id'])
        if not rm:
            return

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                if label_id not in rm.metering_labels:
                    continue

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)
                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)

                rm.iptables_manager.ipv4['filter'].remove_chain(label_chain,
                                                                wrap=False)
                rm.iptables_manager.ipv4['filter'].remove_chain(rules_chain,
                                                                wrap=False)

                del rm.metering_labels[label_id]
    def _process_metering_rule_action(self, router, action):
        rm = self.routers.get(router['id'])
        if not rm:
            return
        ext_dev = self.get_external_device_name(rm.router['gw_port_id'])
        if not ext_dev:
            return
        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)
                rule = label.get('rule')
                if rule:
                    if action == 'create':
                        self._process_metering_label_rule_add(rm, rule,
                                                              ext_dev,
                                                              label_chain,
                                                              rules_chain)
                    elif action == 'delete':
                        self._process_metering_label_rule_delete(rm, rule,
                                                                 ext_dev,
                                                                 label_chain,
                                                                 rules_chain)
Example #7
0
    def _process_associate_metering_label(self, router):
        self._update_router(router)
        rm = self.routers.get(router['id'])

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)
                rm.iptables_manager.ipv4['filter'].add_chain(label_chain,
                                                             wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)
                rm.iptables_manager.ipv4['filter'].add_chain(rules_chain,
                                                             wrap=False)
                rm.iptables_manager.ipv4['filter'].add_rule(TOP_CHAIN, '-j ' +
                                                            rules_chain,
                                                            wrap=False)

                rm.iptables_manager.ipv4['filter'].add_rule(label_chain,
                                                            '',
                                                            wrap=False)

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(rm, rules,
                                                       label_chain,
                                                       rules_chain)

                rm.metering_labels[label_id] = label
Example #8
0
    def _process_metering_rule_action(self, router, action):
        rm = self.routers.get(router['id'])
        if not rm:
            return
        ext_dev = self.get_external_device_name(rm.router['gw_port_id'])
        if not ext_dev:
            return
        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)
                rule = label.get('rule')
                if rule:
                    if action == 'create':
                        self._process_metering_label_rule_add(rm, rule,
                                                              ext_dev,
                                                              label_chain,
                                                              rules_chain)
                    elif action == 'delete':
                        self._process_metering_label_rule_delete(rm, rule,
                                                                 ext_dev,
                                                                 label_chain,
                                                                 rules_chain)
Example #9
0
    def _process_disassociate_metering_label(self, router):
        rm = self.routers.get(router['id'])
        if not rm:
            return

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                if label_id not in rm.metering_labels:
                    continue

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)
                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)

                rm.iptables_manager.ipv4['filter'].remove_chain(label_chain,
                                                                wrap=False)
                rm.iptables_manager.ipv4['filter'].remove_chain(rules_chain,
                                                                wrap=False)

                del rm.metering_labels[label_id]
Example #10
0
    def _process_metering_rule_action_based_on_ns(
        self, router, action, ext_dev, im):
        '''Process metering rule actions based specific namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)

                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)

                exists = rm.metering_labels.get(label_id)
                if action == 'create' and not exists:
                    self._create_metering_label_chain(rm,
                                                      label_chain,
                                                      rules_chain)
                    rm.metering_labels[label_id] = label

                rule = label.get('rule')
                if rule:
                    if action == 'create':
                        self._process_metering_label_rule_add(
                            rule, ext_dev, label_chain, rules_chain, im)
                    elif action == 'delete':
                        self._process_metering_label_rule_delete(
                            rule, ext_dev, label_chain, rules_chain, im)
Example #11
0
    def _process_ns_specific_metering_label(self, router, ext_dev, im):
        '''Process metering label based on the associated namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)

                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)

                exists = rm.metering_labels.get(label_id)
                if not exists:
                    self._create_metering_label_chain(rm,
                                                      label_chain,
                                                      rules_chain)
                    rm.metering_labels[label_id] = label

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(
                        rules, label_chain, rules_chain, ext_dev, im)
 def test_get_chain_name(self):
     name = "0123456789" * 5
     # 28 chars is the maximum length of iptables chain name.
     self.assertEqual(iptables_manager.get_chain_name(name, wrap=False), name[:28])
     # 11 chars is the maximum length of chain name of iptable_manager
     # if binary_name is prepended.
     self.assertEqual(iptables_manager.get_chain_name(name, wrap=True), name[:11])
Example #13
0
    def _process_ns_specific_metering_label(self, router, ext_dev, im):
        '''Process metering label based on the associated namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)

                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)

                exists = rm.metering_labels.get(label_id)
                if not exists:
                    self._create_metering_label_chain(rm, label_chain,
                                                      rules_chain)
                    rm.metering_labels[label_id] = label

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(rules, label_chain,
                                                       rules_chain, ext_dev,
                                                       im)
 def test_get_chain_name(self):
     name = '0123456789' * 5
     # 28 chars is the maximum length of iptables chain name.
     self.assertEqual(iptables_manager.get_chain_name(name, wrap=False),
                      name[:28])
     # 11 chars is the maximum length of chain name of iptable_manager
     # if binary_name is prepended.
     self.assertEqual(iptables_manager.get_chain_name(name, wrap=True),
                      name[:11])
Example #15
0
    def get_traffic_counters(self, context, routers):
        accs = {}
        routers_to_reconfigure = set()
        for router in routers:
            rm = self.routers.get(router["id"])
            if not rm:
                continue

            for label_id, label in rm.metering_labels.items():
                try:
                    chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL + label_id, wrap=False)

                    chain_acc = rm.iptables_manager.get_traffic_counters(chain, wrap=False, zero=True)
                except RuntimeError:
                    LOG.exception(_LE("Failed to get traffic counters, " "router: %s"), router)
                    routers_to_reconfigure.add(router["id"])
                    continue

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {"pkts": 0, "bytes": 0})

                acc["pkts"] += chain_acc["pkts"]
                acc["bytes"] += chain_acc["bytes"]

                accs[label_id] = acc

        for router_id in routers_to_reconfigure:
            del self.routers[router_id]

        return accs
Example #16
0
    def _process_ns_specific_disassociate_metering_label(self, router, im):
        '''Disassociate metering label based on specific namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                if label_id not in rm.metering_labels:
                    continue

                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)
                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)
                im.ipv4['filter'].remove_chain(label_chain, wrap=False)
                im.ipv4['filter'].remove_chain(rules_chain, wrap=False)
Example #17
0
    def get_traffic_counters(self, context, routers):
        accs = {}
        for router in routers:
            rm = self.routers.get(router['id'])
            if not rm:
                continue

            for label_id, label in rm.metering_labels.items():
                try:
                    chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                            LABEL +
                                                            label_id,
                                                            wrap=False)

                    chain_acc = rm.iptables_manager.get_traffic_counters(
                        chain, wrap=False, zero=True)
                except RuntimeError:
                    LOG.exception(_LE('Failed to get traffic counters, '
                                      'router: %s'), router)
                    continue

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {'pkts': 0, 'bytes': 0})

                acc['pkts'] += chain_acc['pkts']
                acc['bytes'] += chain_acc['bytes']

                accs[label_id] = acc

        return accs
    def get_traffic_counters(self, context, routers):
        accs = {}
        for router in routers:
            rm = self.routers.get(router['id'])
            if not rm:
                continue

            for label_id, label in rm.metering_labels.items():
                try:
                    chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
                                                            label_id,
                                                            wrap=False)

                    chain_acc = rm.iptables_manager.get_traffic_counters(
                        chain, wrap=False, zero=True)
                except RuntimeError:
                    LOG.exception(
                        _LE('Failed to get traffic counters, '
                            'router: %s'), router)
                    continue

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {'pkts': 0, 'bytes': 0})

                acc['pkts'] += chain_acc['pkts']
                acc['bytes'] += chain_acc['bytes']

                accs[label_id] = acc

        return accs
    def test_rule_with_wrap_target(self):
        name = '0123456789' * 5
        wrap = "%s-%s" % (iptables_manager.binary_name,
                          iptables_manager.get_chain_name(name))

        iptables_args = {'bn': iptables_manager.binary_name,
                         'wrap': wrap}

        filter_dump_mod = ('# Generated by iptables_manager\n'
                           '*filter\n'
                           ':neutron-filter-top - [0:0]\n'
                           ':%(bn)s-FORWARD - [0:0]\n'
                           ':%(bn)s-INPUT - [0:0]\n'
                           ':%(bn)s-local - [0:0]\n'
                           ':%(wrap)s - [0:0]\n'
                           ':%(bn)s-OUTPUT - [0:0]\n'
                           '[0:0] -A FORWARD -j neutron-filter-top\n'
                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
                           '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j '
                           '%(wrap)s\n'
                           'COMMIT\n'
                           '# Completed by iptables_manager\n'
                           % iptables_args)

        expected_calls_and_values = [
            (mock.call(['iptables-save', '-c'],
                       root_helper=self.root_helper),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=NAT_DUMP + filter_dump_mod,
                       root_helper=self.root_helper),
             None),
            (mock.call(['iptables-save', '-c'],
                       root_helper=self.root_helper),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=NAT_DUMP + FILTER_DUMP,
                       root_helper=self.root_helper),
             None),
        ]
        tools.setup_mock_calls(self.execute, expected_calls_and_values)

        self.iptables.ipv4['filter'].add_chain(name)
        self.iptables.ipv4['filter'].add_rule('INPUT',
                                              '-s 0/0 -d 192.168.0.2 -j'
                                              ' $%s' % name)
        self.iptables.apply()

        self.iptables.ipv4['filter'].remove_rule('INPUT',
                                                 '-s 0/0 -d 192.168.0.2 -j'
                                                 ' $%s' % name)
        self.iptables.ipv4['filter'].remove_chain(name)

        self.iptables.apply()

        tools.verify_mock_calls(self.execute, expected_calls_and_values)
Example #20
0
    def test_rule_with_wrap_target(self):
        name = '0123456789' * 5
        wrap = "%s-%s" % (iptables_manager.binary_name,
                          iptables_manager.get_chain_name(name))

        iptables_args = {'bn': iptables_manager.binary_name,
                         'wrap': wrap}

        filter_dump_mod = ('# Generated by iptables_manager\n'
                           '*filter\n'
                           ':neutron-filter-top - [0:0]\n'
                           ':%(bn)s-FORWARD - [0:0]\n'
                           ':%(bn)s-INPUT - [0:0]\n'
                           ':%(bn)s-local - [0:0]\n'
                           ':%(wrap)s - [0:0]\n'
                           ':%(bn)s-OUTPUT - [0:0]\n'
                           '[0:0] -A FORWARD -j neutron-filter-top\n'
                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
                           '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j '
                           '%(wrap)s\n'
                           'COMMIT\n'
                           '# Completed by iptables_manager\n'
                           % iptables_args)

        expected_calls_and_values = [
            (mock.call(['iptables-save', '-c'],
                       root_helper=self.root_helper),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=NAT_DUMP + filter_dump_mod,
                       root_helper=self.root_helper),
             None),
            (mock.call(['iptables-save', '-c'],
                       root_helper=self.root_helper),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=NAT_DUMP + FILTER_DUMP,
                       root_helper=self.root_helper),
             None),
        ]
        tools.setup_mock_calls(self.execute, expected_calls_and_values)

        self.iptables.ipv4['filter'].add_chain(name)
        self.iptables.ipv4['filter'].add_rule('INPUT',
                                              '-s 0/0 -d 192.168.0.2 -j'
                                              ' $%s' % name)
        self.iptables.apply()

        self.iptables.ipv4['filter'].remove_rule('INPUT',
                                                 '-s 0/0 -d 192.168.0.2 -j'
                                                 ' $%s' % name)
        self.iptables.ipv4['filter'].remove_chain(name)

        self.iptables.apply()

        tools.verify_mock_calls(self.execute, expected_calls_and_values)
Example #21
0
    def remove_rule(self, chain, rule, wrap=True, top=False, comment=None):
        """Remove a rule from a chain.

        Note: The rule must be exactly identical to the one that was added.
        You cannot switch arguments around like you can with the ebtables
        CLI tool.

        """
        chain = get_chain_name(chain, wrap)
        try:
            if '$' in rule:
                rule = ' '.join(
                    self._wrap_target_chain(e, wrap) for e in rule.split(' '))

            self.rules.remove(EbtablesRule(chain, rule, wrap, top,
                                           self.wrap_name,
                                           comment=comment))
            if not wrap:
                self.remove_rules.append(str(EbtablesRule(chain, rule, wrap,
                                                          top, self.wrap_name,
                                                          comment=comment)))
        except ValueError:
            LOG.warning('Tried to remove rule that was not there:'
                        ' %(chain)r %(rule)r %(wrap)r %(top)r',
                        {'chain': chain, 'rule': rule,
                         'top': top, 'wrap': wrap})
Example #22
0
    def _process_ns_specific_disassociate_metering_label(self, router, im):
        '''Disassociate metering label based on specific namespaces.'''
        rm = self.routers.get(router['id'])
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']
                if label_id not in rm.metering_labels:
                    continue

                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)
                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)
                im.ipv4['filter'].remove_chain(label_chain, wrap=False)
                im.ipv4['filter'].remove_chain(rules_chain, wrap=False)
Example #23
0
    def get_traffic_counters(self, context, routers):
        accs = {}
        for router in routers:
            rm = self.routers.get(router['id'])
            if not rm:
                continue

            for label_id, label in rm.metering_labels.items():
                chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
                                                        label_id, wrap=False)

                chain_acc = rm.iptables_manager.get_traffic_counters(
                    chain, wrap=False, zero=True)

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {'pkts': 0, 'bytes': 0})

                acc['pkts'] += chain_acc['pkts']
                acc['bytes'] += chain_acc['bytes']

                accs[label_id] = acc

        return accs
Example #24
0
    def _update_metering_label_rules_based_on_ns(self, router, ext_dev, im):
        '''Update metering lable rules based on namespace.'''
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)
                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)
                im.ipv4['filter'].empty_chain(rules_chain, wrap=False)

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(
                        rules, label_chain, rules_chain, ext_dev, im)
Example #25
0
    def _update_metering_label_rules_based_on_ns(self, router, ext_dev, im):
        '''Update metering lable rules based on namespace.'''
        with IptablesManagerTransaction(im):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + LABEL + label_id, wrap=False)
                rules_chain = iptables_manager.get_chain_name(
                    WRAP_NAME + RULE + label_id, wrap=False)
                im.ipv4['filter'].empty_chain(rules_chain, wrap=False)

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(
                        rules, label_chain, rules_chain, ext_dev, im)
Example #26
0
    def _update_metering_label_rules(self, router):
        rm = self.routers.get(router["id"])
        if not rm:
            return

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label["id"]

                label_chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL + label_id, wrap=False)
                rules_chain = iptables_manager.get_chain_name(WRAP_NAME + RULE + label_id, wrap=False)
                rm.iptables_manager.ipv4["filter"].empty_chain(rules_chain, wrap=False)

                rules = label.get("rules")
                if rules:
                    self._process_metering_label_rules(rm, rules, label_chain, rules_chain)
Example #27
0
 def __init__(self, chain, rule, wrap=True, top=False,
              _binary_name=binary_name, tag=None, comment=None):
     self.chain = get_chain_name(chain, wrap)
     self.rule = rule
     self.wrap = wrap
     self.top = top
     self.wrap_name = _binary_name[:16]
     self.tag = tag
     self.comment = comment
Example #28
0
    def _enable_policy_chain(self, fwid, ipt_mgr):
        bname = iptables_manager.binary_name

        for (ver, tbl) in [(IPV4, ipt_mgr.ipv4["filter"]), (IPV6, ipt_mgr.ipv4["filter"])]:
            for direction in [INGRESS_DIRECTION, EGRESS_DIRECTION]:
                chain_name = self._get_chain_name(fwid, ver, direction)
                chain_name = iptables_manager.get_chain_name(chain_name)
                if chain_name in tbl.chains:
                    jump_rule = ["%s qr-+ -j %s-%s" % (IPTABLES_DIR[direction], bname, chain_name)]
                    self._add_rules_to_chain(ipt_mgr, ver, "FORWARD", jump_rule)

        # jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ["-o qr-+ -j %s-%s" % (bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, "FORWARD", jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, "FORWARD", jump_rule)

        # jump to DROP_ALL policy
        chain_name = iptables_manager.get_chain_name(FWAAS_DEFAULT_CHAIN)
        jump_rule = ["-i qr-+ -j %s-%s" % (bname, chain_name)]
        self._add_rules_to_chain(ipt_mgr, IPV4, "FORWARD", jump_rule)
        self._add_rules_to_chain(ipt_mgr, IPV6, "FORWARD", jump_rule)
    def _update_metering_label_rules(self, router):
        rm = self.routers.get(router['id'])
        if not rm:
            return

        with IptablesManagerTransaction(rm.iptables_manager):
            labels = router.get(constants.METERING_LABEL_KEY, [])
            for label in labels:
                label_id = label['id']

                label_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              LABEL + label_id,
                                                              wrap=False)
                rules_chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                              RULE + label_id,
                                                              wrap=False)
                rm.iptables_manager.ipv4['filter'].empty_chain(rules_chain,
                                                               wrap=False)

                rules = label.get('rules')
                if rules:
                    self._process_metering_label_rules(rm, rules, label_chain,
                                                       rules_chain)
Example #30
0
    def retrieve_traffic_counters(label_id, rm, router,
                                  routers_to_reconfigure):
        try:
            chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
                                                    label_id,
                                                    wrap=False)

            chain_acc = rm.iptables_manager.get_traffic_counters(chain,
                                                                 wrap=False,
                                                                 zero=True)
        except RuntimeError:
            LOG.exception('Failed to get traffic counters, '
                          'router: %s', router)
            routers_to_reconfigure.add(router['id'])
            return {}
        return chain_acc
Example #31
0
    def add_chain(self, name, wrap=True):
        """Adds a named chain to the table.

        The chain name is wrapped to be unique for the component creating
        it, so different components of Nova can safely create identically
        named chains without interfering with one another.

        At the moment, its wrapped name is <binary name>-<chain name>,
        so if neutron-openvswitch-agent creates a chain named 'OUTPUT',
        it'll actually end up being named 'neutron-openvswi-OUTPUT'.

        """
        name = get_chain_name(name, wrap)
        if wrap:
            self.chains.add(name)
        else:
            self.unwrapped_chains.add(name)
Example #32
0
    def retrieve_traffic_counters(label_id, rm, router,
                                  routers_to_reconfigure):
        try:
            chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
                                                    label_id,
                                                    wrap=False)

            chain_acc = rm.iptables_manager.get_traffic_counters(chain,
                                                                 wrap=False,
                                                                 zero=True)
        except RuntimeError as e:
            LOG.warning(
                'Failed to get traffic counters for router [%s] due '
                'to [%s]. This error message can happen when routers '
                'are migrated; therefore, most of the times they can '
                'be ignored.', router, e)

            routers_to_reconfigure.add(router['id'])
            return {}
        return chain_acc
Example #33
0
    def add_rule(self, chain, rule, wrap=True, top=False, tag=None,
                 comment=None):
        """Add a rule to the table.

        This is just like what you'd feed to ebtables, just without
        the '-A <chain name>' bit at the start.

        However, if you need to jump to one of your wrapped chains,
        prepend its name with a '$' which will ensure the wrapping
        is applied correctly.

        """
        chain = get_chain_name(chain, wrap)
        if wrap and chain not in self.chains:
            raise LookupError(_('Unknown chain: %r') % chain)

        if '$' in rule:
            rule = ' '.join(
                self._wrap_target_chain(e, wrap) for e in rule.split(' '))

        self.rules.append(EbtablesRule(chain, rule, wrap, top, self.wrap_name,
                                       tag, comment))
Example #34
0
    def get_traffic_counters(self, context, routers):
        accs = {}
        routers_to_reconfigure = set()
        for router in routers:
            rm = self.routers.get(router['id'])
            if not rm:
                continue

            for label_id in rm.metering_labels:
                try:
                    chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL +
                                                            label_id,
                                                            wrap=False)

                    chain_acc = rm.iptables_manager.get_traffic_counters(
                        chain, wrap=False, zero=True)
                except RuntimeError:
                    LOG.exception(
                        'Failed to get traffic counters, '
                        'router: %s', router)
                    routers_to_reconfigure.add(router['id'])
                    continue

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {'pkts': 0, 'bytes': 0})

                acc['pkts'] += chain_acc['pkts']
                acc['bytes'] += chain_acc['bytes']

                accs[label_id] = acc

        for router_id in routers_to_reconfigure:
            del self.routers[router_id]

        return accs
Example #35
0
    def get_traffic_counters(self, context, routers):
        accs = {}
        routers_to_reconfigure = set()
        for router in routers:
            rm = self.routers.get(router['id'])
            if not rm:
                continue

            for label_id in rm.metering_labels:
                try:
                    chain = iptables_manager.get_chain_name(WRAP_NAME +
                                                            LABEL +
                                                            label_id,
                                                            wrap=False)

                    chain_acc = rm.iptables_manager.get_traffic_counters(
                        chain, wrap=False, zero=True)
                except RuntimeError:
                    LOG.exception('Failed to get traffic counters, '
                                  'router: %s', router)
                    routers_to_reconfigure.add(router['id'])
                    continue

                if not chain_acc:
                    continue

                acc = accs.get(label_id, {'pkts': 0, 'bytes': 0})

                acc['pkts'] += chain_acc['pkts']
                acc['bytes'] += chain_acc['bytes']

                accs[label_id] = acc

        for router_id in routers_to_reconfigure:
            del self.routers[router_id]

        return accs
Example #36
0
    def remove_chain(self, name, wrap=True):
        """Remove named chain.

        This removal "cascades". All rule in the chain are removed, as are
        all rules in other chains that jump to it.

        If the chain is not found, this is merely logged.

        """
        name = get_chain_name(name, wrap)
        chain_set = self._select_chain_set(wrap)

        if name not in chain_set:
            LOG.debug('Attempted to remove chain %s which does not exist',
                      name)
            return

        chain_set.remove(name)

        if not wrap:
            # non-wrapped chains and rules need to be dealt with specially,
            # so we keep a list of them to be iterated over in apply()
            self.remove_chains.add(name)

            # Add rules to remove that have a matching chain name or
            # a matching jump chain
            jump_snippet = '-j %s' % name
            self.remove_rules += [str(r) for r in self.rules
                                  if r.chain == name or jump_snippet in r.rule]
        else:
            jump_snippet = '-j %s-%s' % (self.wrap_name, name)

        # Remove rules from list that have a matching chain name or
        # a matching jump chain
        self.rules = [r for r in self.rules
                      if r.chain != name and jump_snippet not in r.rule]
Example #37
0
 def _port_chain_name(self, port, direction):
     return iptables_manager.get_chain_name("%s%s" % (CHAIN_NAME_PREFIX[direction], port["device"]))
Example #38
0
 def _get_action_chain(self, name):
     binary_name = iptables_manager.binary_name
     chain_name = iptables_manager.get_chain_name(name)
     return '%s-%s' % (binary_name, chain_name)
 def _get_action_chain(self, name):
     binary_name = iptables_manager.binary_name
     chain_name = iptables_manager.get_chain_name(name)
     return '%s-%s' % (binary_name, chain_name)
    def _test_rule_with_wrap_target_helper(self, use_ipv6):
        self.iptables = iptables_manager.IptablesManager(
            use_ipv6=use_ipv6)
        self.execute = mock.patch.object(self.iptables, "execute").start()

        name = '0123456789' * 5
        wrap = "%s-%s" % (iptables_manager.binary_name,
                          iptables_manager.get_chain_name(name))

        iptables_args = {'bn': iptables_manager.binary_name,
                         'wrap': wrap}

        filter_dump_mod = ('# Generated by iptables_manager\n'
                           '*filter\n'
                           ':neutron-filter-top - [0:0]\n'
                           ':%(wrap)s - [0:0]\n'
                           ':%(bn)s-FORWARD - [0:0]\n'
                           ':%(bn)s-INPUT - [0:0]\n'
                           ':%(bn)s-OUTPUT - [0:0]\n'
                           ':%(bn)s-local - [0:0]\n'
                           '[0:0] -A FORWARD -j neutron-filter-top\n'
                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
                           '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j '
                           '%(wrap)s\n'
                           'COMMIT\n'
                           '# Completed by iptables_manager\n'
                           % iptables_args)

        expected_calls_and_values = [
            (mock.call(['iptables-save', '-c'],
                       run_as_root=True),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
                                      filter_dump_mod),
                       run_as_root=True),
             None),
            (mock.call(['iptables-save', '-c'],
                       run_as_root=True),
             ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
                                      FILTER_DUMP),
                       run_as_root=True),
             None),
        ]
        if use_ipv6:
            self._extend_with_ip6tables_filter(expected_calls_and_values,
                                               FILTER_DUMP)

        tools.setup_mock_calls(self.execute, expected_calls_and_values)

        self.iptables.ipv4['filter'].add_chain(name)
        self.iptables.ipv4['filter'].add_rule('INPUT',
                                              '-s 0/0 -d 192.168.0.2 -j'
                                              ' $%s' % name)
        self.iptables.apply()

        self.iptables.ipv4['filter'].remove_rule('INPUT',
                                                 '-s 0/0 -d 192.168.0.2 -j'
                                                 ' $%s' % name)
        self.iptables.ipv4['filter'].remove_chain(name)

        self.iptables.apply()

        tools.verify_mock_calls(self.execute, expected_calls_and_values)
Example #41
0
 def _get_chain_rules(self, chain, wrap):
     chain = get_chain_name(chain, wrap)
     return [rule for rule in self.rules
             if rule.chain == chain and rule.wrap == wrap]
Example #42
0
    def _test_rule_with_wrap_target_helper(self, use_ipv6):
        self.iptables = iptables_manager.IptablesManager(root_helper=self.root_helper, use_ipv6=use_ipv6)
        self.execute = mock.patch.object(self.iptables, "execute").start()

        name = "0123456789" * 5
        wrap = "%s-%s" % (iptables_manager.binary_name, iptables_manager.get_chain_name(name))

        iptables_args = {"bn": iptables_manager.binary_name, "wrap": wrap}

        filter_dump_mod = (
            "# Generated by iptables_manager\n"
            "*filter\n"
            ":neutron-filter-top - [0:0]\n"
            ":%(wrap)s - [0:0]\n"
            ":%(bn)s-FORWARD - [0:0]\n"
            ":%(bn)s-INPUT - [0:0]\n"
            ":%(bn)s-OUTPUT - [0:0]\n"
            ":%(bn)s-local - [0:0]\n"
            "[0:0] -A FORWARD -j neutron-filter-top\n"
            "[0:0] -A OUTPUT -j neutron-filter-top\n"
            "[0:0] -A neutron-filter-top -j %(bn)s-local\n"
            "[0:0] -A INPUT -j %(bn)s-INPUT\n"
            "[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n"
            "[0:0] -A FORWARD -j %(bn)s-FORWARD\n"
            "[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j "
            "%(wrap)s\n"
            "COMMIT\n"
            "# Completed by iptables_manager\n" % iptables_args
        )

        expected_calls_and_values = [
            (mock.call(["iptables-save", "-c"], root_helper=self.root_helper), ""),
            (
                mock.call(
                    ["iptables-restore", "-c"],
                    process_input=RAW_DUMP + NAT_DUMP + filter_dump_mod,
                    root_helper=self.root_helper,
                ),
                None,
            ),
            (mock.call(["iptables-save", "-c"], root_helper=self.root_helper), ""),
            (
                mock.call(
                    ["iptables-restore", "-c"],
                    process_input=RAW_DUMP + NAT_DUMP + FILTER_DUMP,
                    root_helper=self.root_helper,
                ),
                None,
            ),
        ]
        if use_ipv6:
            self._extend_with_ip6tables_filter(expected_calls_and_values, FILTER_DUMP)

        tools.setup_mock_calls(self.execute, expected_calls_and_values)

        self.iptables.ipv4["filter"].add_chain(name)
        self.iptables.ipv4["filter"].add_rule("INPUT", "-s 0/0 -d 192.168.0.2 -j" " $%s" % name)
        self.iptables.apply()

        self.iptables.ipv4["filter"].remove_rule("INPUT", "-s 0/0 -d 192.168.0.2 -j" " $%s" % name)
        self.iptables.ipv4["filter"].remove_chain(name)

        self.iptables.apply()

        tools.verify_mock_calls(self.execute, expected_calls_and_values)
Example #43
0
    def _test_rule_with_wrap_target_helper(self, use_ipv6):
        self.iptables = iptables_manager.IptablesManager(use_ipv6=use_ipv6)
        self.execute = mock.patch.object(self.iptables, "execute").start()

        name = '0123456789' * 5
        wrap = "%s-%s" % (iptables_manager.binary_name,
                          iptables_manager.get_chain_name(name))

        iptables_args = {'bn': iptables_manager.binary_name, 'wrap': wrap}

        filter_dump_mod = ('# Generated by iptables_manager\n'
                           '*filter\n'
                           ':neutron-filter-top - [0:0]\n'
                           ':%(wrap)s - [0:0]\n'
                           ':%(bn)s-FORWARD - [0:0]\n'
                           ':%(bn)s-INPUT - [0:0]\n'
                           ':%(bn)s-OUTPUT - [0:0]\n'
                           ':%(bn)s-local - [0:0]\n'
                           '[0:0] -A FORWARD -j neutron-filter-top\n'
                           '[0:0] -A OUTPUT -j neutron-filter-top\n'
                           '[0:0] -A neutron-filter-top -j %(bn)s-local\n'
                           '[0:0] -A INPUT -j %(bn)s-INPUT\n'
                           '[0:0] -A OUTPUT -j %(bn)s-OUTPUT\n'
                           '[0:0] -A FORWARD -j %(bn)s-FORWARD\n'
                           '[0:0] -A %(bn)s-INPUT -s 0/0 -d 192.168.0.2 -j '
                           '%(wrap)s\n'
                           'COMMIT\n'
                           '# Completed by iptables_manager\n' % iptables_args)

        raw_dump = RAW_DUMP % IPTABLES_ARG

        expected_calls_and_values = [
            (mock.call(['iptables-save', '-c'], run_as_root=True), ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
                                      filter_dump_mod),
                       run_as_root=True), None),
            (mock.call(['iptables-save', '-c'], run_as_root=True), ''),
            (mock.call(['iptables-restore', '-c'],
                       process_input=(RAW_DUMP + NAT_DUMP + MANGLE_DUMP +
                                      FILTER_DUMP),
                       run_as_root=True), None),
        ]
        if use_ipv6:
            self._extend_with_ip6tables_filter(expected_calls_and_values,
                                               raw_dump + FILTER_DUMP)

        tools.setup_mock_calls(self.execute, expected_calls_and_values)

        self.iptables.ipv4['filter'].add_chain(name)
        self.iptables.ipv4['filter'].add_rule(
            'INPUT', '-s 0/0 -d 192.168.0.2 -j'
            ' $%s' % name)
        self.iptables.apply()

        self.iptables.ipv4['filter'].remove_rule(
            'INPUT', '-s 0/0 -d 192.168.0.2 -j'
            ' $%s' % name)
        self.iptables.ipv4['filter'].remove_chain(name)

        self.iptables.apply()

        tools.verify_mock_calls(self.execute, expected_calls_and_values)
Example #44
0
 def _dscp_chain_name(self, direction, device):
     return iptables_manager.get_chain_name(
         "qos-%s%s" %
         (self.IPTABLES_DIRECTION_PREFIX[direction], device[3:]))
Example #45
0
    def _wrap_target_chain(self, s, wrap):
        if s.startswith('$'):
            s = ('%s-%s' % (self.wrap_name, get_chain_name(s[1:], wrap)))

        return s
Example #46
0
 def _port_chain_name(self, port, direction):
     return iptables_manager.get_chain_name(
         '%s%s' % (CHAIN_NAME_PREFIX[direction], port['device']))
Example #47
0
 def _dscp_chain_name(self, direction, device):
     return iptables_manager.get_chain_name(
         "qos-%s%s" % (self.IPTABLES_DIRECTION_PREFIX[direction],
                       device[3:]))