pipeline: auto-detect endianness of action arguments
[dpdk.git] / examples / pipeline / examples / vxlan.spec
1 ; SPDX-License-Identifier: BSD-3-Clause
2 ; Copyright(c) 2020 Intel Corporation
3
4 //
5 // Headers
6 //
7 struct ethernet_h {
8         bit<48> dst_addr
9         bit<48> src_addr
10         bit<16> ethertype
11 }
12
13 struct 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
26 struct udp_h {
27         bit<16> src_port
28         bit<16> dst_port
29         bit<16> length
30         bit<16> checksum
31 }
32
33 struct vxlan_h {
34         bit<8> flags
35         bit<24> reserved
36         bit<24> vni
37         bit<8> reserved2
38 }
39
40 header ethernet instanceof ethernet_h
41 header ipv4 instanceof ipv4_h
42 header outer_ethernet instanceof ethernet_h
43 header outer_ipv4 instanceof ipv4_h
44 header outer_udp instanceof udp_h
45 header outer_vxlan instanceof vxlan_h
46
47 //
48 // Meta-data
49 //
50 struct metadata_t {
51         bit<32> port_in
52         bit<32> port_out
53 }
54
55 metadata instanceof metadata_t
56
57 //
58 // Actions
59 //
60 struct 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
116 action 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
165 action drop args none {
166         drop
167 }
168
169 //
170 // Tables.
171 //
172 table 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 //
189 apply {
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 }