From patchwork Sat Mar 28 18:55:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 221652 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1723C2D0EC for ; Sat, 28 Mar 2020 18:55:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BC272206F6 for ; Sat, 28 Mar 2020 18:55:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JJkaF5g1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727183AbgC1SzY (ORCPT ); Sat, 28 Mar 2020 14:55:24 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:41065 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726912AbgC1SzV (ORCPT ); Sat, 28 Mar 2020 14:55:21 -0400 Received: by mail-pl1-f196.google.com with SMTP id d24so1046771pll.8; Sat, 28 Mar 2020 11:55:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AXwEK4/+KEcLToq3y6f3bgpsRtBTc8LMEI6YEpgoXLI=; b=JJkaF5g1Neec6tTiRYebxMW5p8aq/fZ/c/j1/hHCwjf2gHoOvN8V+i8FGJ7QPtqh3n LkNIKrYZqkJpTmkq/U3euGleWsQh+K5vDs0yWWxpT73gxH6JUF5qQ4WNRWH1s7ebsn9m qJ70xw9Ftxv2wDYvC0/kn5VfmAdtWknBesiwThbxlUevNpydYUiQn8lAxq5Gw3zhdYOf GqM5SEeH7vvAK1rWLC1mIgekudkiLWekNKlDqZ7norvmUWWHueUd2uhY9zaPEEAgjecC jm1/S5/xkN+XlLaEN7nOLeOGYBSReZnEMPcb+r/xQVkrI4uleYEByazt58BlrVwzLrn+ kUIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=AXwEK4/+KEcLToq3y6f3bgpsRtBTc8LMEI6YEpgoXLI=; b=FrBLhnPOU9hL9/SpWYi/8cdbMkjQ9gKUX3+GljyhdWRzCOifF3E5Vi2XI/X6vaNcsb XGrXKH8200a9tnDapUIvXkJ8um7Oqi67vN9BaJ39NepQIZ0n6AOfjpjRvgj1m3FfH820 ystTfUOz69vALq56QkgyQ7Z0yg+uVZwJ1Pv6eyPJgp825aikRGOuZU27HHMzm96jGQ4Q 554fOcXiqomFIbpCBdKHEmWHmKcfBNDOyw968lmcEb2L7SnVs8p3sjF645xEYZfV/x51 OHj17lN3GL8z9ZY1wCurMlwUXDlFzV6wLyT8zQLNM8MubwwKNeC8PPHwROvrxS/4GINd hsUw== X-Gm-Message-State: ANhLgQ0aWKqvU7gFDg0gO4nA6BmbatB9KjuYj4trYOd3L2cq7VS/ytCQ HaP7vg+G/4jqWs72FC50sAdqX9Cm X-Google-Smtp-Source: ADFU+vtu1BJ15Y5kfVFgMh12YAhK0r6CPRGrF8Wq8gx2RV6YhhBuykT7bxsj9fThJ5Dz/QYltr/Maw== X-Received: by 2002:a17:90a:c482:: with SMTP id j2mr6435352pjt.71.1585421718843; Sat, 28 Mar 2020 11:55:18 -0700 (PDT) Received: from localhost.localdomain (c-73-93-5-123.hsd1.ca.comcast.net. [73.93.5.123]) by smtp.gmail.com with ESMTPSA id d7sm6682022pfo.86.2020.03.28.11.55.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Mar 2020 11:55:18 -0700 (PDT) From: Joe Stringer To: bpf@vger.kernel.org Cc: netdev@vger.kernel.org, daniel@iogearbox.net, ast@kernel.org, eric.dumazet@gmail.com, lmb@cloudflare.com, kafai@fb.com Subject: [PATCHv4 bpf-next 2/5] net: Track socket refcounts in skb_steal_sock() Date: Sat, 28 Mar 2020 11:55:05 -0700 Message-Id: <20200328185509.20892-3-joe@wand.net.nz> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200328185509.20892-1-joe@wand.net.nz> References: <20200328185509.20892-1-joe@wand.net.nz> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Refactor the UDP/TCP handlers slightly to allow skb_steal_sock() to make the determination of whether the socket is reference counted in the case where it is prefetched by earlier logic such as early_demux. Signed-off-by: Joe Stringer Acked-by: Martin KaFai Lau --- v4: Commit message update v3: No changes v2: Initial version --- include/net/inet6_hashtables.h | 3 +-- include/net/inet_hashtables.h | 3 +-- include/net/sock.h | 10 +++++++++- net/ipv4/udp.c | 6 ++++-- net/ipv6/udp.c | 9 ++++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index fe96bf247aac..81b965953036 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -85,9 +85,8 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo, int iif, int sdif, bool *refcounted) { - struct sock *sk = skb_steal_sock(skb); + struct sock *sk = skb_steal_sock(skb, refcounted); - *refcounted = true; if (sk) return sk; diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index d0019d3395cf..ad64ba6a057f 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -379,10 +379,9 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, const int sdif, bool *refcounted) { - struct sock *sk = skb_steal_sock(skb); + struct sock *sk = skb_steal_sock(skb, refcounted); const struct iphdr *iph = ip_hdr(skb); - *refcounted = true; if (sk) return sk; diff --git a/include/net/sock.h b/include/net/sock.h index 2613d21a667a..1ca2e808cb8e 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2533,15 +2533,23 @@ skb_sk_is_prefetched(struct sk_buff *skb) return skb->destructor == sock_pfree; } -static inline struct sock *skb_steal_sock(struct sk_buff *skb) +/** + * skb_steal_sock + * @skb to steal the socket from + * @refcounted is set to true if the socket is reference-counted + */ +static inline struct sock * +skb_steal_sock(struct sk_buff *skb, bool *refcounted) { if (skb->sk) { struct sock *sk = skb->sk; + *refcounted = true; skb->destructor = NULL; skb->sk = NULL; return sk; } + *refcounted = false; return NULL; } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2633fc231593..b4035021bbd3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2288,6 +2288,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, struct rtable *rt = skb_rtable(skb); __be32 saddr, daddr; struct net *net = dev_net(skb->dev); + bool refcounted; /* * Validate the packet. @@ -2313,7 +2314,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, if (udp4_csum_init(skb, uh, proto)) goto csum_error; - sk = skb_steal_sock(skb); + sk = skb_steal_sock(skb, &refcounted); if (sk) { struct dst_entry *dst = skb_dst(skb); int ret; @@ -2322,7 +2323,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, udp_sk_rx_dst_set(sk, dst); ret = udp_unicast_rcv_skb(sk, skb, uh); - sock_put(sk); + if (refcounted) + sock_put(sk); return ret; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5dc439a391fe..7d4151747340 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -843,6 +843,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, struct net *net = dev_net(skb->dev); struct udphdr *uh; struct sock *sk; + bool refcounted; u32 ulen = 0; if (!pskb_may_pull(skb, sizeof(struct udphdr))) @@ -879,7 +880,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, goto csum_error; /* Check if the socket is already available, e.g. due to early demux */ - sk = skb_steal_sock(skb); + sk = skb_steal_sock(skb, &refcounted); if (sk) { struct dst_entry *dst = skb_dst(skb); int ret; @@ -888,12 +889,14 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, udp6_sk_rx_dst_set(sk, dst); if (!uh->check && !udp_sk(sk)->no_check6_rx) { - sock_put(sk); + if (refcounted) + sock_put(sk); goto report_csum_error; } ret = udp6_unicast_rcv_skb(sk, skb, uh); - sock_put(sk); + if (refcounted) + sock_put(sk); return ret; } From patchwork Sat Mar 28 18:55:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 221651 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B83D1C2D0E5 for ; Sat, 28 Mar 2020 18:55:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8A5182071B for ; Sat, 28 Mar 2020 18:55:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bkJ2ZNCm" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727387AbgC1Sz1 (ORCPT ); Sat, 28 Mar 2020 14:55:27 -0400 Received: from mail-pl1-f195.google.com ([209.85.214.195]:45362 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727179AbgC1SzY (ORCPT ); Sat, 28 Mar 2020 14:55:24 -0400 Received: by mail-pl1-f195.google.com with SMTP id b9so4875078pls.12; Sat, 28 Mar 2020 11:55:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NDVGlRAeM13C8KfCj3zWdaO8zw4xeNG2F+otqJaRSEg=; b=bkJ2ZNCm0EK8pq1e6mY+2HJwiNqXMFSnDI2OoF3Obuo7s27KuqFqj5UFko+L7UB8Ny qAqCa8geY88/XXTUfFAorfS7Za9Y0dNxHdlZKVWvoXj+siC82uIuu26+767RnG9aqmRf lbxcmhFqFH4KtCDg43jCLohb+WJm86cBJYoE0wFapl/3WYXYyIIKRmln3gJu7sLCubnc JZXvfAySWys2Tk/PAuUQ3kYqOTyazPjoNOooWHgRAgqRYWQL3YJo+oZi3yeEPgFcKtfg Flu6ONzPielusIwOC75rnRBeNvbwAkxuyZHO6gykTmJ4lNuphVHu2MU30eAEQGvUmcbi IHtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=NDVGlRAeM13C8KfCj3zWdaO8zw4xeNG2F+otqJaRSEg=; b=VxBkA5bT+Q6PpOIT3kfCis3FSFGphCsIj+GazJydZ/qq5NxTYl+AjlQJIe5IZriVwe V6IPvXfFvGFP43a7IWkn6+Yr+NjDEkrJA3dljdEsL8JmkpkFgfnK2sR28YJX9VLVXxdv MX8Zkka2xfnTs9pRl1wkUyZ6Xj/vjXnJfbez5XzEh3YPtvClZFpfbYEIerWburtCUVz9 tUyIWRRq1Mf92NRRSmm92EpmMUGetR8wBXqT8nA3BvEA9oFz1ywpMN9vbMfAoxd5YEFy P0FbftNTg1tsn1EcZRVjTVk03/obsnqlKXD1Nl2L+TRnEgBQl30CVXYJe5HzUjZSoPgg UPHQ== X-Gm-Message-State: ANhLgQ1ex3cnPEZfkLLy4lNjUumgu8lp4SvumB+IyQwoiS8IeSD0PJrv rgyvrrKqrS8y2fXjQF5FAYTr5hhT X-Google-Smtp-Source: ADFU+vulhgK7fSZC2t0/B+UepVQzihA080ZOjHp2X++JtOT96tcvmXrRWQcquQF/nTDlglYUPjGBEQ== X-Received: by 2002:a17:902:d895:: with SMTP id b21mr4952404plz.118.1585421722947; Sat, 28 Mar 2020 11:55:22 -0700 (PDT) Received: from localhost.localdomain (c-73-93-5-123.hsd1.ca.comcast.net. [73.93.5.123]) by smtp.gmail.com with ESMTPSA id d7sm6682022pfo.86.2020.03.28.11.55.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Mar 2020 11:55:22 -0700 (PDT) From: Joe Stringer To: bpf@vger.kernel.org Cc: netdev@vger.kernel.org, daniel@iogearbox.net, ast@kernel.org, eric.dumazet@gmail.com, lmb@cloudflare.com, kafai@fb.com Subject: [PATCHv4 bpf-next 5/5] selftests: bpf: Extend sk_assign tests for UDP Date: Sat, 28 Mar 2020 11:55:08 -0700 Message-Id: <20200328185509.20892-6-joe@wand.net.nz> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200328185509.20892-1-joe@wand.net.nz> References: <20200328185509.20892-1-joe@wand.net.nz> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for testing UDP sk_assign to the existing tests. Signed-off-by: Joe Stringer Acked-by: Lorenz Bauer Acked-by: Martin KaFai Lau --- v4: Acked v3: Initial post --- .../selftests/bpf/prog_tests/sk_assign.c | 47 +++++++++++-- .../selftests/bpf/progs/test_sk_assign.c | 69 +++++++++++++++++-- 2 files changed, 105 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sk_assign.c b/tools/testing/selftests/bpf/prog_tests/sk_assign.c index 25f17fe7d678..d572e1a2c297 100644 --- a/tools/testing/selftests/bpf/prog_tests/sk_assign.c +++ b/tools/testing/selftests/bpf/prog_tests/sk_assign.c @@ -69,7 +69,7 @@ start_server(const struct sockaddr *addr, socklen_t len, int type) goto close_out; if (CHECK_FAIL(bind(fd, addr, len) == -1)) goto close_out; - if (CHECK_FAIL(listen(fd, 128) == -1)) + if (type == SOCK_STREAM && CHECK_FAIL(listen(fd, 128) == -1)) goto close_out; goto out; @@ -125,6 +125,20 @@ get_port(int fd) return port; } +static ssize_t +rcv_msg(int srv_client, int type) +{ + struct sockaddr_storage ss; + char buf[BUFSIZ]; + socklen_t slen; + + if (type == SOCK_STREAM) + return read(srv_client, &buf, sizeof(buf)); + else + return recvfrom(srv_client, &buf, sizeof(buf), 0, + (struct sockaddr *)&ss, &slen); +} + static int run_test(int server_fd, const struct sockaddr *addr, socklen_t len, int type) { @@ -139,16 +153,20 @@ run_test(int server_fd, const struct sockaddr *addr, socklen_t len, int type) goto out; } - srv_client = accept(server_fd, NULL, NULL); - if (CHECK_FAIL(srv_client == -1)) { - perror("Can't accept connection"); - goto out; + if (type == SOCK_STREAM) { + srv_client = accept(server_fd, NULL, NULL); + if (CHECK_FAIL(srv_client == -1)) { + perror("Can't accept connection"); + goto out; + } + } else { + srv_client = server_fd; } if (CHECK_FAIL(write(client, buf, sizeof(buf)) != sizeof(buf))) { perror("Can't write on client"); goto out; } - if (CHECK_FAIL(read(srv_client, &buf, sizeof(buf)) != sizeof(buf))) { + if (CHECK_FAIL(rcv_msg(srv_client, type) != sizeof(buf))) { perror("Can't read on server"); goto out; } @@ -156,9 +174,20 @@ run_test(int server_fd, const struct sockaddr *addr, socklen_t len, int type) port = get_port(srv_client); if (CHECK_FAIL(!port)) goto out; - if (CHECK(port != htons(CONNECT_PORT), "Expected", "port %u but got %u", + /* SOCK_STREAM is connected via accept(), so the server's local address + * will be the CONNECT_PORT rather than the BIND port that corresponds + * to the listen socket. SOCK_DGRAM on the other hand is connectionless + * so we can't really do the same check there; the server doesn't ever + * create a socket with CONNECT_PORT. + */ + if (type == SOCK_STREAM && + CHECK(port != htons(CONNECT_PORT), "Expected", "port %u but got %u", CONNECT_PORT, ntohs(port))) goto out; + else if (type == SOCK_DGRAM && + CHECK(port != htons(BIND_PORT), "Expected", + "port %u but got %u", BIND_PORT, ntohs(port))) + goto out; ret = 0; out: @@ -230,6 +259,10 @@ void test_sk_assign(void) TEST("ipv4 tcp addr redir", AF_INET, SOCK_STREAM, true), TEST("ipv6 tcp port redir", AF_INET6, SOCK_STREAM, false), TEST("ipv6 tcp addr redir", AF_INET6, SOCK_STREAM, true), + TEST("ipv4 udp port redir", AF_INET, SOCK_DGRAM, false), + TEST("ipv4 udp addr redir", AF_INET, SOCK_DGRAM, true), + TEST("ipv6 udp port redir", AF_INET6, SOCK_DGRAM, false), + TEST("ipv6 udp addr redir", AF_INET6, SOCK_DGRAM, true), }; int server = -1; int self_net; diff --git a/tools/testing/selftests/bpf/progs/test_sk_assign.c b/tools/testing/selftests/bpf/progs/test_sk_assign.c index bde8748799eb..99547dcaac12 100644 --- a/tools/testing/selftests/bpf/progs/test_sk_assign.c +++ b/tools/testing/selftests/bpf/progs/test_sk_assign.c @@ -21,7 +21,7 @@ char _license[] SEC("license") = "GPL"; /* Fill 'tuple' with L3 info, and attempt to find L4. On fail, return NULL. */ static inline struct bpf_sock_tuple * -get_tuple(struct __sk_buff *skb, bool *ipv4) +get_tuple(struct __sk_buff *skb, bool *ipv4, bool *tcp) { void *data_end = (void *)(long)skb->data_end; void *data = (void *)(long)skb->data; @@ -60,12 +60,64 @@ get_tuple(struct __sk_buff *skb, bool *ipv4) return (struct bpf_sock_tuple *)data; } - if (result + 1 > data_end || proto != IPPROTO_TCP) + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) return NULL; + *tcp = (proto == IPPROTO_TCP); return result; } +static inline int +handle_udp(struct __sk_buff *skb, struct bpf_sock_tuple *tuple, bool ipv4) +{ + struct bpf_sock_tuple ln = {0}; + struct bpf_sock *sk; + size_t tuple_len; + int ret; + + tuple_len = ipv4 ? sizeof(tuple->ipv4) : sizeof(tuple->ipv6); + if ((void *)tuple + tuple_len > skb->data_end) + return TC_ACT_SHOT; + + sk = bpf_sk_lookup_udp(skb, tuple, tuple_len, BPF_F_CURRENT_NETNS, 0); + if (sk) + goto assign; + + if (ipv4) { + if (tuple->ipv4.dport != bpf_htons(4321)) + return TC_ACT_OK; + + ln.ipv4.daddr = bpf_htonl(0x7f000001); + ln.ipv4.dport = bpf_htons(1234); + + sk = bpf_sk_lookup_udp(skb, &ln, sizeof(ln.ipv4), + BPF_F_CURRENT_NETNS, 0); + } else { + if (tuple->ipv6.dport != bpf_htons(4321)) + return TC_ACT_OK; + + /* Upper parts of daddr are already zero. */ + ln.ipv6.daddr[3] = bpf_htonl(0x1); + ln.ipv6.dport = bpf_htons(1234); + + sk = bpf_sk_lookup_udp(skb, &ln, sizeof(ln.ipv6), + BPF_F_CURRENT_NETNS, 0); + } + + /* workaround: We can't do a single socket lookup here, because then + * the compiler will likely spill tuple_len to the stack. This makes it + * lose all bounds information in the verifier, which then rejects the + * call as unsafe. + */ + if (!sk) + return TC_ACT_SHOT; + +assign: + ret = bpf_sk_assign(skb, sk, 0); + bpf_sk_release(sk); + return ret; +} + static inline int handle_tcp(struct __sk_buff *skb, struct bpf_sock_tuple *tuple, bool ipv4) { @@ -130,14 +182,23 @@ int bpf_sk_assign_test(struct __sk_buff *skb) { struct bpf_sock_tuple *tuple, ln = {0}; bool ipv4 = false; + bool tcp = false; int tuple_len; int ret = 0; - tuple = get_tuple(skb, &ipv4); + tuple = get_tuple(skb, &ipv4, &tcp); if (!tuple) return TC_ACT_SHOT; - ret = handle_tcp(skb, tuple, ipv4); + /* Note that the verifier socket return type for bpf_skc_lookup_tcp() + * differs from bpf_sk_lookup_udp(), so even though the C-level type is + * the same here, if we try to share the implementations they will + * fail to verify because we're crossing pointer types. + */ + if (tcp) + ret = handle_tcp(skb, tuple, ipv4); + else + ret = handle_udp(skb, tuple, ipv4); return ret == 0 ? TC_ACT_OK : TC_ACT_SHOT; }