xref: /dpdk/examples/pipeline/examples/vxlan.spec (revision 78376813)
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