Source code for faucet.valve_pipeline

"""Manages movement of packets through the faucet pipeline."""

# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
# Copyright (C) 2015 Brad Cowie, Christopher Lorier and Joe Stringer.
# Copyright (C) 2015 Research and Education Advanced Network New Zealand Ltd.
# Copyright (C) 2015--2018 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 faucet.faucet_metadata as faucet_md
from faucet import valve_of
from faucet.valve_manager_base import ValveManagerBase

[docs]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.classification_table = dp.classification_table() self.output_table = dp.output_table() self.egress_table = None if dp.egress_pipeline: self.egress_table = dp.tables['egress'] self.filter_priority = dp.highest_priority + 1 self.select_priority = dp.highest_priority
[docs] 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 """ inst = [self.output_table.goto_this()] if actions is not None: inst.append(valve_of.apply_actions(actions)) return inst
[docs] def output(self, port, vlan): """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 returns: list of Instructions """ instructions = [] if self.egress_table: metadata, metadata_mask = faucet_md.get_egress_metadata( port.number, vlan.vid) instructions.extend(valve_of.metadata_goto_table( metadata, metadata_mask, self.egress_table)) else: instructions.append(valve_of.apply_actions(vlan.output_port(port))) return instructions
[docs] def initialise_tables(self): """Install rules to initialise the classification_table""" ofmsgs = [] # drop broadcast sources if self.dp.drop_broadcast_source_address: ofmsgs.extend(self.filter_packets( self.classification_table, {'eth_src': valve_of.mac.BROADCAST_STR} )) ofmsgs.extend(self.filter_packets( self.classification_table, {'eth_type': valve_of.ECTP_ETH_TYPE})) # antispoof for FAUCET's MAC address # TODO: antispoof for controller IPs on this VLAN, too. if self.dp.drop_spoofed_faucet_mac: for vlan in list(self.dp.vlans.values()): ofmsgs.extend(self.filter_packets( self.classification_table, {'eth_src': vlan.faucet_mac})) return ofmsgs
[docs] def filter_packets(self, _target_table, match_dict): """get a list of flow modification messages to filter packets from the pipeline. args: _target_table: the table requesting the filtering match_dict: a dictionary specifying the match fields """ return [self.classification_table.flowdrop( self.classification_table.match(**match_dict), priority=(self.filter_priority))]
[docs] def select_packets(self, target_table, match_dict, actions=None): """retrieve rules to redirect packets matching match_dict to table""" inst = [target_table.goto_this()] if actions is not None: inst.append(valve_of.apply_actions(actions)) return [self.classification_table.flowmod( self.classification_table.match(**match_dict), priority=self.select_priority, inst=inst)]