summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2020-01-27 11:25:07 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2020-01-27 11:25:12 +0100
commit82650dab9a5a2928c8d982cce5e3c687f14f8716 (patch)
treed8a90788a7a29307fd509bbf2761f024b4a902f8
parentb23bfa5633b19bf1db87b36a76b2225c734f794c (diff)
parent265bb359061db6ef825dec3912f341a604966371 (diff)
Merge branch 'bpf-flow-dissector-fix-port-ranges'
Yoshiki Komachi says: ==================== When I tried a test based on the selftest program for BPF flow dissector (test_flow_dissector.sh), I observed unexpected result as below: $ tc filter add dev lo parent ffff: protocol ip pref 1337 flower ip_proto \ udp src_port 8-10 action drop $ tools/testing/selftests/bpf/test_flow_dissector -i 4 -f 9 -F inner.dest4: 127.0.0.1 inner.source4: 127.0.0.3 pkts: tx=10 rx=10 The last rx means the number of received packets. I expected rx=0 in this test (i.e., all received packets should have been dropped), but it resulted in acceptance. Although the previous commit 8ffb055beae5 ("cls_flower: Fix the behavior using port ranges with hw-offload") added new flag and field toward filtering based on port ranges with hw-offload, it missed applying for BPF flow dissector then. As a result, BPF flow dissector currently stores data extracted from packets in incorrect field used for exact match whenever packets are classified by filters based on port ranges. Thus, they never match rules in such cases because flow dissector gives rise to generating incorrect flow keys. This series fixes the issue by replacing incorrect flag and field with new ones in BPF flow dissector, and adds a test for filtering based on specified port ranges to the existing selftest program. Changes in v2: - set key_ports to NULL at the top of __skb_flow_bpf_to_target() ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--net/core/flow_dissector.c11
-rwxr-xr-xtools/testing/selftests/bpf/test_flow_dissector.sh14
2 files changed, 23 insertions, 2 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index f560b4902060..a1670dff0629 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -834,10 +834,10 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
struct flow_dissector *flow_dissector,
void *target_container)
{
+ struct flow_dissector_key_ports *key_ports = NULL;
struct flow_dissector_key_control *key_control;
struct flow_dissector_key_basic *key_basic;
struct flow_dissector_key_addrs *key_addrs;
- struct flow_dissector_key_ports *key_ports;
struct flow_dissector_key_tags *key_tags;
key_control = skb_flow_dissector_target(flow_dissector,
@@ -876,10 +876,17 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
}
- if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) {
+ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
key_ports = skb_flow_dissector_target(flow_dissector,
FLOW_DISSECTOR_KEY_PORTS,
target_container);
+ else if (dissector_uses_key(flow_dissector,
+ FLOW_DISSECTOR_KEY_PORTS_RANGE))
+ key_ports = skb_flow_dissector_target(flow_dissector,
+ FLOW_DISSECTOR_KEY_PORTS_RANGE,
+ target_container);
+
+ if (key_ports) {
key_ports->src = flow_keys->sport;
key_ports->dst = flow_keys->dport;
}
diff --git a/tools/testing/selftests/bpf/test_flow_dissector.sh b/tools/testing/selftests/bpf/test_flow_dissector.sh
index a8485ae103d1..174b72a64a4c 100755
--- a/tools/testing/selftests/bpf/test_flow_dissector.sh
+++ b/tools/testing/selftests/bpf/test_flow_dissector.sh
@@ -139,6 +139,20 @@ echo "Testing IPv4 + GRE..."
tc filter del dev lo ingress pref 1337
+echo "Testing port range..."
+# Drops all IP/UDP packets coming from port 8-10
+tc filter add dev lo parent ffff: protocol ip pref 1337 flower ip_proto \
+ udp src_port 8-10 action drop
+
+# Send 10 IPv4/UDP packets from port 7. Filter should not drop any.
+./test_flow_dissector -i 4 -f 7
+# Send 10 IPv4/UDP packets from port 9. Filter should drop all.
+./test_flow_dissector -i 4 -f 9 -F
+# Send 10 IPv4/UDP packets from port 11. Filter should not drop any.
+./test_flow_dissector -i 4 -f 11
+
+tc filter del dev lo ingress pref 1337
+
echo "Testing IPv6..."
# Drops all IPv6/UDP packets coming from port 9
tc filter add dev lo parent ffff: protocol ipv6 pref 1337 flower ip_proto \