1+ /* -*- P4_16 -*- */
2+ #include <core .p4 >
3+ #include <v1model .p4 >
4+
5+ const bit <16 > TYPE_IPV4 = 0x800 ;
6+
7+ /* ************************************************************************
8+ *********************** H E A D E R S ***********************************
9+ *************************************************************************/
10+
11+ typedef bit <9 > egressSpec_t ;
12+ typedef bit <48 > macAddr_t ;
13+ typedef bit <32 > ip4Addr_t ;
14+
15+ header ethernet_t {
16+ macAddr_t dstAddr ;
17+ macAddr_t srcAddr ;
18+ bit <16 > etherType ;
19+ }
20+
21+ header ipv4_t {
22+ bit <4 > version ;
23+ bit <4 > ihl ;
24+ bit <8 > diffserv ;
25+ bit <16 > totalLen ;
26+ bit <16 > identification ;
27+ bit <3 > flags ;
28+ bit <13 > fragOffset ;
29+ bit <8 > ttl ;
30+ bit <8 > protocol ;
31+ bit <16 > hdrChecksum ;
32+ ip4Addr_t srcAddr ;
33+ ip4Addr_t dstAddr ;
34+ }
35+
36+ struct metadata {
37+ /* empty */
38+ }
39+
40+ struct headers {
41+ ethernet_t ethernet ;
42+ ipv4_t ipv4 ;
43+ }
44+
45+ /* ************************************************************************
46+ *********************** P A R S E R ***********************************
47+ *************************************************************************/
48+
49+ parser MyParser (packet_in packet ,
50+ out headers hdr ,
51+ inout metadata meta ,
52+ inout standard_metadata_t standard_metadata ) {
53+
54+ state start {
55+
56+ packet .extract (hdr .ethernet );
57+ transition select (hdr .ethernet .etherType ){
58+
59+ TYPE_IPV4 : ipv4 ;
60+ default : accept ;
61+
62+ }
63+
64+ }
65+
66+ state ipv4 {
67+
68+ packet .extract (hdr .ipv4 );
69+ transition accept ;
70+ }
71+
72+ }
73+
74+
75+ /* ************************************************************************
76+ ************ C H E C K S U M V E R I F I C A T I O N *************
77+ *************************************************************************/
78+
79+ control MyVerifyChecksum (inout headers hdr , inout metadata meta ) {
80+ apply { }
81+ }
82+
83+
84+ /* ************************************************************************
85+ ************** I N G R E S S P R O C E S S I N G *******************
86+ *************************************************************************/
87+
88+ control MyIngress (inout headers hdr ,
89+ inout metadata meta ,
90+ inout standard_metadata_t standard_metadata ) {
91+
92+ action drop () {
93+ mark_to_drop (standard_metadata );
94+ }
95+
96+ action ipv4_forward (macAddr_t dstAddr , egressSpec_t port ) {
97+
98+ // set the src mac address as the previous dst, this is not correct right?
99+ hdr .ethernet .srcAddr = hdr .ethernet .dstAddr ;
100+
101+ // set the destination mac address that we got from the match in the table
102+ hdr .ethernet .dstAddr = dstAddr ;
103+
104+ // set the output port that we also get from the table
105+ standard_metadata .egress_spec = port ;
106+
107+ // decrease ttl by 1
108+ hdr .ipv4 .ttl = hdr .ipv4 .ttl -1 ;
109+ }
110+
111+ table ternary_table {
112+ key = {
113+ hdr .ipv4 .dstAddr : ternary ;
114+ }
115+ actions = {
116+ ipv4_forward ;
117+ drop ;
118+ NoAction ;
119+ }
120+ size = 1024 ;
121+ default_action = NoAction ();
122+ }
123+
124+ apply {
125+
126+ // only if IPV4 the rule is applied. Therefore other packets will not be forwarded.
127+ if (hdr .ipv4 .isValid ()){
128+ ternary_table .apply ();
129+
130+ }
131+ }
132+ }
133+
134+ /* ************************************************************************
135+ **************** E G R E S S P R O C E S S I N G *******************
136+ *************************************************************************/
137+
138+ control MyEgress (inout headers hdr ,
139+ inout metadata meta ,
140+ inout standard_metadata_t standard_metadata ) {
141+ apply { }
142+ }
143+
144+ /* ************************************************************************
145+ ************* C H E C K S U M C O M P U T A T I O N **************
146+ *************************************************************************/
147+
148+ control MyComputeChecksum (inout headers hdr , inout metadata meta ) {
149+ apply {
150+ update_checksum (
151+ hdr .ipv4 .isValid (),
152+ { hdr .ipv4 .version ,
153+ hdr .ipv4 .ihl ,
154+ hdr .ipv4 .diffserv ,
155+ hdr .ipv4 .totalLen ,
156+ hdr .ipv4 .identification ,
157+ hdr .ipv4 .flags ,
158+ hdr .ipv4 .fragOffset ,
159+ hdr .ipv4 .ttl ,
160+ hdr .ipv4 .protocol ,
161+ hdr .ipv4 .srcAddr ,
162+ hdr .ipv4 .dstAddr },
163+ hdr .ipv4 .hdrChecksum ,
164+ HashAlgorithm .csum16 );
165+ }
166+ }
167+
168+
169+ /* ************************************************************************
170+ *********************** D E P A R S E R *******************************
171+ *************************************************************************/
172+
173+ control MyDeparser (packet_out packet , in headers hdr ) {
174+ apply {
175+
176+ // parsed headers have to be added again into the packet.
177+ packet .emit (hdr .ethernet );
178+ packet .emit (hdr .ipv4 );
179+
180+ }
181+ }
182+
183+ /* ************************************************************************
184+ *********************** S W I T C H *******************************
185+ *************************************************************************/
186+
187+ // switch architecture
188+ V1Switch (
189+ MyParser (),
190+ MyVerifyChecksum (),
191+ MyIngress (),
192+ MyEgress (),
193+ MyComputeChecksum (),
194+ MyDeparser ()
195+ ) main ;
0 commit comments