/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.
 */

#include <core.p4>
#include <v1model.p4>

#include "../header.p4"
#include "../action.p4"

control Filtering (
    inout parsed_headers_t hdr,
    inout fabric_metadata_t fabric_metadata,
    inout standard_metadata_t standard_metadata) {

    /*
     * Ingress Port VLAN Table.
     * Process packets for different interfaces (Port number + VLAN).
     * For example, an untagged packet will be tagged when it entered to an
     * interface with untagged VLAN configuration.
     */
    direct_counter(CounterType.packets_and_bytes) ingress_port_vlan_counter;

    action drop() {
        mark_to_drop();
        ingress_port_vlan_counter.count();
    }

    action set_vlan(vlan_id_t new_vlan_id) {
        hdr.vlan_tag.vlan_id = new_vlan_id;
        ingress_port_vlan_counter.count();
    }

    action push_internal_vlan(vlan_id_t new_vlan_id) {
        // Add internal VLAN header, will be removed before packet emission.
        // cfi and pri values are dummy.
        hdr.vlan_tag.setValid();
        hdr.vlan_tag.cfi = 0;
        hdr.vlan_tag.pri = 0;
        hdr.vlan_tag.ether_type = hdr.ethernet.ether_type;
        hdr.ethernet.ether_type = ETHERTYPE_VLAN;
        hdr.vlan_tag.vlan_id = new_vlan_id;

        // pop internal vlan before packet in
        fabric_metadata.pop_vlan_when_packet_in = _TRUE;
        ingress_port_vlan_counter.count();
    }

    table ingress_port_vlan {
        key = {
            standard_metadata.ingress_port: exact;
            hdr.vlan_tag.isValid(): exact @name("hdr.vlan_tag.is_valid");
            hdr.vlan_tag.vlan_id: ternary;
        }

        actions = {
            push_internal_vlan;
            set_vlan;
            @defaultonly nop;
            drop;
        }

        const default_action = nop();
        counters = ingress_port_vlan_counter;
    }

    /*
     * Forwarding Classifier.
     * Setup Forwarding Type metadata for Forwarding control block.
     * There are six types of tables in Forwarding control block:
     * - Bridging: default forwarding type
     * - MPLS: destination mac address is the router mac and ethernet type is
     *         MPLS(0x8847)
     * - IP Multicast: destination mac address is multicast address and ethernet
     *                 type is IP(0x0800 or 0x86dd)
     * - IP Unicast: destination mac address is router mac and ethernet type is
     *               IP(0x0800 or 0x86dd)
     */
    direct_counter(CounterType.packets_and_bytes) fwd_classifier_counter;

    action set_forwarding_type(fwd_type_t fwd_type) {
        fabric_metadata.fwd_type = fwd_type;
        fwd_classifier_counter.count();
    }

    table fwd_classifier {
        key = {
            standard_metadata.ingress_port: exact;
            hdr.ethernet.dst_addr: exact;
            hdr.vlan_tag.ether_type: exact;
        }

        actions = {
            set_forwarding_type;
        }

        const default_action = set_forwarding_type(FWD_BRIDGING);
        counters = fwd_classifier_counter;
    }

    apply {
        ingress_port_vlan.apply();
        fwd_classifier.apply();
    }
}
