Skip to content

Commit 98414c5

Browse files
committed
eBPF flows filtering support
Signed-off-by: Mohamed Mahmoud <mmahmoud@redhat.com>
1 parent 42bd1fe commit 98414c5

File tree

6 files changed

+272
-0
lines changed

6 files changed

+272
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
---
2+
layout: :theme/post
3+
title: "Enhancing NetObserv By Introducing Multi Rules Flow filtering capability in eBPF"
4+
description: NetObserv eBPF Flows Filtering
5+
tags: eBPF,Monitoring,Troubleshooting
6+
authors: [msherif1234]
7+
---
8+
9+
# Flow Filtering in eBPF: Optimizing Resource Usage by Selecting Critical Flows
10+
11+
## Introduction
12+
13+
In high-traffic environments, processing every network flow can be resource-intensive,
14+
leading to CPU overload and excessive memory usage.
15+
eBPF-based flow filtering solves this challenge by selecting only important flows,
16+
reducing system strain while maintaining visibility.
17+
18+
## Why Flow Filtering
19+
20+
The primary goal of flow filtering is resource efficiency.
21+
Instead of capturing and analyzing every flow, filtering mechanisms allow us to:
22+
23+
✅ Reduce CPU & Memory Overhead – Process only relevant traffic, avoiding unnecessary computation.
24+
25+
✅ Optimize Storage Usage – Store only meaningful flow records, reducing disk and database load.
26+
27+
✅ Enhance Performance – Minimize packet processing latency and improve system responsiveness.
28+
29+
✅ Focus on Critical Traffic – Prioritize important flows for security, compliance, and performance monitoring.
30+
31+
## How Flow Filtering Works in eBPF
32+
33+
eBPF allows filtering flows at the source, avoiding costly user-space processing. This typically involves:
34+
35+
1- Defining Filtering Rules – Specify criteria such as source/destination IP, port, protocol,
36+
or application metadata.
37+
The following table shows all possible filtering options and their default setting:
38+
39+
| Option | Description | Possible values | Default |
40+
|-------------|----------------------------------------------------------|-------------------------------------------------------------------------|-----------|
41+
| enable | Enable flow filter | true, false | false |
42+
| action | Action to apply on the flow | Accept, Reject | Accept |
43+
| cidr | CIDR to match on the flow | for example 1.1.1.0/24 or 1::100/64 or 0.0.0.0/0 | 0.0.0.0/0 |
44+
| protocol | Protocol to match on the flow | TCP, UDP, SCTP, ICMP, ICMPv6 | |
45+
| direction | Direction to match on the flow | Ingress, Egress | |
46+
| destPorts | Possible options for destination port settings | | |
47+
| | Single port to match on the flow | for example 80 or 443 or 49051 | |
48+
| | Range of ports to match on the flow or | for example 80-100 | |
49+
| | Two ports to match on | for example 80,100 | |
50+
| sourcePorts | Possible options for source port settings | | |
51+
| | Single port to match on the flow | for example 80 or 443 or 49051 | |
52+
| | Range of ports to match on the flow or | for example 80-100 | |
53+
| | Two ports to match on | for example 80,100 | |
54+
| ports | Possible options for destination or source port settings | | |
55+
| | Single port to match on the flow | for example 80 or 443 or 49051 | |
56+
| | Range of ports to match on the flow or | for example 80-100 | |
57+
| | Two ports to match on | for example 80,100 | |
58+
| icmpType | ICMP type to match on the flow | for example 8 or 13 | |
59+
| icmpCode | ICMP code to match on the flow | for example 0 or 1 | |
60+
| peerIP | Peer IP to match on the flow | for example 1.1.1.1 or 1::1 | |
61+
| peerCIDR | Peer IP CIDR to match on the flow | for example 1.1.1.1/24 or 1::1/48 | |
62+
| pktDrops | filter flows with packets drop | true, false | |
63+
| sampling | sampling rate to use for filtered flows | for example 10 or 20 (any value >= 1) | |
64+
| tcpFlags | TCP flags to filter flows by | "SYN";"SYN-ACK";"ACK";"FIN";"RST";"URG";"ECE";"CWR";"FIN-ACK";"RST-ACK" | |
65+
66+
<p style="text-align: center">Table 1: eBPF flow filtering configuration options </p>
67+
68+
Note:
69+
70+
- A rule cannot include both `ports` and either `sourcePorts` or `destPorts` simultaneously.
71+
- The number of eBPF flow filter rules is capped at `16` to maintain efficient memory usage when this feature is enabled.
72+
- Validation webhook rejects rules containing duplicate CIDRs.
73+
- Supports both `IPv4` and `IPv6` formats.
74+
- If users wish to match any CIDR, the default `0.0.0.0/0` (Null CIDR) can be used.
75+
76+
The example below demonstrates various filtering options using multi-rule filters:
77+
78+
```yaml
79+
agent:
80+
type: eBPF
81+
ebpf:
82+
flowFilter:
83+
enable: true
84+
rules:
85+
- action: Accept
86+
cidr: 10.128.0.0/24
87+
peerCIDR: 10.129.0.0/24
88+
ports: '443,6443'
89+
protocol: TCP
90+
sampling: 10
91+
- action: Accept
92+
cidr: 10.129.0.1/24
93+
ports: 53
94+
protocol: UDP
95+
sampling: 20
96+
- action: Reject
97+
tcpFlags: SYN
98+
cidr: 10.130.0.0/24
99+
protocol: TCP
100+
sourcePorts: 80-100
101+
- action: Accept
102+
cidr: 172.30.0.0/16
103+
protocol: SCTP
104+
pktDrops: true
105+
- action: Reject
106+
cidr: 8.8.8.8/32
107+
protocol: ICMP
108+
icmpType: 8 // ICMP Echo request packet
109+
```
110+
111+
2- Packet Inspection – Extract relevant packet attributes within an eBPF program.
112+
113+
3- Early Flow Filtering –
114+
Skip or Allow packets based on predefined conditions before doing further ebpf packets processing.
115+
The Following Diagram shows how eBPF filtering is done
116+
117+
<img src="{page.image('ebpf-flow-filtering/ebpf-flow-filtering.png')}" alt="eBPF Flow Filtering Packet Processing">
118+
<p style="text-align: center">Figure 1: eBPF Flow Filtering Packet Processing</p>
119+
120+
eBPF flow filtering uses a specific map type called `BPF_MAP_TYPE_LPM_TRIE`, which enables prefix-based matching.
121+
For more details on LPM maps, refer to [BPF_MAP_TYPE_LPM_TRIE](https://docs.ebpf.io/linux/map-type/BPF_MAP_TYPE_LPM_TRIE/).
122+
123+
When a packet traverses the eBPF stack, its `srcIP` undergoes a longest prefix match lookup in the `filter_map`.
124+
If a specific rule matches, the packet is further evaluated against additional fields,
125+
potentially triggering another longest prefix match for `dstIP`
126+
in the `peer_filter_map` only if peer IP filtering is enabled.
127+
Once all matching criteria are met, the corresponding filter rule action is executed—either
128+
allowing the flow or rejecting it—while updating global flow filtering metrics for debugging purposes.
129+
130+
This process is then repeated with `dstIP` as the primary lookup key in the `filter_map`. If peer IP filtering is enabled,
131+
`srcIP` is checked against the `peer_filter_map`. If a match is found,
132+
the rule’s action is executed, and relevant statistics are updated.
133+
134+
When the `sampling` configuration is specified in a flow filter rule,
135+
the matching flows will use this sampling rate, overriding the rate
136+
configured in the `flowcollector` object.
137+
138+
The dual matching approach ensures bidirectional flow tracking, enabling users to correlate and monitor both
139+
directions of a given flow.
140+
141+
In cases where no matching rules exist, the default behavior is to reject the flow.
142+
However, users can customize the handling of unmatched flows by adding a catch-all entry
143+
`(cidr: 0.0.0.0/0)` and specifying a global action to enforce their preferred policy.
144+
145+
## Key Use Cases
146+
147+
🚀 Reducing Observability Overhead – Avoid logging irrelevant flows in high-traffic Kubernetes clusters.
148+
149+
🔐 Security Filtering – Focus on anomalous or suspicious traffic while ignoring normal flows.
150+
151+
🌐 Network Performance Monitoring – Capture only high-latency or dropped-packet flows for troubleshooting.
152+
153+
### Filter EastWest and NorthSouth flows
154+
155+
Given a cluster with Services subnet on `172.30.0.0/16` and Pods subnet on `10.128.0.0/16` and `10.129.0.0/16`,
156+
we can set specific sampling rates and filters to keep and sample exactly what we want.
157+
For instance, allow traffic to service IP `172.30.100.64:80` with a sampling rate of `10`.
158+
Permit communication between pods in the `10.128.0.0/16` and `10.129.0.0/16` subnets with a sampling rate of `20`.
159+
Also Allow pods within the `10.128.0.0/14` subnet attempt to ping an external IP `8.8.8.8`,
160+
this flow should be allowed with a sampling rate of `30`.
161+
Reject all other traffic `default action`
162+
163+
```yaml
164+
agent:
165+
type: eBPF
166+
ebpf:
167+
flowFilter:
168+
enable: true
169+
rules:
170+
- action: Accept
171+
cidr: 172.30.0.0/16
172+
peerCIDR: 10.128.0.0/14
173+
sampling: 10
174+
- action: Accept
175+
cidr: 10.128.0.0/14
176+
peerCIDR: 10.128.0.0/14
177+
sampling: 20
178+
- action: Accept
179+
cidr: 8.8.8.8/32
180+
sampling: 30
181+
peerCIDR: 10.128.0.0/14
182+
protocol: ICMP
183+
icmpType: 8
184+
```
185+
186+
<img src="{page.image('ebpf-flow-filtering/ebpf-svc-and-pods-flows.png')}" alt="eBPF Flow Filtering Kubernetes NorthSouth and EastWest Flows">
187+
<p style="text-align: center">Figure 2: eBPF Flow Filtering Kubernetes NorthSouth and EastWest Flows</p>
188+
189+
### Filter flows with packet drops
190+
191+
Let's filter Kubernetes service flows that include a packet drop and discard all others.
192+
For this use case, the `PacketDrop` feature must be enabled with eBPF in `privileged` mode,
193+
as demonstrated in the configuration below.
194+
195+
```yaml
196+
agent:
197+
type: eBPF
198+
ebpf:
199+
privileged: true
200+
features:
201+
- PacketDrop
202+
flowFilter:
203+
enable: true
204+
rules:
205+
- action: Accept
206+
cidr: 172.30.0.0/16
207+
pktDrops: true
208+
- action: Reject
209+
cidr: 0.0.0.0/0
210+
```
211+
212+
<img src="{page.image('ebpf-flow-filtering/ebpf-filter-svc-pkt-drops.png')}" alt="eBPF Flow Filtering Kubernetes Services with Packet Drop">
213+
<p style="text-align: center">Figure 3: eBPF Flow Filtering Kubernetes Services with Packet Drop</p>
214+
215+
### Filter TCP flows using TCP Flags
216+
217+
Filtering based on TCP flags is an effective method to detect and mitigate TCP SYN flood attacks in a cluster.
218+
A SYN flood is a Denial-of-Service (DoS) attack where an attacker overwhelms a target system by sending a large
219+
number of SYN packets without completing the three-way handshake,
220+
depleting system resources and disrupting legitimate connections.
221+
222+
```yaml
223+
agent:
224+
type: eBPF
225+
ebpf:
226+
flowFilter:
227+
enable: true
228+
rules:
229+
- action: Accept
230+
cidr: 0.0.0.0/0
231+
protocol: TCP
232+
tcpFlags: SYN
233+
sampling: 1
234+
```
235+
236+
<img src="{page.image('ebpf-flow-filtering/ebpf-filter-with-tcpflags.png')}" alt="eBPF Flow Filtering TCP flows using TCP flags">
237+
<p style="text-align: center">Figure 4: eBPF Flow Filtering TCP flows using TCP flags</p>
238+
239+
### Filter DNS query over ports 53 and 5353 for both TCP and UDP
240+
241+
This Use case involves capturing DNS flows over both `TCP` and `UDP`,
242+
with the option to enable the `DNSTracking` feature for enhanced DNS latency insights.
243+
244+
```yaml
245+
agent:
246+
type: eBPF
247+
ebpf:
248+
features:
249+
- DNSTracking
250+
flowFilter:
251+
enable: true
252+
rules:
253+
- action: Accept
254+
cidr: 0.0.0.0/0
255+
sourcePorts: '53,5353'
256+
sampling: 1
257+
```
258+
259+
<img src="{page.image('ebpf-flow-filtering/ebpf-filter-DNS-flows.png')}" alt="eBPF Flow Filtering DNS flows">
260+
<p style="text-align: center">Figure 5: eBPF Flow Filtering DNS flows</p>
261+
262+
## Conclusion
263+
264+
By filtering flows at the kernel level with eBPF, we maximize efficiency,
265+
ensuring only the most relevant data is processed and stored.
266+
This approach is critical for scalability, cost reduction, and real-time network insights.
267+
268+
## Feedback
269+
270+
We hope you liked this article!
271+
Netobserv is an open source project [available on github](https://github.com/netobserv).
272+
Feel free to share your [ideas](https://github.com/netobserv/network-observability-operator/discussions/categories/ideas), [use cases](https://github.com/netobserv/network-observability-operator/discussions/categories/show-and-tell) or [ask the community for help](https://github.com/netobserv/network-observability-operator/discussions/categories/q-a).
215 KB
Loading
121 KB
Loading
222 KB
Loading
236 KB
Loading
208 KB
Loading

0 commit comments

Comments
 (0)