public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection
@ 2022-08-21 11:35 Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode Shmulik Ladkani
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Shmulik Ladkani @ 2022-08-21 11:35 UTC (permalink / raw)
  To: bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
replaces the flow-dissector logic with custom dissection logic.
This forces implementors to write programs that handle dissection for
any flows expected in the namespace.

It makes sense for flow-dissector bpf programs to just augment the
dissector with custom logic (e.g. dissecting certain flows or custom
protocols), while enjoying the broad capabilities of the standard
dissector for any other traffic.

v2:
- Extend selftests/bpf/progs/bpf_flow.c to exercise new ret code

Shmulik Ladkani (4):
  flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode
  bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for
    flow-dissector bpf progs
  bpf: test_run: Propagate bpf_flow_dissect's retval to user's
    bpf_attr.test.retval
  selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE

 include/linux/skbuff.h                        |  4 +-
 include/uapi/linux/bpf.h                      |  5 +++
 net/core/flow_dissector.c                     | 16 ++++---
 tools/include/uapi/linux/bpf.h                |  5 +++
 .../selftests/bpf/prog_tests/flow_dissector.c | 44 ++++++++++++++++++-
 .../prog_tests/flow_dissector_load_bytes.c    |  2 +-
 tools/testing/selftests/bpf/progs/bpf_flow.c  | 15 +++++++
 .../selftests/bpf/test_flow_dissector.sh      |  8 ++++
 8 files changed, 89 insertions(+), 10 deletions(-)

-- 
2.37.2


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 bpf-next 1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
@ 2022-08-21 11:35 ` Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 2/4] bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for flow-dissector bpf progs Shmulik Ladkani
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Shmulik Ladkani @ 2022-08-21 11:35 UTC (permalink / raw)
  To: bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

Let 'bpf_flow_dissect' callers know the bpf program's retcode and act
accordingly.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
 include/linux/skbuff.h    |  4 ++--
 net/bpf/test_run.c        |  2 +-
 net/core/flow_dissector.c | 13 +++++++------
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ca8afa382bf2..87921996175c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1460,8 +1460,8 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
 			     unsigned int key_count);
 
 struct bpf_flow_dissector;
-bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
-		      __be16 proto, int nhoff, int hlen, unsigned int flags);
+u32 bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
+		     __be16 proto, int nhoff, int hlen, unsigned int flags);
 
 bool __skb_flow_dissect(const struct net *net,
 			const struct sk_buff *skb,
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 25d8ecf105aa..51c479433517 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -1445,7 +1445,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
 	bpf_test_timer_enter(&t);
 	do {
 		retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
-					  size, flags);
+					  size, flags) == BPF_OK;
 	} while (bpf_test_timer_continue(&t, 1, repeat, &ret, &duration));
 	bpf_test_timer_leave(&t);
 
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 764c4cb3fe8f..a01817fb4ef4 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -866,8 +866,8 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
 	}
 }
 
-bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
-		      __be16 proto, int nhoff, int hlen, unsigned int flags)
+u32 bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
+		     __be16 proto, int nhoff, int hlen, unsigned int flags)
 {
 	struct bpf_flow_keys *flow_keys = ctx->flow_keys;
 	u32 result;
@@ -892,7 +892,7 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
 	flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
 				   flow_keys->nhoff, hlen);
 
-	return result == BPF_OK;
+	return result;
 }
 
 static bool is_pppoe_ses_hdr_valid(const struct pppoe_hdr *hdr)
@@ -1008,6 +1008,7 @@ bool __skb_flow_dissect(const struct net *net,
 			};
 			__be16 n_proto = proto;
 			struct bpf_prog *prog;
+			u32 result;
 
 			if (skb) {
 				ctx.skb = skb;
@@ -1019,12 +1020,12 @@ bool __skb_flow_dissect(const struct net *net,
 			}
 
 			prog = READ_ONCE(run_array->items[0].prog);
-			ret = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
-					       hlen, flags);
+			result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
+						  hlen, flags);
 			__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
 						 target_container);
 			rcu_read_unlock();
-			return ret;
+			return result == BPF_OK;
 		}
 		rcu_read_unlock();
 	}
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 bpf-next 2/4] bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for flow-dissector bpf progs
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode Shmulik Ladkani
@ 2022-08-21 11:35 ` Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 3/4] bpf: test_run: Propagate bpf_flow_dissect's retval to user's bpf_attr.test.retval Shmulik Ladkani
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Shmulik Ladkani @ 2022-08-21 11:35 UTC (permalink / raw)
  To: bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
