@@ -33,6 +33,9 @@ static TRANSPORT_FILTERS: Array<u32> = Array::with_max_entries(8, 0);
33
33
#[ map]
34
34
static LINK_FILTERS : Array < u32 > = Array :: with_max_entries ( 8 , 0 ) ;
35
35
36
+ #[ map]
37
+ static TRAFFIC_DIRECTION_FILTERS : Array < u32 > = Array :: with_max_entries ( 2 , 0 ) ;
38
+
36
39
#[ map]
37
40
static BLOCKLIST_IPV6 : HashMap < u128 , [ u16 ; MAX_RULES_PORT ] > =
38
41
HashMap :: < u128 , [ u16 ; MAX_RULES_PORT ] > :: with_max_entries ( MAX_FIREWALL_RULES , 0 ) ;
@@ -56,6 +59,7 @@ fn submit(packet: RawPacket) {
56
59
buf. submit ( 0 ) ;
57
60
}
58
61
}
62
+
59
63
#[ inline]
60
64
fn ptr_at < T > ( ctx : & TcContext , offset : usize ) -> Result < * const T , ( ) > {
61
65
let start = ctx. data ( ) ;
@@ -70,12 +74,26 @@ fn ptr_at<T>(ctx: &TcContext, offset: usize) -> Result<*const T, ()> {
70
74
}
71
75
72
76
#[ inline]
73
- fn filter_for_ipv4_address (
74
- addr : u32 ,
75
- port : u16 ,
76
- blocked_ports_map : & HashMap < u32 , [ u16 ; 32 ] > ,
77
- ) -> bool {
78
- if let Some ( blocked_ports) = unsafe { blocked_ports_map. get ( & addr) } {
77
+ fn filter_direction ( ) -> bool {
78
+ // 0(default) -> false(send to tui), 1 -> true(filter)
79
+ if let Some ( v) = TRAFFIC_DIRECTION_FILTERS . get ( 0 ) {
80
+ return * v != 0 ;
81
+ }
82
+ false
83
+ }
84
+
85
+ #[ inline]
86
+ fn is_ingress ( ) -> bool {
87
+ // 0(default) -> true(is ingress), 1 -> false (is egress)
88
+ if let Some ( v) = TRAFFIC_DIRECTION_FILTERS . get ( 1 ) {
89
+ return * v == 0 ;
90
+ }
91
+ true
92
+ }
93
+
94
+ #[ inline]
95
+ fn block_ipv4 ( addr : u32 , port : u16 ) -> bool {
96
+ if let Some ( blocked_ports) = unsafe { BLOCKLIST_IPV4 . get ( & addr) } {
79
97
for ( idx, blocked_port) in blocked_ports. iter ( ) . enumerate ( ) {
80
98
if * blocked_port == 0 {
81
99
if idx == 0 {
@@ -92,12 +110,8 @@ fn filter_for_ipv4_address(
92
110
}
93
111
94
112
#[ inline]
95
- fn filter_for_ipv6_address (
96
- addr : u128 ,
97
- port : u16 ,
98
- blocked_ports_map : & HashMap < u128 , [ u16 ; 32 ] > ,
99
- ) -> bool {
100
- if let Some ( blocked_ports) = unsafe { blocked_ports_map. get ( & addr) } {
113
+ fn block_ipv6 ( addr : u128 , port : u16 ) -> bool {
114
+ if let Some ( blocked_ports) = unsafe { BLOCKLIST_IPV6 . get ( & addr) } {
101
115
for ( idx, blocked_port) in blocked_ports. iter ( ) . enumerate ( ) {
102
116
if * blocked_port == 0 {
103
117
if idx == 0 {
@@ -142,44 +156,53 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
142
156
match ethhdr. ether_type {
143
157
EtherType :: Ipv4 => {
144
158
let header: Ipv4Hdr = ctx. load ( EthHdr :: LEN ) . map_err ( |_| ( ) ) ?;
145
- let src_addr = u32:: from_be ( header. src_addr ) ;
146
- let dst_addr = u32:: from_be ( header. dst_addr ) ;
159
+
160
+ let addr = if is_ingress ( ) {
161
+ u32:: from_be ( header. src_addr )
162
+ } else {
163
+ u32:: from_be ( header. dst_addr )
164
+ } ;
147
165
148
166
match header. proto {
149
167
IpProto :: Tcp => {
150
168
let tcphdr: * const TcpHdr = ptr_at ( & ctx, EthHdr :: LEN + Ipv4Hdr :: LEN ) ?;
151
- let src_port = u16:: from_be ( unsafe { ( * tcphdr) . source } ) ;
152
- let dst_port = u16:: from_be ( unsafe { ( * tcphdr) . dest } ) ;
169
+ let port = if is_ingress ( ) {
170
+ u16:: from_be ( unsafe { ( * tcphdr) . source } )
171
+ } else {
172
+ u16:: from_be ( unsafe { ( * tcphdr) . dest } )
173
+ } ;
153
174
154
- if filter_for_ipv4_address ( src_addr, src_port, & BLOCKLIST_IPV4 )
155
- || filter_for_ipv4_address ( dst_addr, dst_port, & BLOCKLIST_IPV4 )
156
- {
175
+ if block_ipv4 ( addr, port) {
157
176
return Ok ( TC_ACT_SHOT ) ;
158
177
}
159
178
160
179
if filter_packet ( Protocol :: Network ( NetworkProtocol :: Ipv4 ) )
161
180
|| filter_packet ( Protocol :: Transport ( TransportProtocol :: TCP ) )
181
+ || filter_direction ( )
162
182
{
163
183
return Ok ( TC_ACT_PIPE ) ; //DONT FWD PACKET TO TUI
164
184
}
185
+
165
186
submit ( RawPacket :: Ip (
166
187
IpHdr :: V4 ( header) ,
167
188
ProtoHdr :: Tcp ( unsafe { * tcphdr } ) ,
168
189
) ) ;
169
190
}
170
191
IpProto :: Udp => {
171
192
let udphdr: * const UdpHdr = ptr_at ( & ctx, EthHdr :: LEN + Ipv4Hdr :: LEN ) ?;
172
- let src_port = u16:: from_be ( unsafe { ( * udphdr) . source } ) ;
173
- let dst_port = u16:: from_be ( unsafe { ( * udphdr) . dest } ) ;
193
+ let port = if is_ingress ( ) {
194
+ u16:: from_be ( unsafe { ( * udphdr) . source } )
195
+ } else {
196
+ u16:: from_be ( unsafe { ( * udphdr) . dest } )
197
+ } ;
174
198
175
- if filter_for_ipv4_address ( src_addr, src_port, & BLOCKLIST_IPV4 )
176
- || filter_for_ipv4_address ( dst_addr, dst_port, & BLOCKLIST_IPV4 )
177
- {
199
+ if block_ipv4 ( addr, port) {
178
200
return Ok ( TC_ACT_SHOT ) ;
179
201
}
180
202
181
203
if filter_packet ( Protocol :: Network ( NetworkProtocol :: Ipv4 ) )
182
204
|| filter_packet ( Protocol :: Transport ( TransportProtocol :: UDP ) )
205
+ || filter_direction ( )
183
206
{
184
207
return Ok ( TC_ACT_PIPE ) ;
185
208
}
@@ -204,22 +227,28 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
204
227
}
205
228
EtherType :: Ipv6 => {
206
229
let header: Ipv6Hdr = ctx. load ( EthHdr :: LEN ) . map_err ( |_| ( ) ) ?;
207
- let src_addr = header. src_addr ( ) . to_bits ( ) ;
208
- let dst_addr = header. dst_addr ( ) . to_bits ( ) ;
230
+ let addr = if is_ingress ( ) {
231
+ header. src_addr ( ) . to_bits ( )
232
+ } else {
233
+ header. dst_addr ( ) . to_bits ( )
234
+ } ;
209
235
210
236
match header. next_hdr {
211
237
IpProto :: Tcp => {
212
238
let tcphdr: * const TcpHdr = ptr_at ( & ctx, EthHdr :: LEN + Ipv6Hdr :: LEN ) ?;
213
- let src_port = u16:: from_be ( unsafe { ( * tcphdr) . source } ) ;
214
- let dst_port = u16:: from_be ( unsafe { ( * tcphdr) . dest } ) ;
239
+ let port = if is_ingress ( ) {
240
+ u16:: from_be ( unsafe { ( * tcphdr) . source } )
241
+ } else {
242
+ u16:: from_be ( unsafe { ( * tcphdr) . dest } )
243
+ } ;
215
244
216
- if filter_for_ipv6_address ( src_addr, src_port, & BLOCKLIST_IPV6 )
217
- || filter_for_ipv6_address ( dst_addr, dst_port, & BLOCKLIST_IPV6 )
218
- {
245
+ if block_ipv6 ( addr, port) {
219
246
return Ok ( TC_ACT_SHOT ) ;
220
247
}
248
+
221
249
if filter_packet ( Protocol :: Network ( NetworkProtocol :: Ipv6 ) )
222
250
|| filter_packet ( Protocol :: Transport ( TransportProtocol :: TCP ) )
251
+ || filter_direction ( )
223
252
{
224
253
return Ok ( TC_ACT_PIPE ) ; //DONT FWD PACKET TO TUI
225
254
}
@@ -230,16 +259,19 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
230
259
}
231
260
IpProto :: Udp => {
232
261
let udphdr: * const UdpHdr = ptr_at ( & ctx, EthHdr :: LEN + Ipv6Hdr :: LEN ) ?;
233
- let src_port = u16:: from_be ( unsafe { ( * udphdr) . source } ) ;
234
- let dst_port = u16:: from_be ( unsafe { ( * udphdr) . dest } ) ;
262
+ let port = if is_ingress ( ) {
263
+ u16:: from_be ( unsafe { ( * udphdr) . source } )
264
+ } else {
265
+ u16:: from_be ( unsafe { ( * udphdr) . dest } )
266
+ } ;
235
267
236
- if filter_for_ipv6_address ( src_addr, src_port, & BLOCKLIST_IPV6 )
237
- || filter_for_ipv6_address ( dst_addr, dst_port, & BLOCKLIST_IPV6 )
238
- {
268
+ if block_ipv6 ( addr, port) {
239
269
return Ok ( TC_ACT_SHOT ) ;
240
270
}
271
+
241
272
if filter_packet ( Protocol :: Network ( NetworkProtocol :: Ipv6 ) )
242
273
|| filter_packet ( Protocol :: Transport ( TransportProtocol :: UDP ) )
274
+ || filter_direction ( )
243
275
{
244
276
return Ok ( TC_ACT_PIPE ) ; //DONT FWD PACKET TO TUI
245
277
}
0 commit comments