1; SPDX-License-Identifier: BSD-3-Clause 2; Copyright(c) 2020 Intel Corporation 3 4// 5// Headers 6// 7struct ethernet_h { 8 bit<48> dst_addr 9 bit<48> src_addr 10 bit<16> ethertype 11} 12 13struct ipv4_h { 14 bit<8> ver_ihl 15 bit<8> diffserv 16 bit<16> total_len 17 bit<16> identification 18 bit<16> flags_offset 19 bit<8> ttl 20 bit<8> protocol 21 bit<16> hdr_checksum 22 bit<32> src_addr 23 bit<32> dst_addr 24} 25 26struct udp_h { 27 bit<16> src_port 28 bit<16> dst_port 29 bit<16> length 30 bit<16> checksum 31} 32 33struct vxlan_h { 34 bit<8> flags 35 bit<24> reserved 36 bit<24> vni 37 bit<8> reserved2 38} 39 40header ethernet instanceof ethernet_h 41header ipv4 instanceof ipv4_h 42header outer_ethernet instanceof ethernet_h 43header outer_ipv4 instanceof ipv4_h 44header outer_udp instanceof udp_h 45header outer_vxlan instanceof vxlan_h 46 47// 48// Meta-data 49// 50struct metadata_t { 51 bit<32> port_in 52 bit<32> port_out 53} 54 55metadata instanceof metadata_t 56 57// 58// Actions 59// 60struct vxlan_encap_args_t { 61 bit<48> ethernet_dst_addr 62 bit<48> ethernet_src_addr 63 bit<16> ethernet_ethertype 64 bit<8> ipv4_ver_ihl 65 bit<8> ipv4_diffserv 66 bit<16> ipv4_total_len 67 bit<16> ipv4_identification 68 bit<16> ipv4_flags_offset 69 bit<8> ipv4_ttl 70 bit<8> ipv4_protocol 71 bit<16> ipv4_hdr_checksum 72 bit<32> ipv4_src_addr 73 bit<32> ipv4_dst_addr 74 bit<16> udp_src_port 75 bit<16> udp_dst_port 76 bit<16> udp_length 77 bit<16> udp_checksum 78 bit<8> vxlan_flags 79 bit<24> vxlan_reserved 80 bit<24> vxlan_vni 81 bit<8> vxlan_reserved2 82 bit<32> port_out 83} 84 85// Input frame: 86// Ethernet (14) | IPv4 (total_len) 87// 88// Output frame: 89// Ethernet (14) | IPv4 (20) | UDP (8) | VXLAN (8) | Input frame | Ethernet FCS (4) 90// 91// Note: The input frame has its FCS removed before encapsulation in the output 92// frame. 93// 94// Assumption: When read from the table, the outer IPv4 and UDP headers contain 95// the following fields: 96// - t.ipv4_total_len: Set to 50, which covers the length of: 97// - The outer IPv4 header (20 bytes); 98// - The outer UDP header (8 bytes); 99// - The outer VXLAN header (8 bytes); 100// - The inner Ethernet header (14 bytes); 101// - t.ipv4_hdr_checksum: Includes the above total length. 102// - t.udp_length: Set to 30, which covers the length of: 103// - The outer UDP header (8 bytes); 104// - The outer VXLAN header (8 bytes); 105// - The inner Ethernet header (14 bytes); 106// - t.udp_checksum: Set to 0. 107// 108// Once the total length of the inner IPv4 packet (h.ipv4.total_len) is known, 109// the outer IPv4 and UDP headers are updated as follows: 110// - h.outer_ipv4.total_len = t.ipv4_total_len + h.ipv4.total_len 111// - h.outer_ipv4.hdr_checksum = t.ipv4_hdr_checksum + h.ipv4.total_len 112// - h.outer_udp.length = t.udp_length + h.ipv4.total_len 113// - h.outer_udp.checksum: No change. 114// 115 116action vxlan_encap args instanceof vxlan_encap_args_t { 117 //Set the outer Ethernet header. 118 mov h.outer_ethernet.dst_addr t.ethernet_dst_addr 119 mov h.outer_ethernet.src_addr t.ethernet_src_addr 120 mov h.outer_ethernet.ethertype t.ethernet_ethertype 121 validate h.outer_ethernet 122 123 //Set the outer IPv4 header. 124 mov h.outer_ipv4.ver_ihl t.ipv4_ver_ihl 125 mov h.outer_ipv4.diffserv t.ipv4_diffserv 126 mov h.outer_ipv4.total_len t.ipv4_total_len 127 mov h.outer_ipv4.identification t.ipv4_identification 128 mov h.outer_ipv4.flags_offset t.ipv4_flags_offset 129 mov h.outer_ipv4.ttl t.ipv4_ttl 130 mov h.outer_ipv4.protocol t.ipv4_protocol 131 mov h.outer_ipv4.hdr_checksum t.ipv4_hdr_checksum 132 mov h.outer_ipv4.src_addr t.ipv4_src_addr 133 mov h.outer_ipv4.dst_addr t.ipv4_dst_addr 134 validate h.outer_ipv4 135 136 //Set the outer UDP header. 137 mov h.outer_udp.src_port t.udp_src_port 138 mov h.outer_udp.dst_port t.udp_dst_port 139 mov h.outer_udp.length t.udp_length 140 mov h.outer_udp.checksum t.udp_checksum 141 validate h.outer_udp 142 143 //Set the outer VXLAN header. 144 mov h.outer_vxlan.flags t.vxlan_flags 145 mov h.outer_vxlan.reserved t.vxlan_reserved 146 mov h.outer_vxlan.vni t.vxlan_vni 147 mov h.outer_vxlan.reserved2 t.vxlan_reserved2 148 validate h.outer_vxlan 149 150 //Set the output port. 151 mov m.port_out t.port_out 152 153 //Update h.outer_ipv4.total_len field. 154 add h.outer_ipv4.total_len h.ipv4.total_len 155 156 //Update h.outer_ipv4.hdr_checksum field. 157 ckadd h.outer_ipv4.hdr_checksum h.ipv4.total_len 158 159 //Update h.outer_udp.length field. 160 add h.outer_udp.length h.ipv4.total_len 161 162 return 163} 164 165action drop args none { 166 drop 167} 168 169// 170// Tables. 171// 172table vxlan_table { 173 key { 174 h.ethernet.dst_addr exact 175 } 176 177 actions { 178 vxlan_encap 179 drop 180 } 181 182 default_action drop args none 183 size 1048576 184} 185 186// 187// Pipeline. 188// 189apply { 190 rx m.port_in 191 extract h.ethernet 192 extract h.ipv4 193 table vxlan_table 194 emit h.outer_ethernet 195 emit h.outer_ipv4 196 emit h.outer_udp 197 emit h.outer_vxlan 198 emit h.ethernet 199 emit h.ipv4 200 tx m.port_out 201} 202