-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathICMP_firewall.p4
175 lines (143 loc) · 2.71 KB
/
ICMP_firewall.p4
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
#define ETHERTYPE_IPV4 0x0800
#define PROTOCOL_ICMP 0x01
header_type header_ethernet_t
{
fields
{
bit<48>dst; //目的mac
bit<48>src; //源mac
bit<16>ethertype; //数据段协议类型
}
}
header_type header_ipv4_t
{
fields {
bit<4>version; //版本
bit<4>ihl; //头部长度
bit<8>diffserv; //区分服务
bit<16>totalLen; //总长度
bit<16>identification; //标识,主机计数器
bit<3>flags; //标志,分片使用
bit<13>fragOffset; //分片偏移
bit<8>ttl; //ttl
bit<8>protocol; //数据段协议类型
bit<16>hdrChecksum; //头部校验和
bit<32>srcAddr; //源IP
bit<32>dstAddr; //目的IP
}
}
header_type cnt_metadata_t
{
fields
{
bit<6>cnt; //计数50个icnp包
}
}
//header实例化
header header_ethernet_t header_ethernet;
header header_ipv4_t header_ipv4;
metadata cnt_metadata_t cnt_metadata;
//parser
parser start
{
return parse_ethernet;
}
parser parse_ethernet
{
extract(header_ethernet);
return select(header_ethernet.ethertype)
{
ETHERTYPE_IPV4 : parse_ipv4;
default : ingress;
}
}
parser parse_ipv4
{
extract(header_ipv4);
return ingress;
}
register drop_triger
{
width : 6;
instance_count : 1;
}
action update_metadata()
{
modify_field(cnt_metadata.cnt,drop_triger[0]);
modify_field(cnt_metadata.cnt,cnt_metadata.cnt + 1);
modify_field(drop_triger[0],cnt_metadata.cnt);
}
action forward_normal(in bit<9> port)
{
modify_field(standard_metadata.egress_spec,port);
}
action _drop()
{
drop();
}
table update_table
{
actions
{
update_metadata;
}
}
table forward_table_1
{
reads
{
header_ipv4.dstAddr : lpm;
}
actions
{
forward_normal;
}
}
table forward_table_2
{
reads
{
header_ipv4.dstAddr : lpm;
}
actions
{
forward_normal;
}
}
table drop_table
{
actions
{
_drop;
}
}
control ingress
{
if(header_ipv4.protocol == PROTOCOL_ICMP)
{
apply(update_table);
if(cnt_metadata.cnt >= 50)
{
apply(drop_table);
}
else
{
apply(forward_table_1);
}
}
else
{
apply(forward_table_2);
}
}
control egress
{
}
/*
table_set_default update_table update_metadata
table_set_default drop_table _drop
table_add forward_table_1 forward_normal 10.0.0.10/32 => 1
table_add forward_table_1 forward_normal 10.0.1.10/32 => 2
table_add forward_table_2 forward_normal 10.0.0.10/32 => 1
table_add forward_table_2 forward_normal 10.0.1.10/32 => 2
*/