replaces the flow-dissector logic with custom dissection logic.
This forces implementors to write programs that handle dissection for
any flows expected in the namespace.

It makes sense for flow-dissector bpf programs to just augment the
dissector with custom logic (e.g. dissecting certain flows or custom
protocols), while enjoying the broad capabilities of the standard
dissector for any other traffic.

Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode. Flow-dissector bpf
programs may return this to indicate no dissection was made, and
fallback to the standard dissector is requested.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
 include/uapi/linux/bpf.h       | 5 +++++
 net/core/flow_dissector.c      | 3 +++
 tools/include/uapi/linux/bpf.h | 5 +++++
 3 files changed, 13 insertions(+)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 934a2a8beb87..7f87012b012e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5861,6 +5861,11 @@ enum bpf_ret_code {
 	 *    represented by BPF_REDIRECT above).
 	 */
 	BPF_LWT_REROUTE = 128,
+	/* BPF_FLOW_DISSECTOR_CONTINUE: used by BPF_PROG_TYPE_FLOW_DISSECTOR
+	 *   to indicate that no custom dissection was performed, and
+	 *   fallback to standard dissector is requested.
+	 */
+	BPF_FLOW_DISSECTOR_CONTINUE = 129,
 };
 
 struct bpf_sock {
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index a01817fb4ef4..990429c69ccd 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1022,11 +1022,14 @@ bool __skb_flow_dissect(const struct net *net,
 			prog = READ_ONCE(run_array->items[0].prog);
 			result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff,
 						  hlen, flags);
+			if (result == BPF_FLOW_DISSECTOR_CONTINUE)
+				goto dissect_continue;
 			__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
 						 target_container);
 			rcu_read_unlock();
 			return result == BPF_OK;
 		}
+dissect_continue:
 		rcu_read_unlock();
 	}
 
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 1d6085e15fc8..f38814fbb618 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5861,6 +5861,11 @@ enum bpf_ret_code {
 	 *    represented by BPF_REDIRECT above).
 	 */
 	BPF_LWT_REROUTE = 128,
+	/* BPF_FLOW_DISSECTOR_CONTINUE: used by BPF_PROG_TYPE_FLOW_DISSECTOR
+	 *   to indicate that no custom dissection was performed, and
+	 *   fallback to standard dissector is requested.
+	 */
+	BPF_FLOW_DISSECTOR_CONTINUE = 129,
 };
 
 struct bpf_sock {
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 bpf-next 3/4] bpf: test_run: Propagate bpf_flow_dissect's retval to user's bpf_attr.test.retval
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 2/4] bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for flow-dissector bpf progs Shmulik Ladkani
@ 2022-08-21 11:35 ` Shmulik Ladkani
  2022-08-21 11:35 ` [PATCH v2 bpf-next 4/4] selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE Shmulik Ladkani
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Shmulik Ladkani @ 2022-08-21 11:35 UTC (permalink / raw)
  To: bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

Formerly, a boolean denoting whether bpf_flow_dissect returned BPF_OK
was set into 'bpf_attr.test.retval'.

Augment this, so users can check the actual return code of the dissector
program under test.

Existing prog_tests/flow_dissector*.c tests were correspondingly changed
to check against each test's expected retval.
Also, tests' resulting 'flow_keys' are verified only in case the expected
retval is BPF_OK. This allows adding new tests that expect non BPF_OK.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
 net/bpf/test_run.c                            |  2 +-
 .../selftests/bpf/prog_tests/flow_dissector.c | 23 ++++++++++++++++++-
 .../prog_tests/flow_dissector_load_bytes.c    |  2 +-
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 51c479433517..25d8ecf105aa 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -1445,7 +1445,7 @@ int bpf_prog_test_run_flow_dissector(struct bpf_prog *prog,
 	bpf_test_timer_enter(&t);
 	do {
 		retval = bpf_flow_dissect(prog, &ctx, eth->h_proto, ETH_HLEN,
-					  size, flags) == BPF_OK;
+					  size, flags);
 	} while (bpf_test_timer_continue(&t, 1, repeat, &ret, &duration));
 	bpf_test_timer_leave(&t);
 
diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
index 0c1661ea996e..8fa3c454995e 100644
--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
@@ -100,6 +100,7 @@ struct test {
 	} pkt;
 	struct bpf_flow_keys keys;
 	__u32 flags;
+	__u32 retval;
 };
 
 #define VLAN_HLEN	4
@@ -126,6 +127,7 @@ struct test tests[] = {
 			.sport = 80,
 			.dport = 8080,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv6",
@@ -146,6 +148,7 @@ struct test tests[] = {
 			.sport = 80,
 			.dport = 8080,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "802.1q-ipv4",
@@ -168,6 +171,7 @@ struct test tests[] = {
 			.sport = 80,
 			.dport = 8080,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "802.1ad-ipv6",
@@ -191,6 +195,7 @@ struct test tests[] = {
 			.sport = 80,
 			.dport = 8080,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv4-frag",
@@ -217,6 +222,7 @@ struct test tests[] = {
 			.dport = 8080,
 		},
 		.flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG,
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv4-no-frag",
@@ -239,6 +245,7 @@ struct test tests[] = {
 			.is_frag = true,
 			.is_first_frag = true,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv6-frag",
@@ -265,6 +272,7 @@ struct test tests[] = {
 			.dport = 8080,
 		},
 		.flags = BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG,
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv6-no-frag",
@@ -287,6 +295,7 @@ struct test tests[] = {
 			.is_frag = true,
 			.is_first_frag = true,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv6-flow-label",
@@ -309,6 +318,7 @@ struct test tests[] = {
 			.dport = 8080,
 			.flow_label = __bpf_constant_htonl(0xbeeef),
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipv6-no-flow-label",
@@ -331,6 +341,7 @@ struct test tests[] = {
 			.flow_label = __bpf_constant_htonl(0xbeeef),
 		},
 		.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL,
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipip-encap",
@@ -359,6 +370,7 @@ struct test tests[] = {
 			.sport = 80,
 			.dport = 8080,
 		},
+		.retval = BPF_OK,
 	},
 	{
 		.name = "ipip-no-encap",
@@ -386,6 +398,7 @@ struct test tests[] = {
 			.is_encap = true,
 		},
 		.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
+		.retval = BPF_OK,
 	},
 };
 
@@ -503,6 +516,10 @@ static void run_tests_skb_less(int tap_fd, struct bpf_map *keys)
 		err = tx_tap(tap_fd, &tests[i].pkt, sizeof(tests[i].pkt));
 		CHECK(err < 0, "tx_tap", "err %d errno %d\n", err, errno);
 
+		/* check the stored flow_keys only if BPF_OK expected */
+		if (tests[i].retval != BPF_OK)
+			continue;
+
 		err = bpf_map_lookup_elem(keys_fd, &key, &flow_keys);
 		ASSERT_OK(err, "bpf_map_lookup_elem");
 
@@ -588,7 +605,11 @@ void test_flow_dissector(void)
 
 		err = bpf_prog_test_run_opts(prog_fd, &topts);
 		ASSERT_OK(err, "test_run");
-		ASSERT_EQ(topts.retval, 1, "test_run retval");
+		ASSERT_EQ(topts.retval, tests[i].retval, "test_run retval");
+
+		/* check the resulting flow_keys only if BPF_OK returned */
+		if (topts.retval != BPF_OK)
+			continue;
 		ASSERT_EQ(topts.data_size_out, sizeof(flow_keys),
 			  "test_run data_size_out");
 		CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys);
diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector_load_bytes.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector_load_bytes.c
index 36afb409c25f..c7a47b57ac91 100644
--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector_load_bytes.c
+++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector_load_bytes.c
@@ -44,7 +44,7 @@ void serial_test_flow_dissector_load_bytes(void)
 	ASSERT_OK(err, "test_run");
 	ASSERT_EQ(topts.data_size_out, sizeof(flow_keys),
 		  "test_run data_size_out");
-	ASSERT_EQ(topts.retval, 1, "test_run retval");
+	ASSERT_EQ(topts.retval, BPF_OK, "test_run retval");
 
 	if (fd >= -1)
 		close(fd);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 bpf-next 4/4] selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
                   ` (2 preceding siblings ...)
  2022-08-21 11:35 ` [PATCH v2 bpf-next 3/4] bpf: test_run: Propagate bpf_flow_dissect's retval to user's bpf_attr.test.retval Shmulik Ladkani
@ 2022-08-21 11:35 ` Shmulik Ladkani
  2022-08-22 18:06 ` [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Stanislav Fomichev
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Shmulik Ladkani @ 2022-08-21 11:35 UTC (permalink / raw)
  To: bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

The dissector program returns BPF_FLOW_DISSECTOR_CONTINUE (and avoids
setting skb->flow_keys or last_dissection map) in case it encounters
IP packets whose (outer) source address is 127.0.0.127.

Additional test is added to prog_tests/flow_dissector.c which sets
this address as test's pkk.iph.saddr, with the expected retval of
BPF_FLOW_DISSECTOR_CONTINUE.

Also, legacy test_flow_dissector.sh was similarly augmented.

Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
---
 .../selftests/bpf/prog_tests/flow_dissector.c | 21 +++++++++++++++++++
 tools/testing/selftests/bpf/progs/bpf_flow.c  | 15 +++++++++++++
 .../selftests/bpf/test_flow_dissector.sh      |  8 +++++++
 3 files changed, 44 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
index 8fa3c454995e..7acca37a3d2b 100644
--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
@@ -8,6 +8,8 @@
 
 #include "bpf_flow.skel.h"
 
+#define FLOW_CONTINUE_SADDR 0x7f00007f /* 127.0.0.127 */
+
 #ifndef IP_MF
 #define IP_MF 0x2000
 #endif
@@ -400,6 +402,25 @@ struct test tests[] = {
 		.flags = BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP,
 		.retval = BPF_OK,
 	},
+	{
+		.name = "ipip-encap-dissector-continue",
+		.pkt.ipip = {
+			.eth.h_proto = __bpf_constant_htons(ETH_P_IP),
+			.iph.ihl = 5,
+			.iph.protocol = IPPROTO_IPIP,
+			.iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
+			.iph.saddr = __bpf_constant_htonl(FLOW_CONTINUE_SADDR),
+			.iph_inner.ihl = 5,
+			.iph_inner.protocol = IPPROTO_TCP,
+			.iph_inner.tot_len =
+				__bpf_constant_htons(MAGIC_BYTES) -
+				sizeof(struct iphdr),
+			.tcp.doff = 5,
+			.tcp.source = 99,
+			.tcp.dest = 9090,
+		},
+		.retval = BPF_FLOW_DISSECTOR_CONTINUE,
+	},
 };
 
 static int create_tap(const char *ifname)
diff --git a/tools/testing/selftests/bpf/progs/bpf_flow.c b/tools/testing/selftests/bpf/progs/bpf_flow.c
index f266c757b3df..a20c5ed5e454 100644
--- a/tools/testing/selftests/bpf/progs/bpf_flow.c
+++ b/tools/testing/selftests/bpf/progs/bpf_flow.c
@@ -22,6 +22,8 @@
 #define PROG(F) PROG_(F, _##F)
 #define PROG_(NUM, NAME) SEC("flow_dissector") int flow_dissector_##NUM
 
+#define FLOW_CONTINUE_SADDR 0x7f00007f /* 127.0.0.127 */
+
 /* These are the identifiers of the BPF programs that will be used in tail
  * calls. Name is limited to 16 characters, with the terminating character and
  * bpf_func_ above, we have only 6 to work with, anything after will be cropped.
@@ -143,6 +145,19 @@ int _dissect(struct __sk_buff *skb)
 {
 	struct bpf_flow_keys *keys = skb->flow_keys;
 
+	if (keys->n_proto == bpf_htons(ETH_P_IP)) {
+		/* IP traffic from FLOW_CONTINUE_SADDR falls-back to
+		 * standard dissector
+		 */
+		struct iphdr *iph, _iph;
+
+		iph = bpf_flow_dissect_get_header(skb, sizeof(*iph), &_iph);
+		if (iph && iph->ihl == 5 &&
+		    iph->saddr == bpf_htonl(FLOW_CONTINUE_SADDR)) {
+			return BPF_FLOW_DISSECTOR_CONTINUE;
+		}
+	}
+
 	return parse_eth_proto(skb, keys->n_proto);
 }
 
diff --git a/tools/testing/selftests/bpf/test_flow_dissector.sh b/tools/testing/selftests/bpf/test_flow_dissector.sh
index dbd91221727d..5303ce0c977b 100755
--- a/tools/testing/selftests/bpf/test_flow_dissector.sh
+++ b/tools/testing/selftests/bpf/test_flow_dissector.sh
@@ -115,6 +115,14 @@ tc filter add dev lo parent ffff: protocol ip pref 1337 flower ip_proto \
 # Send 10 IPv4/UDP packets from port 10. Filter should not drop any.
 ./test_flow_dissector -i 4 -f 10
 
+echo "Testing IPv4 from 127.0.0.127 (fallback to generic dissector)..."
+# Send 10 IPv4/UDP packets from port 8. Filter should not drop any.
+./test_flow_dissector -i 4 -S 127.0.0.127 -f 8
+# Send 10 IPv4/UDP packets from port 9. Filter should drop all.
+./test_flow_dissector -i 4 -S 127.0.0.127 -f 9 -F
+# Send 10 IPv4/UDP packets from port 10. Filter should not drop any.
+./test_flow_dissector -i 4 -S 127.0.0.127 -f 10
+
 echo "Testing IPIP..."
 # Send 10 IPv4/IPv4/UDP packets from port 8. Filter should not drop any.
 ./with_addr.sh ./with_tunnels.sh ./test_flow_dissector -o 4 -e bare -i 4 \
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
                   ` (3 preceding siblings ...)
  2022-08-21 11:35 ` [PATCH v2 bpf-next 4/4] selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE Shmulik Ladkani
@ 2022-08-22 18:06 ` Stanislav Fomichev
  2022-08-23  7:38 ` John Fastabend
  2022-08-23 20:50 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: Stanislav Fomichev @ 2022-08-22 18:06 UTC (permalink / raw)
  To: Shmulik Ladkani
  Cc: bpf, Alexei Starovoitov, Jakub Sitnicki, Petar Penkov,
	Willem de Bruijn, Shmulik Ladkani

On Sun, Aug 21, 2022 at 4:35 AM Shmulik Ladkani
<shmulik@metanetworks.com> wrote:
>
> Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
> replaces the flow-dissector logic with custom dissection logic.
> This forces implementors to write programs that handle dissection for
> any flows expected in the namespace.
>
> It makes sense for flow-dissector bpf programs to just augment the
> dissector with custom logic (e.g. dissecting certain flows or custom
> protocols), while enjoying the broad capabilities of the standard
> dissector for any other traffic.
>
> v2:
> - Extend selftests/bpf/progs/bpf_flow.c to exercise new ret code

The series looks good to me, thank you!

Reviewed-by: Stanislav Fomichev <sdf@google.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
                   ` (4 preceding siblings ...)
  2022-08-22 18:06 ` [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Stanislav Fomichev
@ 2022-08-23  7:38 ` John Fastabend
  2022-08-23 20:50 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: John Fastabend @ 2022-08-23  7:38 UTC (permalink / raw)
  To: Shmulik Ladkani, bpf, Alexei Starovoitov, Stanislav Fomichev
  Cc: Jakub Sitnicki, Petar Penkov, Willem de Bruijn, Shmulik Ladkani

Shmulik Ladkani wrote:
> Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
> replaces the flow-dissector logic with custom dissection logic.
> This forces implementors to write programs that handle dissection for
> any flows expected in the namespace.
> 
> It makes sense for flow-dissector bpf programs to just augment the
> dissector with custom logic (e.g. dissecting certain flows or custom
> protocols), while enjoying the broad capabilities of the standard
> dissector for any other traffic.
> 
> v2:
> - Extend selftests/bpf/progs/bpf_flow.c to exercise new ret code
> 
> Shmulik Ladkani (4):
>   flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode
>   bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for
>     flow-dissector bpf progs
>   bpf: test_run: Propagate bpf_flow_dissect's retval to user's
>     bpf_attr.test.retval
>   selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE
> 
>  include/linux/skbuff.h                        |  4 +-
>  include/uapi/linux/bpf.h                      |  5 +++
>  net/core/flow_dissector.c                     | 16 ++++---
>  tools/include/uapi/linux/bpf.h                |  5 +++
>  .../selftests/bpf/prog_tests/flow_dissector.c | 44 ++++++++++++++++++-
>  .../prog_tests/flow_dissector_load_bytes.c    |  2 +-
>  tools/testing/selftests/bpf/progs/bpf_flow.c  | 15 +++++++
>  .../selftests/bpf/test_flow_dissector.sh      |  8 ++++
>  8 files changed, 89 insertions(+), 10 deletions(-)
> 
> -- 
> 2.37.2
> 

LGTM.

Acked-by: John Fastabend <john.fastabend@gmail.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection
  2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
                   ` (5 preceding siblings ...)
  2022-08-23  7:38 ` John Fastabend
@ 2022-08-23 20:50 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-08-23 20:50 UTC (permalink / raw)
  To: Shmulik Ladkani; +Cc: bpf, ast, sdf, jakub, ppenkov, willemb, shmulik.ladkani

Hello:

This series was applied to bpf/bpf-next.git (master)
by Daniel Borkmann <daniel@iogearbox.net>:

On Sun, 21 Aug 2022 14:35:15 +0300 you wrote:
> Currently, attaching BPF_PROG_TYPE_FLOW_DISSECTOR programs completely
> replaces the flow-dissector logic with custom dissection logic.
> This forces implementors to write programs that handle dissection for
> any flows expected in the namespace.
> 
> It makes sense for flow-dissector bpf programs to just augment the
> dissector with custom logic (e.g. dissecting certain flows or custom
> protocols), while enjoying the broad capabilities of the standard
> dissector for any other traffic.
> 
> [...]

Here is the summary with links:
  - [v2,bpf-next,1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode
    https://git.kernel.org/bpf/bpf-next/c/0ba985024ae7
  - [v2,bpf-next,2/4] bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for flow-dissector bpf progs
    https://git.kernel.org/bpf/bpf-next/c/91350fe15293
  - [v2,bpf-next,3/4] bpf: test_run: Propagate bpf_flow_dissect's retval to user's bpf_attr.test.retval
    https://git.kernel.org/bpf/bpf-next/c/5deedfbee842
  - [v2,bpf-next,4/4] selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE
    https://git.kernel.org/bpf/bpf-next/c/d6513727c2af

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-08-23 20:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-21 11:35 [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Shmulik Ladkani
2022-08-21 11:35 ` [PATCH v2 bpf-next 1/4] flow_dissector: Make 'bpf_flow_dissect' return the bpf program retcode Shmulik Ladkani
2022-08-21 11:35 ` [PATCH v2 bpf-next 2/4] bpf/flow_dissector: Introduce BPF_FLOW_DISSECTOR_CONTINUE retcode for flow-dissector bpf progs Shmulik Ladkani
2022-08-21 11:35 ` [PATCH v2 bpf-next 3/4] bpf: test_run: Propagate bpf_flow_dissect's retval to user's bpf_attr.test.retval Shmulik Ladkani
2022-08-21 11:35 ` [PATCH v2 bpf-next 4/4] selftests/bpf: test BPF_FLOW_DISSECTOR_CONTINUE Shmulik Ladkani
2022-08-22 18:06 ` [PATCH v2 bpf-next 0/4] flow_dissector: Allow bpf flow-dissector progs to request fallback to normal dissection Stanislav Fomichev
2022-08-23  7:38 ` John Fastabend
2022-08-23 20:50 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox