/*
 * Copyright 2019-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.
 */

 /*
  * BNG processor implementation. Provides upstream and downstream termination
  * based on double VLAN tags (s_tag, c_tag) and PPPoE.
  *
  * This implementation is based on the P4 Service Edge (p4se) contribution from
  * Deutsche Telekom:
  * https://github.com/opencord/p4se
  */

#ifndef __BNG__
#define __BNG__

#define BNG_SUBSC_IPV6_NET_PREFIX_LEN 64

control bng_ingress_upstream(
        inout parsed_headers_t hdr,
        inout fabric_metadata_t fmeta,
        inout standard_metadata_t smeta) {

    counter(BNG_MAX_SUBSC, CounterType.packets) c_terminated;
    counter(BNG_MAX_SUBSC, CounterType.packets) c_dropped;
    counter(BNG_MAX_SUBSC, CounterType.packets) c_control;

    // TABLE: t_pppoe_cp
    // Punt to CPU for PPPeE control packets.

    action punt_to_cpu() {
        smeta.egress_spec = CPU_PORT;
        c_control.count(fmeta.bng.line_id);
    }

    table t_pppoe_cp {
        key = {
            hdr.pppoe.code     : exact   @name("pppoe_code");
            hdr.pppoe.protocol : ternary @name("pppoe_protocol");
        }
        actions = {
            punt_to_cpu;
            @defaultonly nop;
        }
        size = 16;
        const default_action = nop;
    }

    // TABLE: PPPoE termination for IPv4
    // Check subscriber IPv4 source address, line_id, and pppoe_session_id
    // (antispoofing), if line is enabled, pop PPPoE and double VLANs.

    @hidden
    action term_enabled(bit<16> eth_type) {
        hdr.inner_vlan_tag.eth_type = eth_type;
        fmeta.last_eth_type = eth_type;
        hdr.pppoe.setInvalid();
        c_terminated.count(fmeta.bng.line_id);
    }

    action term_disabled() {
        fmeta.bng.type = BNG_TYPE_INVALID;
        mark_to_drop(smeta);
    }

    action term_enabled_v4() {
        term_enabled(ETHERTYPE_IPV4);
    }

    // TODO: add match on hdr.ethernet.src_addr for antispoofing
    // Take into account that MAC src address is modified by the Next control block
    // when doing routing functionality.
    table t_pppoe_term_v4 {
        key = {
            fmeta.bng.line_id    : exact @name("line_id");
            hdr.ipv4.src_addr    : exact @name("ipv4_src");
            hdr.pppoe.session_id : exact @name("pppoe_session_id");
        }
        actions = {
            term_enabled_v4;
            @defaultonly term_disabled;
        }
        size = BNG_MAX_SUBSC_NET;
        const default_action = term_disabled;
    }

#ifdef WITH_IPV6
    action term_enabled_v6() {
        term_enabled(ETHERTYPE_IPV6);
    }

    // TODO: add match on hdr.ethernet.src_addr for antispoofing
    // Match on unmodified metadata field, taking into account that MAC src address
    // is modified by the Next control block when doing routing functionality.
    table t_pppoe_term_v6 {
        key = {
            fmeta.bng.line_id         : exact @name("line_id");
            hdr.ipv6.src_addr[127:64] : exact @name("ipv6_src_net_id");
            hdr.pppoe.session_id      : exact @name("pppoe_session_id");
        }
        actions = {
            term_enabled_v6;
            @defaultonly term_disabled;
        }
        size = BNG_MAX_SUBSC_NET;
        const default_action = term_disabled;
    }
#endif // WITH_IPV6

    apply {
        if(t_pppoe_cp.apply().hit) {
            return;
        }
        if (hdr.ipv4.isValid()) {
            switch(t_pppoe_term_v4.apply().action_run) {
                term_disabled: {
                    c_dropped.count(fmeta.bng.line_id);
                }
            }
        }
#ifdef WITH_IPV6
        else if (hdr.ipv6.isValid()) {
            switch(t_pppoe_term_v6.apply().action_run) {
               term_disabled: {
                   c_dropped.count(fmeta.bng.line_id);
               }
           }
        }
#endif // WITH_IPV6
    }
}

