<commit_before>"""Manages movement of packets through the faucet pipeline."""

# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
# Copyright (C) 2015 <NAME>, <NAME> and <NAME>.
# Copyright (C) 2015 Research and Education Advanced Network New Zealand Ltd.
# Copyright (C) 2015--2019 The Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import copy
import functools
import faucet.faucet_metadata as faucet_md
from faucet import valve_of
from faucet.valve_manager_base import ValveManagerBase


class ValvePipeline(ValveManagerBase):
    """Responsible for maintaing the integrity of the Faucet pipeline for a
    single valve.

    Controls what packets a module sees in its tables and how it can pass
    packets through the pipeline.

    Responsible for installing flows in the vlan, egress and classification
    tables"""

    def __init__(self, dp):
        self.dp = dp
        self.vlan_table = dp.tables['vlan']
        self.classification_table = dp.classification_table()
        self.output_table = dp.output_table()
        self.egress_table = None
        self.egress_acl_table = None
        if dp.egress_pipeline:
            self.egress_table = dp.tables['egress']
            self.egress_acl_table = dp.tables.get('egress_acl')
        self.filter_priority = self._FILTER_PRIORITY
        self.select_priority = self._HIGH_PRIORITY

    @staticmethod
    @functools.lru_cache()
    def _accept_to_table(table, actions):
        inst = [table.goto_this()]
        if actions:
            inst.append(valve_of.apply_actions(actions))
        return tuple(inst)

    @functools.lru_cache()
    def accept_to_vlan(self, actions=None):
        """Get instructions to forward packet through the pipeline to
        vlan table.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.vlan_table, actions)

    @functools.lru_cache()
    def accept_to_classification(self, actions=None):
        """Get instructions to forward packet through the pipeline to
        classification table.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.classification_table, actions)

    @functools.lru_cache()
    def accept_to_l2_forwarding(self, actions=None):
        """Get instructions to forward packet through the pipeline to l2
        forwarding.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.output_table, actions)

    @functools.lru_cache()
    def accept_to_egress(self, actions=None):
        """Get instructions to forward packet through the pipeline to egress
        table

        Raises an assertion error if egress pipeline is not configured

        args:
            actions: (optional) list of actions to apply to the packet
        returns:
            list of instructions:
        """
        assert self.egress_table is not None
        return self._accept_to_table(self.egress_table, actions)

    def output(self, port, vlan, hairpin=False, external_forwarding_requested=None):
        """Get instructions list to output a packet through the regular
        pipeline.

        args:
            port: Port object of port to output packet to
            vlan: Vlan object of vlan to output packet on
            hairpin: if True, hairpinning is required
            apply_egress_acl: if True the packet will be sent to the egress acl
                table before being output
        returns:
            list of Instructions
        """
        instructions = []
        if self.egress_table:
            metadata, metadata_mask = faucet_md.get_egress_metadata(<commit_msg>Update valve_pipeline.py<commit_after>"""Manages movement of packets through the faucet pipeline."""

# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
# Copyright (C) 2015 <NAME>, <NAME> and <NAME>.
# Copyright (C) 2015 Research and Education Advanced Network New Zealand Ltd.
# Copyright (C) 2015--2019 The Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import copy
import functools
import faucet.faucet_metadata as faucet_md
from faucet import valve_of
from faucet.valve_manager_base import ValveManagerBase


class ValvePipeline(ValveManagerBase):
    """Responsible for maintaing the integrity of the Faucet pipeline for a
    single valve.

    Controls what packets a module sees in its tables and how it can pass
    packets through the pipeline.

    Responsible for installing flows in the vlan, egress and classification
    tables"""

    def __init__(self, dp):
        self.dp = dp
        self.vlan_table = dp.tables['vlan']
        self.classification_table = dp.classification_table()
        self.output_table = dp.output_table()
        self.egress_table = None
        self.egress_acl_table = None
        if dp.egress_pipeline:
            self.egress_table = dp.tables['egress']
            self.egress_acl_table = dp.tables.get('egress_acl')
        self.filter_priority = self._FILTER_PRIORITY
        self.select_priority = self._HIGH_PRIORITY

    @staticmethod
    @functools.lru_cache(maxsize=1024)
    def _accept_to_table(table, actions):
        inst = [table.goto_this()]
        if actions:
            inst.append(valve_of.apply_actions(actions))
        return tuple(inst)

    @functools.lru_cache(maxsize=1024)
    def accept_to_vlan(self, actions=None):
        """Get instructions to forward packet through the pipeline to
        vlan table.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.vlan_table, actions)

    @functools.lru_cache(maxsize=1024)
    def accept_to_classification(self, actions=None):
        """Get instructions to forward packet through the pipeline to
        classification table.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.classification_table, actions)

    @functools.lru_cache(maxsize=1024)
    def accept_to_l2_forwarding(self, actions=None):
        """Get instructions to forward packet through the pipeline to l2
        forwarding.
        args:
            actions: (optional) list of actions to apply to packet.
        returns:
            list of instructions
        """
        return self._accept_to_table(self.output_table, actions)

    @functools.lru_cache(maxsize=1024)
    def accept_to_egress(self, actions=None):
        """Get instructions to forward packet through the pipeline to egress
        table

        Raises an assertion error if egress pipeline is not configured

        args:
            actions: (optional) list of actions to apply to the packet
        returns:
            list of instructions:
        """
        assert self.egress_table is not None
        return self._accept_to_table(self.egress_table, actions)

    def output(self, port, vlan, hairpin=False, external_forwarding_requested=None):
        """Get instructions list to output a packet through the regular
        pipeline.

        args:
            port: Port object of port to output packet to
            vlan: Vlan object of vlan to output packet on
            hairpin: if True, hairpinning is required
            apply_egress_acl: if True the packet will be sent to the egress acl
                table before being output
        returns:
            list of Instructions
        """
        instructions = []
        if self.egress_table:
            metadata, metadata_mask = faucet_md.get_egress_metadata(
{'fraction_non_alphanumeric': 0.06722689075630252, 'fraction_numerical': 0.008067226890756302, 'mean_word_length': 2.708350643955131, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5252339', 'n_tokens_mistral': 2449, 'n_tokens_neox': 2356, 'n_words': 852}