blob: 89eb35a3eedf71e5a8fb62a77bd281e7d0ec6b00 [file] [log] [blame]
/*
* 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 "../define.p4"
#include "../header.p4"
#include "../action.p4"
control Forwarding (
inout parsed_headers_t hdr,
inout fabric_metadata_t fabric_metadata,
inout standard_metadata_t standard_metadata) {
/*
* Bridging Table.
* Matches destination mac address and VLAN Id and make egress decision.
*/
direct_counter(CounterType.packets_and_bytes) bridging_counter;
action set_next_id_bridging(next_id_t next_id) {
fabric_metadata.next_id = next_id;
bridging_counter.count();
}
table bridging {
key = {
hdr.vlan_tag.vlan_id: exact;
hdr.ethernet.dst_addr: ternary;
}
actions = {
set_next_id_bridging;
}
counters = bridging_counter;
}
/*
* MPLS Table.
* Matches MPLS label and make egress decision.
*/
direct_counter(CounterType.packets_and_bytes) mpls_counter;
action pop_mpls_and_next(next_id_t next_id) {
hdr.mpls.setInvalid();
fabric_metadata.next_id = next_id;
mpls_counter.count();
}
table mpls {
key = {
hdr.mpls.label: exact;
}
actions = {
pop_mpls_and_next;
}
counters = mpls_counter;
}
/*
* IPv4 Routing Table.
* Matches IPv4 prefix and make egress decision.
*/
direct_counter(CounterType.packets_and_bytes) routing_v4_counter;
action set_next_id_routing_v4(next_id_t next_id) {
fabric_metadata.next_id = next_id;
routing_v4_counter.count();
}
table routing_v4 {
key = {
hdr.ipv4.dst_addr: lpm;
}
actions = {
set_next_id_routing_v4;
}
counters = routing_v4_counter;
}
/*
* ACL Table.
* Make final egress decision based on general metch fields.
*/
direct_counter(CounterType.packets_and_bytes) acl_counter;
action set_next_id_acl(next_id_t next_id) {
fabric_metadata.next_id = next_id;
acl_counter.count();
}
// Send immendiatelly to CPU - skip the rest of pipeline.
action punt_to_cpu() {
standard_metadata.egress_spec = CPU_PORT;
acl_counter.count();
exit;
}
action clone_to_cpu() {
// FIXME: works only if pkt will be replicated via PRE multicast group.
fabric_metadata.clone_to_cpu = _TRUE;
acl_counter.count();
}
action drop() {
mark_to_drop();
acl_counter.count();
}
action nop_acl() {
acl_counter.count();
}
table acl {
key = {
standard_metadata.ingress_port: ternary; // 9
fabric_metadata.ip_proto: ternary; // 8
fabric_metadata.l4_src_port: ternary; // 16
fabric_metadata.l4_dst_port: ternary; // 16
hdr.ethernet.dst_addr: ternary; // 48
hdr.ethernet.src_addr: ternary; // 48
hdr.vlan_tag.vlan_id: ternary; // 12
hdr.vlan_tag.ether_type: ternary; //16
hdr.ipv4.src_addr: ternary; // 32
hdr.ipv4.dst_addr: ternary; // 32
hdr.icmp.icmp_type: ternary; // 8
hdr.icmp.icmp_code: ternary; // 8
}
actions = {
set_next_id_acl;
punt_to_cpu;
clone_to_cpu;
drop;
nop_acl;
}
const default_action = nop_acl();
size = 128;
counters = acl_counter;
}
#ifdef WITH_IPV6
/*
* IPv6 Routing Table.
* Matches IPv6 prefix and make egress decision.
*/
direct_counter(CounterType.packets_and_bytes) routing_v6_counter;
action set_next_id_routing_v6(next_id_t next_id) {
fabric_metadata.next_id = next_id;
routing_v6_counter.count();
}
table routing_v6 {
key = {
hdr.ipv6.dst_addr: lpm;
}
actions = {
set_next_id_routing_v6;
}
counters = routing_v6_counter;
}
#endif // WITH_IPV6
apply {
if(fabric_metadata.fwd_type == FWD_BRIDGING) bridging.apply();
else if (fabric_metadata.fwd_type == FWD_MPLS) {
mpls.apply();
// TODO: IPv6
hdr.vlan_tag.ether_type = ETHERTYPE_IPV4;
}
else if (fabric_metadata.fwd_type == FWD_IPV4_UNICAST) routing_v4.apply();
#ifdef WITH_IPV6
else if (fabric_metadata.fwd_type == FWD_IPV6_UNICAST) routing_v6.apply();
#endif // WITH_IPV6
acl.apply();
}
}