> On Aug 19, 2026, at 10:34 PM, Emil Tsalapatis <[email protected]> wrote:
> 
> !-------------------------------------------------------------------|
>  This Message Is From an External Sender
>  This message came from outside your organization.
> |-------------------------------------------------------------------!
> 
> On Tue Aug 18, 2026 at 8:03 AM EDT, Nick Hudson wrote:
>> This follow-up tightens the selftest to guard against false passes in
>> GSO decap validation.
>> 
>> It validates the expected post-decap state for both GSO and non-GSO
>> packets: expected tunnel gso_type bits must be cleared and
>> skb->encapsulation must match the remaining tunnel state.
>> 
>> It also adds explicit assertions that the decap validation path was
>> executed, including the large-send phase for GSO-marked subtests, and
>> asserts that the large-send marker is reset after the send.
>> 
>> This keeps the tc_tunnel decap checks meaningful and avoids false-pass
>> regressions without over-constraining behavior across tunnel modes.
>> 
>> Signed-off-by: Nick Hudson <[email protected]>
>> ---
>> .../selftests/bpf/prog_tests/test_tc_tunnel.c | 33 +++++++++++++++----
>> .../selftests/bpf/progs/test_tc_tunnel.c      | 19 +++++++++++
>> 2 files changed, 46 insertions(+), 6 deletions(-)
>> 
>> diff --git a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c 
>> b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
>> index 67ba27d69347..08d7d90f7772 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
>> @@ -206,7 +206,7 @@ static void disconnect_client_from_server(struct 
>> subtest_cfg *cfg,
>>      free(conn);
>> }
>> 
>> -static int send_and_test_data(struct subtest_cfg *cfg)
>> +static int send_and_test_data(struct subtest_cfg *cfg, struct 
>> test_tc_tunnel *skel)
>> {
>>      struct connection *conn;
>>      int err, res = -1;
>> @@ -215,6 +215,7 @@ static int send_and_test_data(struct subtest_cfg *cfg)
>>      if (!ASSERT_OK_PTR(conn, "connect to server"))
>>              return -1;
>> 
>> +    skel->bss->decap_expect_large_send = 0;
>>      err = send(conn->client_fd, tx_buffer, DEFAULT_TEST_DATA_SIZE, 0);
>>      if (!ASSERT_EQ(err, DEFAULT_TEST_DATA_SIZE, "send data from client"))
>>              goto end;
>> @@ -226,14 +227,17 @@ static int send_and_test_data(struct subtest_cfg *cfg)
>>              goto end;
>>      }
>> 
>> +    skel->bss->decap_expect_large_send = 1;
>>      err = send(conn->client_fd, tx_buffer, GSO_TEST_DATA_SIZE, 0);
>>      if (!ASSERT_EQ(err, GSO_TEST_DATA_SIZE, "send (large) data from 
>> client"))
>>              goto end;
>>      if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE))
>>              goto end;
>> +    skel->bss->decap_expect_large_send = 0;
>> 
>>      res = 0;
>> end:
>> +    skel->bss->decap_expect_large_send = 0;
>>      disconnect_client_from_server(cfg, conn);
>>      return res;
>> }
>> @@ -374,10 +378,15 @@ static int configure_ebpf_decapsulation(struct 
>> subtest_cfg *cfg)
>>      return ret;
>> }
>> 
>> -static void run_test(struct subtest_cfg *cfg)
>> +static void run_test(struct subtest_cfg *cfg, struct test_tc_tunnel *skel)
>> {
>>      struct nstoken *nstoken;
>> 
>> +    skel->bss->decap_validation_seen = 0;
>> +    skel->bss->decap_gso_validation_seen = 0;
> 
> Sashiko points out correctly that gso_validation_seen is never checked.
> Can we assert it with the others?
> 

Yeah, I’m fixing this and removing

    decap_{large_send_validation_seen,expect_large_send}


> The CI bot's point on the other hand doesn't matter that much imo, the
> assert for the config variable is good in case we ever add any other
> subtests.

Which point, sorry? 

> 
> pw-bot: cr
> 
>> +    skel->bss->decap_large_send_validation_seen = 0;
>> +    skel->bss->decap_expect_large_send = 0;
>> +
>>      if (!ASSERT_OK(run_server(cfg), "run server"))
>>              return;
>> 
>> @@ -386,7 +395,7 @@ static void run_test(struct subtest_cfg *cfg)
>>              goto fail;
>> 
>>      /* Basic communication must work */
>> -    if (!ASSERT_OK(send_and_test_data(cfg), "connect without any encap"))
>> +    if (!ASSERT_OK(send_and_test_data(cfg, skel), "connect without any 
>> encap"))
>>              goto fail;
>> 
>>      /* Attach encapsulation program to client */
>> @@ -398,7 +407,7 @@ static void run_test(struct subtest_cfg *cfg)
>>              if (!ASSERT_OK(configure_kernel_decapsulation(cfg),
>>                                      "configure kernel decapsulation"))
>>                      goto fail;
>> -            if (!ASSERT_OK(send_and_test_data(cfg),
>> +            if (!ASSERT_OK(send_and_test_data(cfg, skel),
>>                             "connect with encap prog and kern decap"))
>>                      goto fail;
>>      }
>> @@ -406,7 +415,18 @@ static void run_test(struct subtest_cfg *cfg)
>>      /* Replace kernel decapsulation with BPF decapsulation, test must pass 
>> */
>>      if (!ASSERT_OK(configure_ebpf_decapsulation(cfg), "configure ebpf 
>> decapsulation"))
>>              goto fail;
>> -    ASSERT_OK(send_and_test_data(cfg), "connect with encap and decap 
>> progs");
>> +    if (!ASSERT_OK(send_and_test_data(cfg, skel), "connect with encap and 
>> decap progs"))
>> +            goto fail;
>> +    if (!ASSERT_NEQ(skel->bss->decap_validation_seen, 0,
>> +                    "decap validation executed"))
>> +            goto fail;
>> +    if (!ASSERT_EQ(skel->bss->decap_expect_large_send, 0,
>> +                   "decap large-send marker reset"))
>> +            goto fail;
>> +    if (cfg->test_gso) {
>> +            ASSERT_NEQ(skel->bss->decap_large_send_validation_seen, 0,
>> +                       "decap validation executed for large send");
>> +    }
>> 
>> fail:
>>      close_netns(nstoken);
>> @@ -438,6 +458,7 @@ static int setup(void)
>>      SYS(fail_close_ns_client, "ip link add %s type veth peer name %s",
>>          "veth1 mtu 1500 netns " CLIENT_NS " address " MAC_ADDR_VETH1,
>>          "veth2 mtu 1500 netns " SERVER_NS " address " MAC_ADDR_VETH2);
>> +    SYS(fail_close_ns_client, "ethtool -K veth1 tso off");
>>      SYS(fail_close_ns_client, "ip link set veth1 up");
>>      nstoken_server = open_netns(SERVER_NS);
>>      if (!ASSERT_OK_PTR(nstoken_server, "open server ns"))
>> @@ -701,7 +722,7 @@ void test_tc_tunnel(void)
>>              if (ret < 0 || !test__start_subtest(cfg->name))
>>                      continue;
>>              if (subtest_setup(skel, cfg) == 0)
>> -                    run_test(cfg);
>> +                    run_test(cfg, skel);
>>              subtest_cleanup(cfg);
>>      }
>>      cleanup();
>> diff --git a/tools/testing/selftests/bpf/progs/test_tc_tunnel.c 
>> b/tools/testing/selftests/bpf/progs/test_tc_tunnel.c
>> index 853bca962910..e9bd1c9781f7 100644
>> --- a/tools/testing/selftests/bpf/progs/test_tc_tunnel.c
>> +++ b/tools/testing/selftests/bpf/progs/test_tc_tunnel.c
>> @@ -16,6 +16,11 @@ static const int cfg_port = 8000;
>> 
>> static const int cfg_udp_src = 20000;
>> 
>> +__u64 decap_validation_seen;
>> +__u64 decap_gso_validation_seen;
>> +__u64 decap_large_send_validation_seen;
>> +__u32 decap_expect_large_send;
>> +
>> #define ETH_P_MPLS_UC        0x8847
>> #define ETH_P_TEB    0x6558
>> 
>> @@ -690,7 +695,21 @@ static int decap_internal(struct __sk_buff *skb, int 
>> off, int len, char proto,
>> 
>>      kskb = bpf_cast_to_kern_ctx(skb);
>>      shinfo = bpf_core_cast(kskb->head + kskb->end, struct skb_shared_info);
>> +
>> +    if (flags & (BPF_F_ADJ_ROOM_DECAP_L4_MASK |
>> +                 BPF_F_ADJ_ROOM_DECAP_IPXIP_MASK))
>> +            decap_validation_seen++;
>> +
>> +    if ((flags & (BPF_F_ADJ_ROOM_DECAP_L4_MASK |
>> +                  BPF_F_ADJ_ROOM_DECAP_IPXIP_MASK)) &&
>> +        decap_expect_large_send)
>> +            decap_large_send_validation_seen++;
>> +
>>      if (shinfo->gso_size) {
>> +            if (flags & (BPF_F_ADJ_ROOM_DECAP_L4_MASK |
>> +                         BPF_F_ADJ_ROOM_DECAP_IPXIP_MASK))
>> +                    decap_gso_validation_seen++;
>> +
>>              if ((flags & BPF_F_ADJ_ROOM_DECAP_L4_UDP) &&
>>                  (shinfo->gso_type & SKB_GSO_UDP_TUNNEL_MASK))
>>                      return TC_ACT_SHOT;
> 

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to