control bng_ingress_downstream(
        inout parsed_headers_t hdr,
        inout fabric_metadata_t fmeta,
        inout standard_metadata_t smeta) {

    counter(BNG_MAX_SUBSC, CounterType.packets_and_bytes) c_line_rx;

    meter(BNG_MAX_SUBSC, MeterType.bytes) m_besteff;
    meter(BNG_MAX_SUBSC, MeterType.bytes) m_prio;

    action set_session(bit<16> pppoe_session_id) {
        fmeta.bng.type = BNG_TYPE_DOWNSTREAM;
        fmeta.bng.pppoe_session_id = pppoe_session_id;
        c_line_rx.count(fmeta.bng.line_id);
    }

    action drop() {
        fmeta.bng.type = BNG_TYPE_DOWNSTREAM;
        c_line_rx.count(fmeta.bng.line_id);
        mark_to_drop(smeta);
    }

    table t_line_session_map {
        key = {
            fmeta.bng.line_id : exact @name("line_id");
        }
        actions = {
            @defaultonly nop;
            set_session;
            drop;
        }
        size = BNG_MAX_SUBSC;
        const default_action = nop;
    }

    // Downstream QoS tables.
    // Provide coarse metering before prioritazion in the OLT. By default
    // everything is tagged and metered as best-effort traffic.

    action qos_prio() {
        // no-op
    }

    action qos_besteff() {
        // no-op
    }

    table t_qos_v4 {
        key = {
            fmeta.bng.line_id : ternary @name("line_id");
            hdr.ipv4.src_addr : lpm     @name("ipv4_src");
            hdr.ipv4.dscp     : ternary @name("ipv4_dscp");
            hdr.ipv4.ecn      : ternary @name("ipv4_ecn");
        }
        actions = {
            qos_prio;
            qos_besteff;
        }
        size = 256;
        const default_action = qos_besteff;
    }

#ifdef WITH_IPV6
    table t_qos_v6 {
        key = {
            fmeta.bng.line_id      : ternary @name("line_id");
            hdr.ipv6.src_addr      : lpm     @name("ipv6_src");
            hdr.ipv6.traffic_class : ternary @name("ipv6_traffic_class");
        }
        actions = {
            qos_prio;
            qos_besteff;
        }
        size = 256;
        const default_action = qos_besteff;
    }
#endif // WITH_IPV6

    apply {
        // We are not sure the pkt is a BNG downstream one, first we need to
        // verify the line_id matches the one of a subscriber...

        // IPv4
        if (t_line_session_map.apply().hit) {
            // Apply QoS only to subscriber traffic. This makes sense only
            // if the downstream ports are used to receive IP traffic NOT
            // destined to subscribers, e.g. to services in the compute
            // nodes.
            if (hdr.ipv4.isValid()) {
                switch (t_qos_v4.apply().action_run) {
                    qos_prio: {
                        m_prio.execute_meter(fmeta.bng.line_id, fmeta.bng.ds_meter_result);
                    }
                    qos_besteff: {
                        m_besteff.execute_meter(fmeta.bng.line_id, fmeta.bng.ds_meter_result);
                    }
                }
            }
#ifdef WITH_IPV6
            // IPv6
            else if (hdr.ipv6.isValid()) {
                switch (t_qos_v6.apply().action_run) {
                    qos_prio: {
                        m_prio.execute_meter(fmeta.bng.line_id, fmeta.bng.ds_meter_result);
                    }
                    qos_besteff: {
                        m_besteff.execute_meter(fmeta.bng.line_id, fmeta.bng.ds_meter_result);
                    }
                }
            }
#endif // WITH_IPV6
        }
    }
}

control bng_egress_downstream(
        inout parsed_headers_t hdr,
        inout fabric_metadata_t fmeta,
        inout standard_metadata_t smeta) {

    counter(BNG_MAX_SUBSC, CounterType.packets_and_bytes) c_line_tx;

    @hidden
    action encap() {
        // Here we add PPPoE and modify the inner_vlan_tag Ethernet Type.
        hdr.inner_vlan_tag.eth_type = ETHERTYPE_PPPOES;
        hdr.pppoe.setValid();
        hdr.pppoe.version = 4w1;
        hdr.pppoe.type_id = 4w1;
        hdr.pppoe.code = 8w0; // 0 means session stage.
        hdr.pppoe.session_id = fmeta.bng.pppoe_session_id;
        c_line_tx.count(fmeta.bng.line_id);
    }

    action encap_v4() {
        encap();
        hdr.pppoe.length = hdr.ipv4.total_len + 16w2;
        hdr.pppoe.protocol = PPPOE_PROTOCOL_IP4;
    }

#ifdef WITH_IPV6
    action encap_v6() {
        encap();
        hdr.pppoe.length = hdr.ipv6.payload_len + 16w42;
        hdr.pppoe.protocol = PPPOE_PROTOCOL_IP6;
    }
#endif // WITH_IPV6

    apply {
        if (hdr.ipv4.isValid()) {
            encap_v4();
        }
#ifdef WITH_IPV6
        // IPv6
        else if (hdr.ipv6.isValid()) {
            encap_v6();
        }
#endif // WITH_IPV6
    }
}

control bng_ingress(
        inout parsed_headers_t hdr,
        inout fabric_metadata_t fmeta,
        inout standard_metadata_t smeta) {

        bng_ingress_upstream() upstream;
        bng_ingress_downstream() downstream;

        vlan_id_t s_tag = 0;
        vlan_id_t c_tag = 0;

        // TABLE: t_line_map
        // Map s_tag and c_tag to a line ID to uniquely identify a subscriber

        action set_line(bit<32> line_id) {
            fmeta.bng.line_id = line_id;
        }

        table t_line_map {
            key = {
                s_tag : exact @name("s_tag");
                c_tag : exact @name("c_tag");
            }
             actions = {
                @defaultonly nop;
                set_line;
            }
            size = BNG_MAX_SUBSC;
            const default_action = nop;
        }

        apply {
            if(hdr.pppoe.isValid()) {
                s_tag = hdr.vlan_tag.vlan_id;
                c_tag = hdr.inner_vlan_tag.vlan_id;
            } else {
                // We expect the packet to be downstream,
                // the tags are set by the next stage in the metadata.
                s_tag = fmeta.vlan_id;
                c_tag = fmeta.inner_vlan_id;
            }

            // First map the double VLAN tags to a line ID
            // If table miss line ID will be 0.
            t_line_map.apply();

            if (hdr.pppoe.isValid()) {
                fmeta.bng.type = BNG_TYPE_UPSTREAM;
                upstream.apply(hdr, fmeta, smeta);
            } else {
                downstream.apply(hdr, fmeta, smeta);
            }
        }
}

control bng_egress(
        inout parsed_headers_t hdr,
        inout fabric_metadata_t fmeta,
        inout standard_metadata_t smeta) {

    bng_egress_downstream() downstream;

    apply {
        if (fmeta.bng.type == BNG_TYPE_DOWNSTREAM) {
            downstream.apply(hdr, fmeta, smeta);
        }
    }
}

#endif
