-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathflowlet_switching.p4
More file actions
192 lines (148 loc) · 5.42 KB
/
flowlet_switching.p4
File metadata and controls
192 lines (148 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* -*- P4_16 -*- */
#include <core.p4>
#include <v1model.p4>
//My includes
#include "include/headers.p4"
#include "include/parsers.p4"
#define REGISTER_SIZE 8192
#define TIMESTAMP_WIDTH 48
#define ID_WIDTH 16
#define FLOWLET_TIMEOUT 48w200000 //200ms
/*************************************************************************
************ C H E C K S U M V E R I F I C A T I O N *************
*************************************************************************/
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { }
}
/*************************************************************************
************** I N G R E S S P R O C E S S I N G *******************
*************************************************************************/
control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
//TODO 5: define the id and timestamp registers
register<bit<ID_WIDTH>>(REGISTER_SIZE) flowlet_to_id;
register<bit<TIMESTAMP_WIDTH>>(REGISTER_SIZE) flowlet_time_stamp;
action drop() {
mark_to_drop(standard_metadata);
}
action read_flowlet_registers(bit<16> num_nhops){
//TODO 6: define the action to read the registers using the flowlet index you get from hashing the 5-tuple.
hash(meta.flowlet_hash_index,HashAlgorithm.crc16,(bit<1>)0,{hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr,
hdr.tcp.srcPort,
hdr.tcp.dstPort,
hdr.ipv4.protocol},num_nhops);
flowlet_to_id.read(meta.flowlet_id, (bit<32>)meta.flowlet_hash_index);
flowlet_time_stamp.read(meta.flowlet_timestamp, (bit<32>)meta.flowlet_hash_index);
flowlet_time_stamp.write((bit<32>)meta.flowlet_hash_index, standard_metadata.ingress_global_timestamp);
}
action update_flowlet_id(){
//TODO 7: define the action to update the flowlet id (if needed).
bit<ID_WIDTH> random_number;
random(random_number, 0, 10000);
flowlet_to_id.write((bit<32>)meta.flowlet_hash_index,random_number);
flowlet_to_id.read(meta.flowlet_id, (bit<32>)meta.flowlet_hash_index);
}
//TODO 4: copy the tables and actions from ECMP
action ecmp_group(bit<14> ecmp_group_id, bit<16> num_nhops){
//TODO 8: add the flowlet id to the hash function in the ecmp_group action
hash(meta.ecmp_hash,HashAlgorithm.crc16,(bit<1>)0,{hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr,
hdr.tcp.srcPort,
hdr.tcp.dstPort,
hdr.ipv4.protocol,
meta.flowlet_id},num_nhops);
meta.ecmp_group_id = ecmp_group_id;
}
action set_nhop(macAddr_t dstAddr, egressSpec_t port) {
bit<48> tmpAddr;
tmpAddr = hdr.ethernet.dstAddr;
hdr.ethernet.dstAddr = dstAddr;
standard_metadata.egress_spec = port;
hdr.ethernet.srcAddr = tmpAddr;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
}
table ecmp_group_to_nhop {
key = {
meta.ecmp_group_id: exact;
meta.ecmp_hash: exact;
}
actions = {
set_nhop;
drop;
}
size = 1024;
default_action = drop();
}
table ipv4_lpm {
key = {
hdr.ipv4.dstAddr: lpm;
}
actions = {
set_nhop;
ecmp_group;
drop;
}
size = 1024;
default_action = drop();
}
apply {
//TODO 9: write the ingress logic as described in the exercise description
if (hdr.ipv4.isValid()) {
read_flowlet_registers(4);
if ((standard_metadata.ingress_global_timestamp - meta.flowlet_timestamp) > FLOWLET_TIMEOUT) {
update_flowlet_id();
}
switch(ipv4_lpm.apply().action_run) {
ecmp_group: {
ecmp_group_to_nhop.apply();
}
}
}
}
}
/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply {
}
}
/*************************************************************************
************* C H E C K S U M C O M P U T A T I O N **************
*************************************************************************/
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply {
update_checksum(
hdr.ipv4.isValid(),
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.dscp,
hdr.ipv4.ecn,
hdr.ipv4.totalLen,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol,
hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr },
hdr.ipv4.hdrChecksum,
HashAlgorithm.csum16);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
//switch architecture
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;