/* * Copyright 2019-present GEANT RARE project * * 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. */ #ifndef _IG_CTL_PKT_PRE_EMIT_P4_ #define _IG_CTL_PKT_PRE_EMIT_P4_ control IngressControlPktPreEmit(inout headers hdr, inout ingress_metadata_t ig_md, in ingress_intrinsic_metadata_t ig_intr_md, inout ingress_intrinsic_metadata_for_tm_t ig_tm_md) { action act_pkt_send_to_cpu() { hdr.cpu.setValid(); hdr.cpu._padding = 0; hdr.cpu.port = ig_md.ingress_id; ig_tm_md.ucast_egress_port = CPU_PORT; ig_tm_md.bypass_egress = 1; } #ifdef HAVE_MPLS action act_pkt_mpls_swap_0() { ig_md.ethertype = ETHERTYPE_MPLS_UCAST; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_swap_1() { hdr.mpls0.setInvalid(); ig_md.ethertype = ETHERTYPE_MPLS_UCAST; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv4_decap_0_1() { hdr.mpls0.setInvalid(); hdr.mpls1.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV4; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv4_decap_0() { hdr.mpls0.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV4; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv4_decap_1() { hdr.mpls1.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV4; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv6_decap_0_1() { hdr.mpls0.setInvalid(); hdr.mpls1.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV6; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv6_decap_0() { hdr.mpls0.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV6; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_ipv6_decap_1() { hdr.mpls1.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV6; } #endif #ifdef HAVE_MPLS action _act_pkt_mpls2_encap() { ig_md.ethertype = ETHERTYPE_MPLS_UCAST; hdr.mpls0.setValid(); hdr.mpls0.label = ig_md.mpls_encap_egress_label; hdr.mpls0.exp = 0; hdr.mpls0.bos = 0; hdr.mpls0.ttl = 255; hdr.mpls1.setValid(); hdr.mpls1.label = ig_md.mpls_encap_svc_label; hdr.mpls1.exp = 0; hdr.mpls1.bos = 1; hdr.mpls1.ttl = 255; } #endif #ifdef HAVE_MPLS action _act_pkt_mpls1_encap() { ig_md.ethertype = ETHERTYPE_MPLS_UCAST; hdr.mpls0.setValid(); hdr.mpls0.label = ig_md.mpls_encap_egress_label; hdr.mpls0.exp = 0; hdr.mpls0.bos = 1; hdr.mpls0.ttl = 255; } #endif action _act_pkt_inner_eth_encap() { hdr.eth2.setValid(); hdr.eth2 = hdr.ethernet; hdr.eth2.ethertype = ig_md.ethertype; } #ifdef HAVE_MPLS action act_pkt_mpls_rawip_ipv4_encap() { _act_pkt_mpls1_encap(); hdr.mpls0.ttl = hdr.ipv4.ttl; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_rawip_ipv6_encap() { _act_pkt_mpls1_encap(); hdr.mpls0.ttl = hdr.ipv6.hop_limit; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_rawip_ipv4_reencap() { hdr.mpls1.setInvalid(); _act_pkt_mpls1_encap(); hdr.mpls0.ttl = hdr.ipv4.ttl; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_rawip_ipv6_reencap() { hdr.mpls1.setInvalid(); _act_pkt_mpls1_encap(); hdr.mpls0.ttl = hdr.ipv6.hop_limit; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_l3vpn_ipv4_encap() { _act_pkt_mpls2_encap(); hdr.mpls0.ttl = hdr.ipv4.ttl; hdr.mpls1.ttl = hdr.ipv4.ttl; } #endif #ifdef HAVE_MPLS action act_pkt_mpls_l3vpn_ipv6_encap() { _act_pkt_mpls2_encap(); hdr.mpls0.ttl = hdr.ipv6.hop_limit; hdr.mpls1.ttl = hdr.ipv6.hop_limit; } #endif #ifdef HAVE_MPLS #ifdef HAVE_BRIDGE action act_pkt_mpls_l2vpn_encap() { _act_pkt_inner_eth_encap(); _act_pkt_mpls2_encap(); } #endif #endif #ifdef HAVE_SRV6 action act_pkt_srv_l3vpn_encap() { hdr.ipv6.version = 6; hdr.ipv6.hop_limit = 255; hdr.ipv6.src_addr = ig_md.srv_target; hdr.ipv6.dst_addr = ig_md.srv_target; ig_md.ethertype = ETHERTYPE_IPV6; } #endif #ifdef HAVE_SRV6 action act_pkt_srv_l3vpn_ipv4_encap() { hdr.ipv4b.setValid(); hdr.ipv4b = hdr.ipv4; hdr.ipv4.setInvalid(); hdr.ipv6.setValid(); hdr.ipv6.payload_len = hdr.ipv4b.total_len; hdr.ipv6.next_hdr = IP_PROTOCOL_IPV4; act_pkt_srv_l3vpn_encap(); } #endif #ifdef HAVE_SRV6 action act_pkt_srv_l3vpn_ipv6_encap() { hdr.ipv6b.setValid(); hdr.ipv6b = hdr.ipv6; hdr.ipv6.payload_len = hdr.ipv6b.payload_len + 40; hdr.ipv6.next_hdr = IP_PROTOCOL_IPV6; act_pkt_srv_l3vpn_encap(); } #endif #ifdef HAVE_SRV6 action act_pkt_srv_ipv4_decap() { hdr.ipv4.setValid(); hdr.ipv4 = hdr.ipv4b; hdr.ipv4b.setInvalid(); hdr.ipv6.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV4; } #endif #ifdef HAVE_SRV6 action act_pkt_srv_ipv6_decap() { hdr.ipv6 = hdr.ipv6b; hdr.ipv6b.setInvalid(); ig_md.ethertype = ETHERTYPE_IPV6; } #endif table tbl_pkt_pre_emit { key = { ig_md.srv_encap_l3vpn_valid: exact; ig_md.mpls_encap_rawip_valid: exact; ig_md.mpls_encap_l3vpn_valid: exact; ig_md.mpls_encap_l2vpn_valid: exact; ig_md.srv_remove: exact; ig_md.mpls0_remove: exact; ig_md.mpls1_remove: exact; ig_md.mpls_encap_decap_sap_type: exact; ig_md.nexthop_id: ternary; } actions = { #ifdef HAVE_MPLS act_pkt_mpls_l3vpn_ipv4_encap; act_pkt_mpls_l3vpn_ipv6_encap; act_pkt_mpls_rawip_ipv4_encap; act_pkt_mpls_rawip_ipv6_encap; act_pkt_mpls_rawip_ipv4_reencap; act_pkt_mpls_rawip_ipv6_reencap; #ifdef HAVE_BRIDGE act_pkt_mpls_l2vpn_encap; #endif #endif #ifdef HAVE_SRV6 act_pkt_srv_l3vpn_ipv4_encap; act_pkt_srv_l3vpn_ipv6_encap; #endif act_pkt_send_to_cpu; #ifdef HAVE_MPLS act_pkt_mpls_ipv4_decap_0_1; act_pkt_mpls_ipv4_decap_0; act_pkt_mpls_ipv4_decap_1; act_pkt_mpls_ipv6_decap_0_1; act_pkt_mpls_ipv6_decap_0; act_pkt_mpls_ipv6_decap_1; act_pkt_mpls_swap_0; act_pkt_mpls_swap_1; #endif #ifdef HAVE_SRV6 act_pkt_srv_ipv4_decap; act_pkt_srv_ipv6_decap; #endif @defaultonly NoAction; } const entries = { #ifdef HAVE_MPLS (0, 1, 0, 0, 0, 0, 0, 4, _):act_pkt_mpls_rawip_ipv4_encap(); (0, 1, 0, 0, 0, 0, 0, 6, _):act_pkt_mpls_rawip_ipv6_encap(); (0, 1, 0, 0, 0, 0, 1, 4, _):act_pkt_mpls_rawip_ipv4_reencap(); (0, 1, 0, 0, 0, 0, 1, 6, _):act_pkt_mpls_rawip_ipv6_reencap(); (0, 0, 1, 0, 0, 0, 0, 4, _):act_pkt_mpls_l3vpn_ipv4_encap(); (0, 0, 1, 0, 0, 0, 0, 6, _):act_pkt_mpls_l3vpn_ipv6_encap(); #ifdef HAVE_BRIDGE (0, 0, 0, 1, 0, 0, 0, 2, _):act_pkt_mpls_l2vpn_encap(); #endif #endif #ifdef HAVE_SRV6 (1, 0, 0, 0, 0, 0, 0, 4, _):act_pkt_srv_l3vpn_ipv4_encap(); (1, 0, 0, 0, 0, 0, 0, 6, _):act_pkt_srv_l3vpn_ipv6_encap(); #endif (0, 0, 0, 0, 0, 0, 0, 0, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 0, 1, 0, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 0, 0, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 1, 0, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 0, 0, 4, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 0, 1, 4, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 0, 4, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 1, 4, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 0, 0, 6, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 0, 1, 6, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 0, 6, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 0, 1, 1, 6, CPU_PORT):act_pkt_send_to_cpu(); #ifdef HAVE_SRV6 (1, 0, 0, 0, 0, 0, 0, 4, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 1, 0, 0, 4, CPU_PORT):act_pkt_send_to_cpu(); (1, 0, 0, 0, 0, 0, 0, 6, CPU_PORT):act_pkt_send_to_cpu(); (0, 0, 0, 0, 1, 0, 0, 6, CPU_PORT):act_pkt_send_to_cpu(); #endif #ifdef HAVE_MPLS (0, 0, 0, 0, 0, 1, 1, 4, _):act_pkt_mpls_ipv4_decap_0_1(); (0, 0, 0, 0, 0, 1, 0, 4, _):act_pkt_mpls_ipv4_decap_0(); (0, 0, 0, 0, 0, 0, 1, 4, _):act_pkt_mpls_ipv4_decap_1(); (0, 0, 0, 0, 0, 1, 1, 6, _):act_pkt_mpls_ipv6_decap_0_1(); (0, 0, 0, 0, 0, 1, 0, 6, _):act_pkt_mpls_ipv6_decap_0(); (0, 0, 0, 0, 0, 0, 1, 6, _):act_pkt_mpls_ipv6_decap_1(); #endif #ifdef HAVE_SRV6 (0, 0, 0, 0, 1, 0, 0, 4, _):act_pkt_srv_ipv4_decap(); (0, 0, 0, 0, 1, 0, 0, 6, _):act_pkt_srv_ipv6_decap(); #endif #ifdef HAVE_MPLS (0, 0, 0, 0, 0, 0, 0, 1, _):act_pkt_mpls_swap_0(); (0, 0, 0, 0, 0, 1, 0, 1, _):act_pkt_mpls_swap_1(); #endif } size = 32; default_action = NoAction(); } apply { tbl_pkt_pre_emit.apply(); } } #endif // _IG_CTL_PKT_PRE_EMIT_P4_