From patchwork Thu Mar 13 19:02:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015810 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C1F078C9C; Thu, 13 Mar 2025 19:03:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892602; cv=none; b=oYdD7vUGtbDOl3StzzcKhkHQHkvevZpqMTYFFm/FvbMVWvJzLH145DUeI6ld9pcMxatZapI/GKeDyauNRKuQpkNYKWC5UjmHTEmRl8Z2b9ICJiYVEwcY5ZwJL0f3g9awBSR/QKzYrCdLHTiQWttXvq6P0rwC0JorYtNgkKfcwt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892602; c=relaxed/simple; bh=7ZdIUWwy2ZwCtyLTE2CZpC1ML5KbxUCT89YsXIcUQK0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t9uG6muvQPAhMXZxw3oqv73x07K4i2gF33SRtkPwhHQDUG9CkR6FHL1w2Hv9lXrAMEzHoHneSk+ic13dUO34Rm1VbrK9W8FzZROUSTKfcA5F7EIlezTTTEZ5fymIZSS5nwpLJ4w3IAs6lArWSYYpIlwjGi/+2QQBL0C/zXKIP5M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=R+tpF3M8; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R+tpF3M8" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2243803b776so40016555ad.0; Thu, 13 Mar 2025 12:03:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892600; x=1742497400; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JBe2Vn5705Uoga5BCF8FrreTJ3KADBCQ6CgS8nbEEIo=; b=R+tpF3M89UPyHq6zHIbZwGlu6HBRDXR9qaCOBgUkG24vEeNgUSqW+AKFwkM1qQ+eb0 iqhmBN1jJhRbbUO3Vseq5mRIPcQUpZ3J4g+B6ZzQMVHgIhTDLehZBlWADWnjl6pjDhf5 /L4W7iEfD3lw2lqVqWAJQ68R8YJYJzBqpdlDSMbU3spzIgGXZjClcHrlG1yP4DF+NOAK OQoX3juZ1/6KdZgJJUJNBwD2yMp5Lg4k2n9KBpCTXTPb6yxGx6qy82da9N0hJwlS3WLo J+xSbKOOrvOrm+gUbIc0HSKA/5RpKns/Q+2EqpXhj2ygahHIYXwuOCGjZdB9FdLX1E5z V8WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892600; x=1742497400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JBe2Vn5705Uoga5BCF8FrreTJ3KADBCQ6CgS8nbEEIo=; b=YBWb/forV8zj2ZEevLAU0Tn5i+pWNVwCbS9yTQdOkz3+ZE+IT8s94VCXxkFZWPW6vY dNw699eC8rH5mXLI5AHqOq8jMXiWv4imYRkAXb+Oe1VO8vSogTyQTkFer1yMOMBJwLy4 lYyDLm7sTHXZPHCXSZ5FJD1RNlHPUkq8N1N6dpHcoAW4SRTIkkgsxKSmwjD/AmN/XeIz QbR41hjJ79mb5qQnty3ZdpSayYFKdvdXjB3MTfkRGBJIKuzuuNC4N770v8rFZRG7utrK zCSwFF1YiITgNHS8MbITahsOsL8YWKxEP1RngxnyWBZTfjxmLLmkEWS6vRTBhm6WnhP9 9+jg== X-Gm-Message-State: AOJu0YyUq+Q5z5eibgHFvjgJszvFX+dFnyxbnGWKUIZ0W6R6Mant4EAb /DysNLUV8jdymmGcQB3uqdXKm/RKOM0USSfB8nsEhWhVYjxI9s4f7oam0nymW6C1hw== X-Gm-Gg: ASbGncsvHPDjdKNl8gIxCYw2jMi9YIok1R0mjI0i9gb3/4hx3A9c/AsVmU8GCk86zTu rW9noSutbXr4rJ8v6ptGEM0U8MCk4KQypULtoyZojEPLZB60JPAcFK3+OsTzfx811nOAQDdu+jG X7WZI+eUeA30z0EN4TKdoWD/e6g3EgbPXM/G0sd4XoYK2EwwRHB+lLOcAUWuH0KLHKqrGqeJO/I PuZTaYlsKNFQlEYu1UiXGGFCTRSn/3kFr7X2MuCyQNNg/z4/NVWiG1pXIvtuyMreD05N2DGulEj uHTrUtXWXAyZuGCrUfMUfQMbbw309DlzilaWhz+LGy+uKo2TwtKFVvLUoz0285iPPbn6PhCdBHp Z3dVRgRScJFQkVnqhWr0= X-Google-Smtp-Source: AGHT+IHQ/8YYRG+tDimUOLk60GZkFEfmf/gUmjBVadwddfwBlZtGq0wpmLQxn9WK4LusuND5l69Q2Q== X-Received: by 2002:a05:6300:67ca:b0:1f5:8903:860f with SMTP id adf61e73a8af0-1f5bd7d4fb3mr1243941637.14.1741892599624; Thu, 13 Mar 2025 12:03:19 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:19 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 01/13] bpf: Prepare to reuse get_ctx_arg_idx Date: Thu, 13 Mar 2025 12:02:55 -0700 Message-ID: <20250313190309.2545711-2-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Rename get_ctx_arg_idx to bpf_ctx_arg_idx, and allow others to call it. No functional change. Signed-off-by: Amery Hung --- include/linux/btf.h | 1 + kernel/bpf/btf.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index ebc0c0c9b944..b2983706292f 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -522,6 +522,7 @@ bool btf_param_match_suffix(const struct btf *btf, const char *suffix); int btf_ctx_arg_offset(const struct btf *btf, const struct btf_type *func_proto, u32 arg_no); +u32 btf_ctx_arg_idx(struct btf *btf, const struct btf_type *func_proto, int off); struct bpf_verifier_log; diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 519e3f5e9c10..9a4920828c30 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -6369,8 +6369,8 @@ static bool is_int_ptr(struct btf *btf, const struct btf_type *t) return btf_type_is_int(t); } -static u32 get_ctx_arg_idx(struct btf *btf, const struct btf_type *func_proto, - int off) +u32 btf_ctx_arg_idx(struct btf *btf, const struct btf_type *func_proto, + int off) { const struct btf_param *args; const struct btf_type *t; @@ -6649,7 +6649,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, tname, off); return false; } - arg = get_ctx_arg_idx(btf, t, off); + arg = btf_ctx_arg_idx(btf, t, off); args = (const struct btf_param *)(t + 1); /* if (t == NULL) Fall back to default BPF prog with * MAX_BPF_FUNC_REG_ARGS u64 arguments. From patchwork Thu Mar 13 19:02:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015811 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A13B11E9B30; Thu, 13 Mar 2025 19:03:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892603; cv=none; b=aRC7KFNvQTc29vGqzfLu16rVh+tVX45a8xw/mIA7quLUCzmndAkoWFUigCn5RjsLnG17eWnJWZBlZVUXa2OOAiy4ljAx05QBlGORFZ9ix0hMAi9Ms2y4vIdW58x0tbeEBjcBwOlpVuxM1GZbHSu4033h+IzCzHEHUiL281+6ppg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892603; c=relaxed/simple; bh=sef1qcilGkhe9JUUrUVaEMXIk/wXcfEC+HV4nh1nh3M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oXT7JGRRhYuCMxNnazUfWcstKHHf4oLwj71M1MTLUwtl8yUMgyH2FtdWjw/bNePoaIaXYDcuQKNSm0JEsWUT6a7C9RmjOzaA+Z6MbFlb52ynFB4fiJWT3ApHBiEdOo65fzPwcD7ZH1YYAVSn9k/mjqe3GLyVSVrEPuU98UHBD8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=K1UmDjlm; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="K1UmDjlm" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2241053582dso34384685ad.1; Thu, 13 Mar 2025 12:03:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892601; x=1742497401; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qjeR/x0qDwmVuV5v1i7wkxBYQ4TFckMqeAG7zQVs0H8=; b=K1UmDjlm/J+p+rzAVRiItlcEpt6Qx67yLB8+RjUnDPgp5p3AvmKJaXDfDMRJJDWoUg zy+voGO65GPVv0ItyV8nOr9O/yCZoCjNsPrN++aRfhygptmyoRKfbvQkfMlsRLBNdGHj wYaXbLKCVMtIvfmiVTroGJmVVYrdZ30QpZXDsdAy6frqXGvr718GdwOpFW3WH3Xh8LKo g7Z5ZAatIbHgFS+ZG2ny6z/t3MDj871mj3v763uU9MsthWtywvJ9dQJVawr2jTXDzGuQ wtcY6T8xHmgIsAH2CjpbqqaNstllDbiYDXkj1Vn9Wub2vlwcDvI7fY08DfULzhj1J1Ks 0O2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892601; x=1742497401; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qjeR/x0qDwmVuV5v1i7wkxBYQ4TFckMqeAG7zQVs0H8=; b=AzDXflzubEK+v9tWCEDwOOkgsoGRwcu/fQFMtrbrb8sd1a5dYEey2knPMR3uFsM89g eQNfyiObgHBoya0apf61LeXpRGw7VH/jsBkHMHi/5eHAkH5oblAynPPGKMyZiuOqEfn/ 17GeKMFgFjGvkRFIflNiFnyoRUbEXmBYVwiUHLEC08DUVjG12qDfd3g7S0dx2DJ1brW4 ksKyx4FDDZMvh7Y4AfWBYjBTnU9GQHGAtGth46QDjfpMXvRbPEH0nZvIJM4I0ew+ylgK wZ3yr4ZuoH8Hm/Gf/dVLhbZlulveSwoSg8stXjPkiXi9udw1WpPMaAZi3/VmVp49K3Mb YMJQ== X-Gm-Message-State: AOJu0YyMwGz8oeiXZXaTy7otWhLlIh+n9iMvj7kgyjx48C0s+t63CWAO vDIugqbHG7+yazCxmNzxyxlAiUVn8cvK6KJodi40PZoNkS1gbOLP3v54MhrqinDigw== X-Gm-Gg: ASbGnctunM6WOVmV/kJdiWHA4/oYu0Cs8pbzQEkk4Q+v9V6or2QbcVx+WBuX/8jY6CI adVFkpAxc0w7kGTBZfhKOxJJgYVf1Nll5B8YM3mzS82UZ9E2JGJE7ZwoFpVlcf4ecV5wYx3xAlQ Cxh6EBLSv/R0lkpQX71fqycpLTXWC8PR4v4YT7IH3GgIj2688WX5OSK72TVE3Y/4tg2djnR8EXH bIwPWA3d3S4ceIeQBhhNfdlLmGsm/kFOyWIi/Lfy2AoWEBALlfmwN91xMP/BYDQynEl8f0bibAr 8um2VGT6iOsyrXe6KR0tC99FolTtHAQjtMS/KLiQYwruYZBP8cqiAgJg4I4wSucOFqF9j3IJVli GaGz7N9zAk0lp1CVBHUg= X-Google-Smtp-Source: AGHT+IGFQZPK7gCfLmUYnjbo20WGBIJwFMaZIRaI++6/zw0QXtNtR50W2mEA98v8RGcbkLPnVlyckA== X-Received: by 2002:a05:6300:4046:b0:1f5:8678:183d with SMTP id adf61e73a8af0-1f5bd8a98c9mr1380466637.14.1741892600587; Thu, 13 Mar 2025 12:03:20 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:20 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 02/13] bpf: Generalize finding member offset of struct_ops prog Date: Thu, 13 Mar 2025 12:02:56 -0700 Message-ID: <20250313190309.2545711-3-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Generalize prog_ops_moff() so that we can use it to retrieve a struct_ops program's offset for different ops. Signed-off-by: Amery Hung Acked-by: Eduard Zingerman --- include/linux/bpf.h | 1 + kernel/bpf/bpf_struct_ops.c | 13 +++++++++++++ net/ipv4/bpf_tcp_ca.c | 23 ++--------------------- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 7d55553de3fc..463e922cb0f5 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1908,6 +1908,7 @@ static inline void bpf_module_put(const void *data, struct module *owner) module_put(owner); } int bpf_struct_ops_link_create(union bpf_attr *attr); +u32 bpf_struct_ops_prog_moff(const struct bpf_prog *prog); #ifdef CONFIG_NET /* Define it here to avoid the use of forward declaration */ diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index db13ee70d94d..1a5a9dee1e4a 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -1387,3 +1387,16 @@ void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struct bpf_map *map info->btf_vmlinux_id = btf_obj_id(st_map->btf); } + +u32 bpf_struct_ops_prog_moff(const struct bpf_prog *prog) +{ + const struct btf_member *m; + const struct btf_type *t; + u32 midx; + + t = btf_type_by_id(prog->aux->attach_btf, prog->aux->attach_btf_id); + midx = prog->expected_attach_type; + m = &btf_type_member(t)[midx]; + + return __btf_member_bit_offset(t, m) / 8; +} diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c index 554804774628..415bd3b18eef 100644 --- a/net/ipv4/bpf_tcp_ca.c +++ b/net/ipv4/bpf_tcp_ca.c @@ -16,7 +16,6 @@ static struct bpf_struct_ops bpf_tcp_congestion_ops; static const struct btf_type *tcp_sock_type; static u32 tcp_sock_id, sock_id; -static const struct btf_type *tcp_congestion_ops_type; static int bpf_tcp_ca_init(struct btf *btf) { @@ -33,11 +32,6 @@ static int bpf_tcp_ca_init(struct btf *btf) tcp_sock_id = type_id; tcp_sock_type = btf_type_by_id(btf, tcp_sock_id); - type_id = btf_find_by_name_kind(btf, "tcp_congestion_ops", BTF_KIND_STRUCT); - if (type_id < 0) - return -EINVAL; - tcp_congestion_ops_type = btf_type_by_id(btf, type_id); - return 0; } @@ -135,19 +129,6 @@ static const struct bpf_func_proto bpf_tcp_send_ack_proto = { .arg2_type = ARG_ANYTHING, }; -static u32 prog_ops_moff(const struct bpf_prog *prog) -{ - const struct btf_member *m; - const struct btf_type *t; - u32 midx; - - midx = prog->expected_attach_type; - t = tcp_congestion_ops_type; - m = &btf_type_member(t)[midx]; - - return __btf_member_bit_offset(t, m) / 8; -} - static const struct bpf_func_proto * bpf_tcp_ca_get_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) @@ -166,7 +147,7 @@ bpf_tcp_ca_get_func_proto(enum bpf_func_id func_id, * setsockopt() to make further changes which * may potentially allocate new resources. */ - if (prog_ops_moff(prog) != + if (bpf_struct_ops_prog_moff(prog) != offsetof(struct tcp_congestion_ops, release)) return &bpf_sk_setsockopt_proto; return NULL; @@ -177,7 +158,7 @@ bpf_tcp_ca_get_func_proto(enum bpf_func_id func_id, * The bpf-tcp-cc already has a more powerful way * to read tcp_sock from the PTR_TO_BTF_ID. */ - if (prog_ops_moff(prog) != + if (bpf_struct_ops_prog_moff(prog) != offsetof(struct tcp_congestion_ops, release)) return &bpf_sk_getsockopt_proto; return NULL; From patchwork Thu Mar 13 19:02:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015812 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B54B01F192E; Thu, 13 Mar 2025 19:03:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892604; cv=none; b=kz3/fPYZqk67Bq5Zv/AIKgLd9eyAtxTAdDIFjzZyKqlU5JXs+dGMft4xLqOF6TM2rwlh/kB+q2Xv+t96Q2qAFQfnDX2KV7aEMZe2KeseIVPbVKDC6Dra1dYU9GRiTSalgs03GITHWFceYnx5qixsL100b5p2F5p3q/Xh6l4AXNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892604; c=relaxed/simple; bh=uvUXT679Ok9m7pSp8UONdHtwRFz9MYJXwSDtsLpmIso=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KkirUvXflWa23h+oLImVhugF/KRmLR9FwTOs8GCl8L5xFm5tPIKjAwORwO91H8tHvfhysVLTd6q/GWttLmcQGHm1MLjNiLaSrMQVB2uWm7fEmjqA4pYa6X1tz2H0MfrOHJq+ZFfzXjLrasyhj0B9ei7YU9iawn8pKfqqjPYMtzo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dP27LXrj; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dP27LXrj" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-224191d92e4so28971905ad.3; Thu, 13 Mar 2025 12:03:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892602; x=1742497402; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Lrkz4aDsMreRmH1bwUi+a9Wu4eVl+hNF0bY8hB1KHyU=; b=dP27LXrjdB5Tfx8kOSJKGvRv9TsYzF+q8hq2jz+anoMIFAu/sjn6Nq6pAZsFHFM4K/ qrwsIfG9mzqC9bgC4+M8UcbyGmQVwy9QzGyVg0tgsWy+3o6MQrNIlRs7Q5/sjkFy8EWh FkAkkDU8T6RSvIY9DxhuDBmcZ9YKY8wfc3UUn6PwiiHmrIpk8opWvYumxqchLMDnOSXi wzpr9+iIYWYiijkNq1RkN+/GaBM8ubObnJINu8g5PUnMYTnftCthSJWhGc2v+jt8tCmW yG8oMiQkbX53oZNUeq6fRbpjQ1ScKtP/UJcfIc1nXb+/YOO1cOPyPM7Q598kbQLIBVE3 bfZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892602; x=1742497402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Lrkz4aDsMreRmH1bwUi+a9Wu4eVl+hNF0bY8hB1KHyU=; b=nWlEi4FLpQFbnAyD8/OB9cjHWX8Y6S8C1c9N+EeJG+QwwB0LjaeOv4Knm6WKZan9XZ bmRGUdSBN6HKmaqOc/ZJBFhD4kur3Aqyg12/Gl7LAdEyDyIuEJ1mURhhyyIV5sjfTgzl CsStGVYuc+ClcgbJDbxC7itcD1754Ik3a1EIC37J57E1MfGG5bBELuVFGNBqYnoYSE+c LBpdPbXJ0SelbFQMW0LK8xoAuC1sY3OkeB1gyLzfTiIyCqYvS+Nv36vLD9ES6i5gS5Tq BylDplaBI1RSLOPaJOvaZd5sjh48rhSpCICJAjbLG91X+mHem3FizgVhtkI3vhDpTpeM vT+Q== X-Gm-Message-State: AOJu0YwDaTRbawTYGFI+BoIcGOiprgJ2/a34PDYolDzCEQ9HcdRdajlz op5PKXVwvVT9anfnHeUUoWOl+j4+sdbjex5xPtuJs+9mTq+cEJs7xLhT5DH63rtl5Q== X-Gm-Gg: ASbGncv3koEqNml9N7dEedReR/u0mgZ7ip3TENPz2SdmGQYjGypXqnpQFB91LGKwI/1 SuBTab0+60i8yvSLGzOnxek0dXglhRsN/zjAu7Oh/AUiJ6m0oAN3OfKwztmk8RtH9dM8u3mlFRG D411+x+KbJdMujh5KX/lQX6WmCnWxsr4+zRba5lLI8wxoI1aafjT6TWQzX1Y0OD4/7FVP5iU72v oYMpECRM9mcqbHHLo4bPXbKjUx32BifXBOG2+mrdko2xUxnjOP90KHXfPoqTXrYFGJ42xss4yOP 9EoWoGtMDuGXsJWE3J3pBAqsHAjSZ1F4q91Kwv/NqNj7G5+0wyjQfg7NDBFwPuNXUdzkMY9Uazp B9qchWM60mFFHIWPq28w= X-Google-Smtp-Source: AGHT+IElijPRTg+5ahfoHGAKrQZdaxOJxboj7dIIIBxaN7D9EXni3f3dgd/oYry1vzjwq7K2IG1TWA== X-Received: by 2002:a05:6a21:9189:b0:1f5:8e94:2e83 with SMTP id adf61e73a8af0-1f5bd785415mr1368521637.8.1741892601695; Thu, 13 Mar 2025 12:03:21 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:21 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 03/13] bpf: net_sched: Support implementation of Qdisc_ops in bpf Date: Thu, 13 Mar 2025 12:02:57 -0700 Message-ID: <20250313190309.2545711-4-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Enable users to implement a classless qdisc using bpf. The last few patches in this series has prepared struct_ops to support core operators in Qdisc_ops. The recent advancement in bpf such as allocated objects, bpf list and bpf rbtree has also provided powerful and flexible building blocks to realize sophisticated scheduling algorithms. Therefore, in this patch, we start allowing qdisc to be implemented using bpf struct_ops. Users can implement Qdisc_ops.{enqueue, dequeue, init, reset, and .destroy in Qdisc_ops in bpf and register the qdisc dynamically into the kernel. Co-developed-by: Cong Wang Signed-off-by: Cong Wang Signed-off-by: Amery Hung Acked-by: Cong Wang --- net/sched/Kconfig | 12 +++ net/sched/Makefile | 1 + net/sched/bpf_qdisc.c | 210 ++++++++++++++++++++++++++++++++++++++++ net/sched/sch_api.c | 7 +- net/sched/sch_generic.c | 3 +- 5 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 net/sched/bpf_qdisc.c diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 8180d0c12fce..ccd0255da5a5 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -403,6 +403,18 @@ config NET_SCH_ETS If unsure, say N. +config NET_SCH_BPF + bool "BPF-based Qdisc" + depends on BPF_SYSCALL && BPF_JIT && DEBUG_INFO_BTF + help + This option allows BPF-based queueing disiplines. With BPF struct_ops, + users can implement supported operators in Qdisc_ops using BPF programs. + The queue holding skb can be built with BPF maps or graphs. + + Say Y here if you want to use BPF-based Qdisc. + + If unsure, say N. + menuconfig NET_SCH_DEFAULT bool "Allow override default queue discipline" help diff --git a/net/sched/Makefile b/net/sched/Makefile index 82c3f78ca486..904d784902d1 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_NET_SCH_FQ_PIE) += sch_fq_pie.o obj-$(CONFIG_NET_SCH_CBS) += sch_cbs.o obj-$(CONFIG_NET_SCH_ETF) += sch_etf.o obj-$(CONFIG_NET_SCH_TAPRIO) += sch_taprio.o +obj-$(CONFIG_NET_SCH_BPF) += bpf_qdisc.o obj-$(CONFIG_NET_CLS_U32) += cls_u32.o obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c new file mode 100644 index 000000000000..00f3232f4a98 --- /dev/null +++ b/net/sched/bpf_qdisc.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include + +static struct bpf_struct_ops bpf_Qdisc_ops; + +struct bpf_sk_buff_ptr { + struct sk_buff *skb; +}; + +static int bpf_qdisc_init(struct btf *btf) +{ + return 0; +} + +static const struct bpf_func_proto * +bpf_qdisc_get_func_proto(enum bpf_func_id func_id, + const struct bpf_prog *prog) +{ + /* Tail call is disabled since there is no gaurantee valid refcounted + * kptrs will always be passed to another bpf program with __ref arguments. + */ + switch (func_id) { + case BPF_FUNC_tail_call: + return NULL; + default: + return bpf_base_func_proto(func_id, prog); + } +} + +BTF_ID_LIST_SINGLE(bpf_sk_buff_ids, struct, sk_buff) +BTF_ID_LIST_SINGLE(bpf_sk_buff_ptr_ids, struct, bpf_sk_buff_ptr) + +static bool bpf_qdisc_is_valid_access(int off, int size, + enum bpf_access_type type, + const struct bpf_prog *prog, + struct bpf_insn_access_aux *info) +{ + struct btf *btf = prog->aux->attach_btf; + u32 arg; + + arg = btf_ctx_arg_idx(btf, prog->aux->attach_func_proto, off); + if (bpf_struct_ops_prog_moff(prog) == offsetof(struct Qdisc_ops, enqueue)) { + if (arg == 2 && type == BPF_READ) { + info->reg_type = PTR_TO_BTF_ID | PTR_TRUSTED; + info->btf = btf; + info->btf_id = bpf_sk_buff_ptr_ids[0]; + return true; + } + } + + return bpf_tracing_btf_ctx_access(off, size, type, prog, info); +} + +static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, + const struct bpf_reg_state *reg, + int off, int size) +{ + const struct btf_type *t, *skbt; + size_t end; + + skbt = btf_type_by_id(reg->btf, bpf_sk_buff_ids[0]); + t = btf_type_by_id(reg->btf, reg->btf_id); + if (t != skbt) { + bpf_log(log, "only read is supported\n"); + return -EACCES; + } + + switch (off) { + case offsetof(struct sk_buff, tstamp): + end = offsetofend(struct sk_buff, tstamp); + break; + case offsetof(struct sk_buff, priority): + end = offsetofend(struct sk_buff, priority); + break; + case offsetof(struct sk_buff, mark): + end = offsetofend(struct sk_buff, mark); + break; + case offsetof(struct sk_buff, queue_mapping): + end = offsetofend(struct sk_buff, queue_mapping); + break; + case offsetof(struct sk_buff, cb) + offsetof(struct qdisc_skb_cb, tc_classid): + end = offsetof(struct sk_buff, cb) + + offsetofend(struct qdisc_skb_cb, tc_classid); + break; + case offsetof(struct sk_buff, cb) + offsetof(struct qdisc_skb_cb, data[0]) ... + offsetof(struct sk_buff, cb) + offsetof(struct qdisc_skb_cb, + data[QDISC_CB_PRIV_LEN - 1]): + end = offsetof(struct sk_buff, cb) + + offsetofend(struct qdisc_skb_cb, data[QDISC_CB_PRIV_LEN - 1]); + break; + case offsetof(struct sk_buff, tc_index): + end = offsetofend(struct sk_buff, tc_index); + break; + default: + bpf_log(log, "no write support to sk_buff at off %d\n", off); + return -EACCES; + } + + if (off + size > end) { + bpf_log(log, + "write access at off %d with size %d beyond the member of sk_buff ended at %zu\n", + off, size, end); + return -EACCES; + } + + return 0; +} + +static const struct bpf_verifier_ops bpf_qdisc_verifier_ops = { + .get_func_proto = bpf_qdisc_get_func_proto, + .is_valid_access = bpf_qdisc_is_valid_access, + .btf_struct_access = bpf_qdisc_btf_struct_access, +}; + +static int bpf_qdisc_init_member(const struct btf_type *t, + const struct btf_member *member, + void *kdata, const void *udata) +{ + const struct Qdisc_ops *uqdisc_ops; + struct Qdisc_ops *qdisc_ops; + u32 moff; + + uqdisc_ops = (const struct Qdisc_ops *)udata; + qdisc_ops = (struct Qdisc_ops *)kdata; + + moff = __btf_member_bit_offset(t, member) / 8; + switch (moff) { + case offsetof(struct Qdisc_ops, peek): + qdisc_ops->peek = qdisc_peek_dequeued; + return 0; + case offsetof(struct Qdisc_ops, id): + if (bpf_obj_name_cpy(qdisc_ops->id, uqdisc_ops->id, + sizeof(qdisc_ops->id)) <= 0) + return -EINVAL; + return 1; + } + + return 0; +} + +static int bpf_qdisc_reg(void *kdata, struct bpf_link *link) +{ + return register_qdisc(kdata); +} + +static void bpf_qdisc_unreg(void *kdata, struct bpf_link *link) +{ + return unregister_qdisc(kdata); +} + +static int Qdisc_ops__enqueue(struct sk_buff *skb__ref, struct Qdisc *sch, + struct sk_buff **to_free) +{ + return 0; +} + +static struct sk_buff *Qdisc_ops__dequeue(struct Qdisc *sch) +{ + return NULL; +} + +static struct sk_buff *Qdisc_ops__peek(struct Qdisc *sch) +{ + return NULL; +} + +static int Qdisc_ops__init(struct Qdisc *sch, struct nlattr *arg, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static void Qdisc_ops__reset(struct Qdisc *sch) +{ +} + +static void Qdisc_ops__destroy(struct Qdisc *sch) +{ +} + +static struct Qdisc_ops __bpf_ops_qdisc_ops = { + .enqueue = Qdisc_ops__enqueue, + .dequeue = Qdisc_ops__dequeue, + .peek = Qdisc_ops__peek, + .init = Qdisc_ops__init, + .reset = Qdisc_ops__reset, + .destroy = Qdisc_ops__destroy, +}; + +static struct bpf_struct_ops bpf_Qdisc_ops = { + .verifier_ops = &bpf_qdisc_verifier_ops, + .reg = bpf_qdisc_reg, + .unreg = bpf_qdisc_unreg, + .init_member = bpf_qdisc_init_member, + .init = bpf_qdisc_init, + .name = "Qdisc_ops", + .cfi_stubs = &__bpf_ops_qdisc_ops, + .owner = THIS_MODULE, +}; + +static int __init bpf_qdisc_kfunc_init(void) +{ + return register_bpf_struct_ops(&bpf_Qdisc_ops, Qdisc_ops); +} +late_initcall(bpf_qdisc_kfunc_init); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index e3e91cf867eb..1aad41b7d5a8 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -358,7 +359,7 @@ static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind) read_lock(&qdisc_mod_lock); for (q = qdisc_base; q; q = q->next) { if (nla_strcmp(kind, q->id) == 0) { - if (!try_module_get(q->owner)) + if (!bpf_try_module_get(q, q->owner)) q = NULL; break; } @@ -1287,7 +1288,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, /* We will try again qdisc_lookup_ops, * so don't keep a reference. */ - module_put(ops->owner); + bpf_module_put(ops, ops->owner); err = -EAGAIN; goto err_out; } @@ -1398,7 +1399,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, netdev_put(dev, &sch->dev_tracker); qdisc_free(sch); err_out2: - module_put(ops->owner); + bpf_module_put(ops, ops->owner); err_out: *errp = err; return NULL; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 14ab2f4c190a..e6fda9f20272 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1078,7 +1079,7 @@ static void __qdisc_destroy(struct Qdisc *qdisc) ops->destroy(qdisc); lockdep_unregister_key(&qdisc->root_lock_key); - module_put(ops->owner); + bpf_module_put(ops, ops->owner); netdev_put(dev, &qdisc->dev_tracker); trace_qdisc_destroy(qdisc); From patchwork Thu Mar 13 19:02:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015813 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C37841F2BAD; Thu, 13 Mar 2025 19:03:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892605; cv=none; b=WdbWQmQGsOJ0wu/JYtPfkOkVU1uF5cgnY9VRQ1IJh9+Km/3Xsn/iPCCYyt9pq8O0tf7biwBK64wekvpjZjaqr9qHpEiPrEMZJlcq/gDouBQWyeqOSVbL0NQGXJVJMRbwO4Cvm0fa7tzfOWS1nkfnaCTyTplVFpwKIGxSg+yzhk8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892605; c=relaxed/simple; bh=599R3VpgWsxsLh3hGv15v6EwAOq/yg+P4ROah6qR1zo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rbex5as0qQoX6Tc4AhRf5zfwxav4aRmx0UdJvdRMlyg65nzM00lcf2EFRcwsI6SUdYUHqSaX3FnmNaAKMRDTKcVpww5clQd4I5eFacoLbG7/eSijKwHL2l1pRvSAx5zD5nl/MEhFjczULDZrm0VFZv0B9vGs1h0Vcn5GcnjT648= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IvAbvMnZ; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IvAbvMnZ" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-224341bbc1dso28767265ad.3; Thu, 13 Mar 2025 12:03:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892603; x=1742497403; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wSydafaY/WsmiIQMqJfn70C+BmyUY73FTlIyW6eivNs=; b=IvAbvMnZ0K4aQO+SXpqGkBdnOupreyRCW26KHKyonJbB74mJWnj9VgbM0fqlkVcqfY pAXjXcv/anEDKhQykJCxnNFYN4qOAdXDwrycNr1GkRnb5HS0KC81tGDgICRMa9Hp84Ui 3RigYYOWH9tYG3Z0nt0wnWu+YOsaOgAzIJxSXIY7E2GyPQFQCoUOkX4H7518/6XgdL72 B0wD3807dlwVBb90cGXMOeJ6m/6juLGOqY6Cq8HZLNtXdchHjxzurRFs7ECXiCDWBILS RWTbZ9hAcu8gjMX2G+WJKpuvK9qh7OiDo90jPIBXAbBKI0Uy1QV5txYSirGXovqS8And 5Y7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892603; x=1742497403; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wSydafaY/WsmiIQMqJfn70C+BmyUY73FTlIyW6eivNs=; b=AXRshL33c4A0NtaWQKGnB2jK2GADlRyrpxjbSHpHTeEfamgrbwsgr0I0+slWWuF1bU DObyMwLs5FW0Qh881k0RCtXrjK54eaTn/ujNlQu+BKxNdI7eJnGni/oFEYTbkT/0ZhYp X0IVQ5ZoKPTGFq2yhjTUeki/fXh5KduX9efCIEEnThjzCEHpCj/3X+RAoGG3y9tnUSdh JF4nyzbB2Ywof3+JZ53+WF2cfMZmqcP6r2jytO+bs5lzqki6Av6qsS8c3yI+RZkPMt9K pxka4ztGHmyg5PIo3SJBWol74i+3zU6MbDhGZ9dYIejKQoXYqCeQqgB82yvQHMvTEyMl NCOA== X-Gm-Message-State: AOJu0YzUjgXHHPZfBdyIo+DhvzTZSQJ+Gtyb6thRQsPxdJX7RDzaAMsp ro8lxEy8uxFtcWVe1l/nC37tnkgHnKJYY5SB4fC7Dsqg3sPaQqXNfphWcONydmee3w== X-Gm-Gg: ASbGncsSshXpl+Uqq1CTfhd5aPvsr/TWyG3Iae3RPrP4BVkxNdHs+7UYwgxrgVgbaQR IOz3k3O0mxT8+sdH7r/NTMknN617ySE2hZhJG1kAgm2Hu13qmWkwVs/YSJId1k+J6ho0W9Ig4ws k93wsUz9ZinxHowlb7pO7iLF5uAefFW2/xzAVX8lNNR+s0UrJ52fXXEYMuXGj4UXphsc5/11ajm VnVQVteMEoP7ls4SZbaH6ZxE57y1RATnryeA45uaFZl9vXYSOY6Gq/NON6kioDVvT06g2K2+Z4a hDTGnalsT1KFDBITwMOocYixab1+Apx+tXOyslpe2DNegHtRP6aKft6g9uIC3uwCADM3yfbIjZL Pvl37wahnWL6coiNNKAI= X-Google-Smtp-Source: AGHT+IEjRSvJWjMEcJjnrGwACOKswdEe7h16nT1S4pm2y869/gQrM0zxLxMLzZ6jCvDzbHnSzys0SQ== X-Received: by 2002:a05:6a21:2d85:b0:1f5:80a3:afe8 with SMTP id adf61e73a8af0-1f58cbdd61dmr17296335637.39.1741892602685; Thu, 13 Mar 2025 12:03:22 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:22 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 04/13] bpf: net_sched: Add basic bpf qdisc kfuncs Date: Thu, 13 Mar 2025 12:02:58 -0700 Message-ID: <20250313190309.2545711-5-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Add basic kfuncs for working on skb in qdisc. Both bpf_qdisc_skb_drop() and bpf_kfree_skb() can be used to release a reference to an skb. However, bpf_qdisc_skb_drop() can only be called in .enqueue where a to_free skb list is available from kernel to defer the release. bpf_kfree_skb() should be used elsewhere. It is also used in bpf_obj_free_fields() when cleaning up skb in maps and collections. bpf_skb_get_hash() returns the flow hash of an skb, which can be used to build flow-based queueing algorithms. Finally, allow users to create read-only dynptr via bpf_dynptr_from_skb(). Signed-off-by: Amery Hung --- include/linux/bpf.h | 1 + kernel/bpf/bpf_struct_ops.c | 2 + net/sched/bpf_qdisc.c | 93 ++++++++++++++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 463e922cb0f5..d3b0c4ccaebf 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1826,6 +1826,7 @@ struct bpf_struct_ops { void *cfi_stubs; struct module *owner; const char *name; + const struct btf_type *type; struct btf_func_model func_models[BPF_STRUCT_OPS_MAX_NR_MEMBERS]; }; diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index 1a5a9dee1e4a..e0a8a9319b84 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -461,6 +461,8 @@ int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc, goto errout; } + st_ops->type = t; + return 0; errout: diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index 00f3232f4a98..69a1d547390c 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -111,6 +111,80 @@ static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, return 0; } +__bpf_kfunc_start_defs(); + +/* bpf_skb_get_hash - Get the flow hash of an skb. + * @skb: The skb to get the flow hash from. + */ +__bpf_kfunc u32 bpf_skb_get_hash(struct sk_buff *skb) +{ + return skb_get_hash(skb); +} + +/* bpf_kfree_skb - Release an skb's reference and drop it immediately. + * @skb: The skb whose reference to be released and dropped. + */ +__bpf_kfunc void bpf_kfree_skb(struct sk_buff *skb) +{ + kfree_skb(skb); +} + +/* bpf_qdisc_skb_drop - Drop an skb by adding it to a deferred free list. + * @skb: The skb whose reference to be released and dropped. + * @to_free_list: The list of skbs to be dropped. + */ +__bpf_kfunc void bpf_qdisc_skb_drop(struct sk_buff *skb, + struct bpf_sk_buff_ptr *to_free_list) +{ + __qdisc_drop(skb, (struct sk_buff **)to_free_list); +} + +__bpf_kfunc_end_defs(); + +BTF_KFUNCS_START(qdisc_kfunc_ids) +BTF_ID_FLAGS(func, bpf_skb_get_hash, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_kfree_skb, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_qdisc_skb_drop, KF_RELEASE) +BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) +BTF_KFUNCS_END(qdisc_kfunc_ids) + +BTF_SET_START(qdisc_common_kfunc_set) +BTF_ID(func, bpf_skb_get_hash) +BTF_ID(func, bpf_kfree_skb) +BTF_ID(func, bpf_dynptr_from_skb) +BTF_SET_END(qdisc_common_kfunc_set) + +BTF_SET_START(qdisc_enqueue_kfunc_set) +BTF_ID(func, bpf_qdisc_skb_drop) +BTF_SET_END(qdisc_enqueue_kfunc_set) + +static int bpf_qdisc_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) +{ + if (bpf_Qdisc_ops.type != btf_type_by_id(prog->aux->attach_btf, + prog->aux->attach_btf_id)) + return 0; + + /* Skip the check when prog->attach_func_name is not yet available + * during check_cfg(). + */ + if (!btf_id_set8_contains(&qdisc_kfunc_ids, kfunc_id) || + !prog->aux->attach_func_name) + return 0; + + if (bpf_struct_ops_prog_moff(prog) == offsetof(struct Qdisc_ops, enqueue)) { + if (btf_id_set_contains(&qdisc_enqueue_kfunc_set, kfunc_id)) + return 0; + } + + return btf_id_set_contains(&qdisc_common_kfunc_set, kfunc_id) ? 0 : -EACCES; +} + +static const struct btf_kfunc_id_set bpf_qdisc_kfunc_set = { + .owner = THIS_MODULE, + .set = &qdisc_kfunc_ids, + .filter = bpf_qdisc_kfunc_filter, +}; + static const struct bpf_verifier_ops bpf_qdisc_verifier_ops = { .get_func_proto = bpf_qdisc_get_func_proto, .is_valid_access = bpf_qdisc_is_valid_access, @@ -203,8 +277,25 @@ static struct bpf_struct_ops bpf_Qdisc_ops = { .owner = THIS_MODULE, }; +BTF_ID_LIST(bpf_sk_buff_dtor_ids) +BTF_ID(func, bpf_kfree_skb) + static int __init bpf_qdisc_kfunc_init(void) { - return register_bpf_struct_ops(&bpf_Qdisc_ops, Qdisc_ops); + int ret; + const struct btf_id_dtor_kfunc skb_kfunc_dtors[] = { + { + .btf_id = bpf_sk_buff_ids[0], + .kfunc_btf_id = bpf_sk_buff_dtor_ids[0] + }, + }; + + ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &bpf_qdisc_kfunc_set); + ret = ret ?: register_btf_id_dtor_kfuncs(skb_kfunc_dtors, + ARRAY_SIZE(skb_kfunc_dtors), + THIS_MODULE); + ret = ret ?: register_bpf_struct_ops(&bpf_Qdisc_ops, Qdisc_ops); + + return ret; } late_initcall(bpf_qdisc_kfunc_init); From patchwork Thu Mar 13 19:02:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015814 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B99BC1F30CC; Thu, 13 Mar 2025 19:03:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892606; cv=none; b=siS62E/JKyRINBk9lEqGOhOKh5VaKOFv9ndm+w6aXjUrA77E0H5z8GfVE6jXW6v2rGzv4kBSphJyWKpwv+euy3wjltnzojKHBGEjCti/tdJpqngFo2RCVuMGNLoO9nKIhSGPd5e3dE2xVstv7u97AiUfDkbQrb6xhgOzKRd/14c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892606; c=relaxed/simple; bh=FPWorS7Tpe+rlq5Kgn0H3infC/85vxSx4GnppcecyGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dGVC6bnNnm49+PrvGLMVPBgjp1ZWclobTqeFHpT80xMmbEbHYNIn7ggC4MMUj9KDyfdC4mm2XPCefwM/EAah1QSRipJcMZc/R3H+zK7PINQ24kYCam7v4XyTETh+RZe1d9eorov2VOOOY3ZycO6E61vh67FKUtqKnPit20qex18= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bFrDNE9o; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bFrDNE9o" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-22398e09e39so29038325ad.3; Thu, 13 Mar 2025 12:03:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892604; x=1742497404; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PTVqWaxfYmIPAROSK14+DooDc9QJZRU2IS03bSh04Dg=; b=bFrDNE9o9+KrIMVEqFZOQsJ/m4PLbPgoQOUAk81Hwb9UTzjLuJJGNMhhwgxYvl3Z1i H1IgEj9tWxR6mQRPtPnyRrtRBsyzq6YrfU7JEN8aHmit2FnNrgz5vh8SuuM//HMusavP Sr/TgQnQvtIk/kGegJ/L+3ioEIQZHvUQhqbQ4E3Ulo/UJmZeFhZcE5VTaXO342KZN6je 4/E2xL35F+kM4x9eJDz5D6XNUh5uuUGZEceHcFcPik/m9nd/CRimVajwsjCFwvRU1mr4 MoS+JRHHBtNNhADvFuzeh6zSoK+SKmPpufQN3JXa+oLg5/0RcKeJjF0YTlBkDry3Kiju Q9Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892604; x=1742497404; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PTVqWaxfYmIPAROSK14+DooDc9QJZRU2IS03bSh04Dg=; b=cKGPpluPAz2o67EkbGkRrn330qDUulHg2GoznJywNL3UwRUjTCii+Nbi2XUef4bXIy vunCdhyz0lllPDqeQ9Hh3GuxaOByuzQW6qberc9Ez2h6Veq0OMs74A2XEGje7Xe5OMit dtUl53SerXQ1RKL4rUjBbd/ePZSJ/sYXjyEWNwA2BNk/cZCZb7pB5m5b1AqcZ266KbzM h9A2ErZ4DVV5/pZCarpQOIZf1Zg+UCImNk1qLxF9itY0gfVvYOwNetmmJN9GWSjc2MlP GlwZZ5pJCwPoZVRnkt6pZI/+eYNCL7P99byjo741aY63DtSD7Z9BpGHXQgypMsXDYAcb Mc6A== X-Gm-Message-State: AOJu0YyHMLdKB/WkZkjMfeaN0OK/ndzTJFmygipFZ6wOgIpWjoKzHOOb XujRk5XussiRI35qhipRdR0pZAisiTjyx1R52WBS5gZonunGV272Pu9OlPV/vMJH5Q== X-Gm-Gg: ASbGnctAUZnwvaGotC2HebQytF+ShSdhUD+H1saypB7LjX+6hgNq1o1Ax/rgkAA0/uU 61nb+3T7U6C7emy56jPvzIjkpsmYVK49k+hkK9UB+XzoTszsqDS1RSgL8IQ0rTLmgnqLOMoAvBS h5NP0BxWQPxWzdoixW3nKtuC50NJ9XKd+oVMxT8ZA5EawTkC53eVaf/bgHFKHG9hmEKQeJJvj8x CAXt42cnHCOg986DtUXiFtt+NCthY7CG6ixRSUCukQvykN/PUayYHQl/Qoa3Xtv3H8FDic6sIf3 xPctvK0RleAe4rtx2IOLZXDRUvTwZAUNGPCzN/NPnwPGm3KjslfBzdgkkmT04rJYXt1jTTMW5yL Y7FsRZDrnU6sFCXeiVKI= X-Google-Smtp-Source: AGHT+IFoo06WkEZkehbe7StgtsbUpGMyjZ66qV0a20AMAWVukO8e2ilYxrUeJCSXJYVsBv/2B6+ZkA== X-Received: by 2002:a05:6a21:a43:b0:1f5:8072:d7f3 with SMTP id adf61e73a8af0-1f5bd95271bmr1376646637.30.1741892603769; Thu, 13 Mar 2025 12:03:23 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:23 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 05/13] bpf: net_sched: Add a qdisc watchdog timer Date: Thu, 13 Mar 2025 12:02:59 -0700 Message-ID: <20250313190309.2545711-6-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Add a watchdog timer to bpf qdisc. The watchdog can be used to schedule the execution of qdisc through kfunc, bpf_qdisc_schedule(). It can be useful for building traffic shaping scheduling algorithm, where the time the next packet will be dequeued is known. Signed-off-by: Amery Hung --- net/sched/bpf_qdisc.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index 69a1d547390c..ae06637f4bab 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -8,6 +8,10 @@ static struct bpf_struct_ops bpf_Qdisc_ops; +struct bpf_sched_data { + struct qdisc_watchdog watchdog; +}; + struct bpf_sk_buff_ptr { struct sk_buff *skb; }; @@ -111,6 +115,46 @@ static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, return 0; } +BTF_ID_LIST(bpf_qdisc_init_prologue_ids) +BTF_ID(func, bpf_qdisc_init_prologue) + +static int bpf_qdisc_gen_prologue(struct bpf_insn *insn_buf, bool direct_write, + const struct bpf_prog *prog) +{ + struct bpf_insn *insn = insn_buf; + + if (bpf_struct_ops_prog_moff(prog) != offsetof(struct Qdisc_ops, init)) + return 0; + + *insn++ = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1); + *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0); + *insn++ = BPF_CALL_KFUNC(0, bpf_qdisc_init_prologue_ids[0]); + *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6); + *insn++ = prog->insnsi[0]; + + return insn - insn_buf; +} + +BTF_ID_LIST(bpf_qdisc_reset_destroy_epilogue_ids) +BTF_ID(func, bpf_qdisc_reset_destroy_epilogue) + +static int bpf_qdisc_gen_epilogue(struct bpf_insn *insn_buf, const struct bpf_prog *prog, + s16 ctx_stack_off) +{ + struct bpf_insn *insn = insn_buf; + + if (bpf_struct_ops_prog_moff(prog) != offsetof(struct Qdisc_ops, reset) && + bpf_struct_ops_prog_moff(prog) != offsetof(struct Qdisc_ops, destroy)) + return 0; + + *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_FP, ctx_stack_off); + *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0); + *insn++ = BPF_CALL_KFUNC(0, bpf_qdisc_reset_destroy_epilogue_ids[0]); + *insn++ = BPF_EXIT_INSN(); + + return insn - insn_buf; +} + __bpf_kfunc_start_defs(); /* bpf_skb_get_hash - Get the flow hash of an skb. @@ -139,6 +183,36 @@ __bpf_kfunc void bpf_qdisc_skb_drop(struct sk_buff *skb, __qdisc_drop(skb, (struct sk_buff **)to_free_list); } +/* bpf_qdisc_watchdog_schedule - Schedule a qdisc to a later time using a timer. + * @sch: The qdisc to be scheduled. + * @expire: The expiry time of the timer. + * @delta_ns: The slack range of the timer. + */ +__bpf_kfunc void bpf_qdisc_watchdog_schedule(struct Qdisc *sch, u64 expire, u64 delta_ns) +{ + struct bpf_sched_data *q = qdisc_priv(sch); + + qdisc_watchdog_schedule_range_ns(&q->watchdog, expire, delta_ns); +} + +/* bpf_qdisc_init_prologue - Hidden kfunc called in prologue of .init. */ +__bpf_kfunc void bpf_qdisc_init_prologue(struct Qdisc *sch) +{ + struct bpf_sched_data *q = qdisc_priv(sch); + + qdisc_watchdog_init(&q->watchdog, sch); +} + +/* bpf_qdisc_reset_destroy_epilogue - Hidden kfunc called in epilogue of .reset + * and .destroy + */ +__bpf_kfunc void bpf_qdisc_reset_destroy_epilogue(struct Qdisc *sch) +{ + struct bpf_sched_data *q = qdisc_priv(sch); + + qdisc_watchdog_cancel(&q->watchdog); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(qdisc_kfunc_ids) @@ -146,6 +220,9 @@ BTF_ID_FLAGS(func, bpf_skb_get_hash, KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_kfree_skb, KF_RELEASE) BTF_ID_FLAGS(func, bpf_qdisc_skb_drop, KF_RELEASE) BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_qdisc_watchdog_schedule, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_qdisc_init_prologue, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_qdisc_reset_destroy_epilogue, KF_TRUSTED_ARGS) BTF_KFUNCS_END(qdisc_kfunc_ids) BTF_SET_START(qdisc_common_kfunc_set) @@ -156,8 +233,13 @@ BTF_SET_END(qdisc_common_kfunc_set) BTF_SET_START(qdisc_enqueue_kfunc_set) BTF_ID(func, bpf_qdisc_skb_drop) +BTF_ID(func, bpf_qdisc_watchdog_schedule) BTF_SET_END(qdisc_enqueue_kfunc_set) +BTF_SET_START(qdisc_dequeue_kfunc_set) +BTF_ID(func, bpf_qdisc_watchdog_schedule) +BTF_SET_END(qdisc_dequeue_kfunc_set) + static int bpf_qdisc_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) { if (bpf_Qdisc_ops.type != btf_type_by_id(prog->aux->attach_btf, @@ -174,6 +256,9 @@ static int bpf_qdisc_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) if (bpf_struct_ops_prog_moff(prog) == offsetof(struct Qdisc_ops, enqueue)) { if (btf_id_set_contains(&qdisc_enqueue_kfunc_set, kfunc_id)) return 0; + } else if (bpf_struct_ops_prog_moff(prog) == offsetof(struct Qdisc_ops, dequeue)) { + if (btf_id_set_contains(&qdisc_dequeue_kfunc_set, kfunc_id)) + return 0; } return btf_id_set_contains(&qdisc_common_kfunc_set, kfunc_id) ? 0 : -EACCES; @@ -189,6 +274,8 @@ static const struct bpf_verifier_ops bpf_qdisc_verifier_ops = { .get_func_proto = bpf_qdisc_get_func_proto, .is_valid_access = bpf_qdisc_is_valid_access, .btf_struct_access = bpf_qdisc_btf_struct_access, + .gen_prologue = bpf_qdisc_gen_prologue, + .gen_epilogue = bpf_qdisc_gen_epilogue, }; static int bpf_qdisc_init_member(const struct btf_type *t, @@ -204,6 +291,11 @@ static int bpf_qdisc_init_member(const struct btf_type *t, moff = __btf_member_bit_offset(t, member) / 8; switch (moff) { + case offsetof(struct Qdisc_ops, priv_size): + if (uqdisc_ops->priv_size) + return -EINVAL; + qdisc_ops->priv_size = sizeof(struct bpf_sched_data); + return 1; case offsetof(struct Qdisc_ops, peek): qdisc_ops->peek = qdisc_peek_dequeued; return 0; From patchwork Thu Mar 13 19:03:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015815 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 981341F3B8A; Thu, 13 Mar 2025 19:03:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892607; cv=none; b=dNZbUTVYwU8RltoFcsKt5zZ2lw3zqHCMnLX6xJwzwHbQqFB9Jmp4E0Olk+D38uWOuqt6YkcIs0M8S68eZbNbwxBpITcGjO4D1GdTa+eQVUCJ+VkkZlI1OHeFT6HmNMsGnl5SROr1opID+NIaRd6IPPDks6Pd1jmzPhORmT4nvKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892607; c=relaxed/simple; bh=PvsjZwquHBtkiD0ex5OqAaIb81/a5+rvsxROvzoxNf4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MhfO6aNKtNv9fNS4iAQZiFgAo8JucczNWP4Cm9YYIYrRPJa0405fzdZydrJVb87XLgHuv1V+eCMCfySKoa0azksoPY7FJDHokXjjAVZwiEN3WMzVv1FBtsWi3oJTI9UbR9NLZ8kBefpzWy9Ejp89txs6mvj6+efQwNh4H63rsH8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=EcKsbbMI; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EcKsbbMI" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-22423adf751so22206295ad.2; Thu, 13 Mar 2025 12:03:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892605; x=1742497405; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Jp4xQH7m5lEMdSS67IiNyx4buTe0VVGMGzphEL5Q8YM=; b=EcKsbbMIooQy/98pmuef1+pgntPKmMEU/JJOsUxnUGBxWVLHO349Whn/SbB6Bo+ZTB QpxN3+tAc3BacQPBkkOdi8pgHAd6ZVXtGslx9iHnVPqu9kmb97JOobZvHu3sXEmbuo3g D05nGcq6PqAU38QPFwdARukgmozI27Krn+1LuSWvp1w4KW9cp0FIlKPHvdXBAYpFEMHd dAvq8SjnJWZjTeYl2NZhdmyFb99TG/7tBIH0EaJ7+n4OzJZDM+N9On/KeJwHHiJeq5f+ 8xE4Ul743GTvlBqiKbf+PmEJ9Urjeg0kmurbziFbKduwHFeWr7hbuJVEvJvMUT75ut8M jSNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892605; x=1742497405; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Jp4xQH7m5lEMdSS67IiNyx4buTe0VVGMGzphEL5Q8YM=; b=Rz2PIasJdRiKV0VXf5+vUjjXsNd2r8DB3CeDC0N12vR7ydUUjDU+rTZEUhql1+zgUl XA4ERiW3wwgDn84Lxfi4G8Vdptg3EnaB1lWuBMerKp7S8WplfKXahRdbAAsmjqssfNQ5 kyUwPFDU9utQWB5kqwi4xxY8TTIxh1+UQvjF5abmVazKzwIIyhFEFF+pyQI6rymO4HxZ uAKwNYd0p2+dKxRdXI4LjGvMIyvpPt72OKjFi3aDlgG8EIbxOQpD32AgyR5a4FrSF6GL lMsN3r4ZdGl11g//YVRRXCYsPbkQ0vA7qvfa2klXPwfgFF3TpSBKxFFXMVET+PC/+e8H cMtg== X-Gm-Message-State: AOJu0YzLevUlHyAFjkPIHIEeYdqVbmxrlZOg2xaiCf01wSx/UCE+QdVB SHl+ECBNNmXo9KcfUw8gFFcgvvDnOm+EI8QnS828K+outcA0YgfZXo8OwX3c9uJf8A== X-Gm-Gg: ASbGncufaKVy2C6KQyBpcRNUO1kcGHHbXpC3dY80A1+VsGeIw7bqXAAIH2InHCxUrfu bvN87YSpQu5TLjscx2H0/+mIuqUIXLc5mpDeQFHpH2WgDHN6cPedZgWXB7QaU/ZDteaYFXgpbqH 1RrFZZAVIz3AS/Eup82LC+5im09LtjiE+JNHFgKOTriimiq08YAXd8RSlm3+wWkJnV66Xc5JJcG LUAAhySDnsSfxQ5Sulu5uutWtFy4BaSaVAvd4dVVjVS/7QsW7hB32rQX8J6W6RPMlpXkXMBvnNj aMaPkI3xm3avBltOS0sXq+O05/TSxae5ADjK6Q8jyxxzP51y/3T8Df7OX8Zc3A3gmDvlnmTLkTk vuGW0zDeXmqpnrAxjG3o= X-Google-Smtp-Source: AGHT+IEViz9aexWCzBKu1TRWDoR4qQOUtDE4jPAiHk+PrnOU78udYENr3+FqtfWBYh+sldk8oNA7CQ== X-Received: by 2002:a05:6a21:6b82:b0:1f5:6e71:e45 with SMTP id adf61e73a8af0-1f5bf84ac57mr472519637.27.1741892604754; Thu, 13 Mar 2025 12:03:24 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:24 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 06/13] bpf: net_sched: Support updating bstats Date: Thu, 13 Mar 2025 12:03:00 -0700 Message-ID: <20250313190309.2545711-7-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Add a kfunc to update Qdisc bstats when an skb is dequeued. The kfunc is only available in .dequeue programs. Signed-off-by: Amery Hung --- net/sched/bpf_qdisc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index ae06637f4bab..edf01f3f1c2a 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -213,6 +213,15 @@ __bpf_kfunc void bpf_qdisc_reset_destroy_epilogue(struct Qdisc *sch) qdisc_watchdog_cancel(&q->watchdog); } +/* bpf_qdisc_bstats_update - Update Qdisc basic statistics + * @sch: The qdisc from which an skb is dequeued. + * @skb: The skb to be dequeued. + */ +__bpf_kfunc void bpf_qdisc_bstats_update(struct Qdisc *sch, const struct sk_buff *skb) +{ + bstats_update(&sch->bstats, skb); +} + __bpf_kfunc_end_defs(); BTF_KFUNCS_START(qdisc_kfunc_ids) @@ -223,6 +232,7 @@ BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_qdisc_watchdog_schedule, KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_qdisc_init_prologue, KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_qdisc_reset_destroy_epilogue, KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_qdisc_bstats_update, KF_TRUSTED_ARGS) BTF_KFUNCS_END(qdisc_kfunc_ids) BTF_SET_START(qdisc_common_kfunc_set) @@ -238,6 +248,7 @@ BTF_SET_END(qdisc_enqueue_kfunc_set) BTF_SET_START(qdisc_dequeue_kfunc_set) BTF_ID(func, bpf_qdisc_watchdog_schedule) +BTF_ID(func, bpf_qdisc_bstats_update) BTF_SET_END(qdisc_dequeue_kfunc_set) static int bpf_qdisc_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id) From patchwork Thu Mar 13 19:03:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015816 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B810B1F3BB5; Thu, 13 Mar 2025 19:03:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892608; cv=none; b=PZl3PIOdWDuxSAakBwy9UPNTaFoHVcGrhpT4XLfDFP3y8o92dxZXiWdTCoBB0DXGvPQpcE6C/PjuIFI8DuU/EMXhJ2J47CBya8uLDxYyNeikrjt1C8aGu9uyhZxbAkLIn5LRbvBEBuNmKKJ08gcjz9h0pSiNgT5a/w8uSTBramo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892608; c=relaxed/simple; bh=vPF4pu/P8uuuCviRPth91G084ytUrBykEU3WXlDjZ8U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lzVUGrV+EvXff4FItTTzRqRHf2F4cr/nrsUpx/Emi58exyIyXBsmmA7wAriYdOSHh6tGDVpauqqlKH80zXIRGM+ahGJ7nswAhQSUZP6dWdR415RMuX3OmHKnxa8hJyxq6dqH6PtLAckq8zG9F8mrOBD39WGj5sq+olgmAxFN91s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ny2p3jwQ; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ny2p3jwQ" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-223a7065ff8so37043615ad.0; Thu, 13 Mar 2025 12:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892606; x=1742497406; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=eY+Y9OxGeDSUuz0ekM5BZDl8hgTH17GlThABvm9XWiw=; b=Ny2p3jwQO4U4hnehjrK3XDNLUTsHpo4vFOTV/DJC9xg3YPpr9krm1JL43Nq0TNhU2f bis8l2rA0BRIwAzBVKNnpyggXkT/TRYeAPBc6XFMu9C0OBlheh7t9o/Y4f3U9FgyJ90z oCZ7FGQT/xIs/I5/v5/r6L74drKM0N3YDAA9ZWB8SpUaBOawacoVPLCjh8ZCRx0T2Mf8 0fcI0N4MeASxkyUmsjTwfOv7rYFEzQiZle0DUGzHluc/AKNvz3zN94o4c4WkGfr4Ea9H DICISwP3ZV6daneSa+AWvHuigE/uc7r+rJQ+ECA7wiPJYRz0Hk+R2f7EVZJf9aTPXcCT KNSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892606; x=1742497406; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eY+Y9OxGeDSUuz0ekM5BZDl8hgTH17GlThABvm9XWiw=; b=Je4UW/IJI2PEfA8w1dMfn535UrTIe0P87iICkoGUyoQzukrMK5cgx2qu9yypa8g6/x uwnea2sG973cRtRXvYd5IX5HOyXYl+8tH5NcABGCG3DnvAsRCCEiA36IKXFQWEpszNkO dyECG0HV7N0CmKqfcG/80E45KnBwl1cze7TLMT3/OkOpIodStx08YU0uPRyEj5IyLgD6 0jU2cPjzeW9TY3U+rF9XFo/6GnB0S+RFE6UrjHNtgQy6E3HnpblZciRMi+8iDqZzZ97b emuZbbbWiPNrWLT9cu+0QYCUdUt0O2aSS2KzHWJMXen7K2224+ZPunMkEG2CQsnHerc/ PhGQ== X-Gm-Message-State: AOJu0Ywrzocm9cU19+ixO8uAY70tfYzo8uko27ffiJ8UUJptnmsjUpvP R2vBlFWZTIjcL05aFUusbaHLgDOmPr7YLTzPNQnGZQzZcfVgtQyOSCEgNTPruk+dJw== X-Gm-Gg: ASbGncsGKX9wYQNlqOzBUELkRz9Vw9zE/I0Y1/MFUoe8oOpOnFGNFpgZk7AYqmlhU+O UOcRcr1QbFhGk1PyYqAeD+5TvN6GdGAUTPWHFfS6FN0Al+COLVOFvZmfWhF1ULPad6+4dRmmiC4 FLGepWZI2pmJNsL+OMmdNFP16LGXPBxruPd829VGaxUT74KM+QjiEHFqFbP29sIBRNoTUe7WBqZ jiR8QbGjN2n0tHj4S80ihVe9UWXvLLF48Gti1V3QqZE1pL/W0pIM+5l15wLHUMd5MCrKWjuTMML hefko6XKuJtmDYc27vOieHN1QdRY9rhEYwsq1Crgcl0I3BuKSZbcEBYr1JjN0f9MMzgUeNcdw15 CxEiBlYFb02qLAIzS+fR0+JRsXSaM+A== X-Google-Smtp-Source: AGHT+IHEWyhsNjlW0lbTXQ8cUQBj7X6D1W1T55Vt+rww5yrGqETiAt+Ps8ysYrHQNJswgQML0/MKfA== X-Received: by 2002:a05:6a21:180a:b0:1f5:591b:4f7c with SMTP id adf61e73a8af0-1f5bd8a945amr1169141637.10.1741892605797; Thu, 13 Mar 2025 12:03:25 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:25 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 07/13] bpf: net_sched: Support updating qstats Date: Thu, 13 Mar 2025 12:03:01 -0700 Message-ID: <20250313190309.2545711-8-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Allow bpf qdisc programs to update Qdisc qstats directly with btf struct access. Signed-off-by: Amery Hung --- net/sched/bpf_qdisc.c | 53 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index edf01f3f1c2a..6ad3050275a4 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -36,6 +36,7 @@ bpf_qdisc_get_func_proto(enum bpf_func_id func_id, } } +BTF_ID_LIST_SINGLE(bpf_qdisc_ids, struct, Qdisc) BTF_ID_LIST_SINGLE(bpf_sk_buff_ids, struct, sk_buff) BTF_ID_LIST_SINGLE(bpf_sk_buff_ptr_ids, struct, bpf_sk_buff_ptr) @@ -60,20 +61,37 @@ static bool bpf_qdisc_is_valid_access(int off, int size, return bpf_tracing_btf_ctx_access(off, size, type, prog, info); } -static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, - const struct bpf_reg_state *reg, - int off, int size) +static int bpf_qdisc_qdisc_access(struct bpf_verifier_log *log, + const struct bpf_reg_state *reg, + int off, int size) { - const struct btf_type *t, *skbt; size_t end; - skbt = btf_type_by_id(reg->btf, bpf_sk_buff_ids[0]); - t = btf_type_by_id(reg->btf, reg->btf_id); - if (t != skbt) { - bpf_log(log, "only read is supported\n"); + switch (off) { + case offsetof(struct Qdisc, qstats) ... offsetofend(struct Qdisc, qstats) - 1: + end = offsetofend(struct Qdisc, qstats); + break; + default: + bpf_log(log, "no write support to Qdisc at off %d\n", off); + return -EACCES; + } + + if (off + size > end) { + bpf_log(log, + "write access at off %d with size %d beyond the member of Qdisc ended at %zu\n", + off, size, end); return -EACCES; } + return 0; +} + +static int bpf_qdisc_sk_buff_access(struct bpf_verifier_log *log, + const struct bpf_reg_state *reg, + int off, int size) +{ + size_t end; + switch (off) { case offsetof(struct sk_buff, tstamp): end = offsetofend(struct sk_buff, tstamp); @@ -115,6 +133,25 @@ static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, return 0; } +static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, + const struct bpf_reg_state *reg, + int off, int size) +{ + const struct btf_type *t, *skbt, *qdisct; + + skbt = btf_type_by_id(reg->btf, bpf_sk_buff_ids[0]); + qdisct = btf_type_by_id(reg->btf, bpf_qdisc_ids[0]); + t = btf_type_by_id(reg->btf, reg->btf_id); + + if (t == skbt) + return bpf_qdisc_sk_buff_access(log, reg, off, size); + else if (t == qdisct) + return bpf_qdisc_qdisc_access(log, reg, off, size); + + bpf_log(log, "only read is supported\n"); + return -EACCES; +} + BTF_ID_LIST(bpf_qdisc_init_prologue_ids) BTF_ID(func, bpf_qdisc_init_prologue) From patchwork Thu Mar 13 19:03:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015817 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0A4A1F3FCB; Thu, 13 Mar 2025 19:03:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892609; cv=none; b=NkG31UyQcxNRQ4157Yixy5kgJCqUpZr0hQWH3tBSMrq/SZzeUm/Jet551cLr4IEiJElk6LBzfPQmKKx9H4vEo5tX8LPfXTCd9UrJ28AXPHEbaqOHj5N4pZv0iiGDoDUvtUfivH3vMdBuGfTL2PD8qeGsSE4KzO6rXFurejRE0AU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892609; c=relaxed/simple; bh=oVv2JtaDPIKhZsdywXA46ACT2BCLo0/oHTOdRQDrkDg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HENwQ5gVOT/5J6d30tVMSv+hRY9CL7kpzX2xyuYuobcdtCH/W/mvevFqsqfapLOuK2kizxkwLfiEftVtC29ugXzVoMhO/XtfnC6lWDr+Ody8QwyGSwuyKmbQCIjvcs3LL8do3L0ZRaXwGrSQc7GPbVPwNL4IrXFbFhcyVQTJ9po= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mnDOkxOD; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mnDOkxOD" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-22349bb8605so31092855ad.0; Thu, 13 Mar 2025 12:03:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892607; x=1742497407; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6GH5rMBh11R0Ev4mXMfCpLP6RKJCsJzPSkJfSqyVzrk=; b=mnDOkxODZsXOTZQ9qDL8iiPkQaMHPGMHMiPcbpP93+afrz6tS+LrSnnkEg1ytNKnIh KznVIjf4s/UzECDUj/EIDS4dQ5hZbcRa9eCuPGBh/vMVLwTSI2qB51znSD8OObV3Tgkw UUo66bqqMcGdHEYMZMYJu8kMVZeu8gwnGMj69iljI0xLohHjiq/XZVTILxpAXT0z3wbm NtHV8pOWHwRLMEpQCOpMq6u/TEFnb68aXw+CJojWooeyT9WjTKx/Ot1lJpeCeELeLBZI pWNX7lIeT/GCWovI6PDNEzrKZwasz5RqtyauQMySxvxUAVb5/OBqamJprfQbudSh65LX Deiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892607; x=1742497407; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6GH5rMBh11R0Ev4mXMfCpLP6RKJCsJzPSkJfSqyVzrk=; b=FD9yjcnDe4fwgPmWy0shyeGZuGbk4qvX2RRiQPaCj25V829I0NKaV6GWqBW/3K14lT dWudkWCoqJK/zsqCfrcof8yK7hTAOPff7HeA4tWXaMm+U2cOj8zKqL9qWPP8lLPjq4xL Y+ykQDqFq6JoSzF+LGGi8xkMiMHgFQo6Aq2XlkP1AlakXrGdn6TMFT0i8VN/y8KjJgeD MxbXnNOkcv6FTWibm4QNNluPFfgTHzskJvyUXm1YOypMXt+brCTQXbFN4RUkVAsw3ZLy 2ekbfU+vRW2/16BSC7y9tAKuQim1xLaESebVFv3M6vsGtgtcU6diDb6221v0MbWgc3c0 2cJA== X-Gm-Message-State: AOJu0Yzud7xERVn1TEf66AtPS2cgls79KP1Zog7MOSyziJ4bwognnMg9 dkQYjQtg1jfhsMusYt3V0mY9scVCI5WHhuwbamy6RSm+qsYQTsK9qfHYSz0QUHQNTA== X-Gm-Gg: ASbGnctED947SDf+RR7CDiSfApzu4sQJDiWTfw8NnCDGLqyjkYmQQXLwhqGyoh9TSvb Su0+737HEbH74fxkdyKA5GfrxBTkKoF+GSongXHtXAcVSxPYwc7AUNJMtfTnauruFaAgpZDZPVO 29L7PwQ10EknVevnPrPeOWTWNyj1etDczHF5r6q33zoeVLetysPsxhVYOPEy3eQFoxWj/nYOH+C C/OmLHRTdbaOpAsA4Bg4gbZHahuJXPW/7B40eoK7hDA6NFrfPpjHL2HvCrR5rKcU5F1FDkawxWB +LhgKmMKGV5g2N4mPHWGrArKPhZgYtww4qAb42Ngmd3yUOfhfIeTkhwnxxfE4GWd4kSJTgqfjSH UxWusndFgozwjYk9znqc= X-Google-Smtp-Source: AGHT+IEaZLQ5SVTNwT5WE9ZJPQ5WCSpIZ5M8IeqsbZumlsj2hhjlUpxPjFHs6E9RQThKfNWL7eOYbA== X-Received: by 2002:a05:6a21:2d87:b0:1ee:d06c:cddc with SMTP id adf61e73a8af0-1f5bd8c2cacmr1377381637.30.1741892606779; Thu, 13 Mar 2025 12:03:26 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:26 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 08/13] bpf: net_sched: Allow writing to more Qdisc members Date: Thu, 13 Mar 2025 12:03:02 -0700 Message-ID: <20250313190309.2545711-9-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Allow bpf qdisc to write to Qdisc->limit and Qdisc->q.qlen. Signed-off-by: Amery Hung --- net/sched/bpf_qdisc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index 6ad3050275a4..e4e7a5879869 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -68,6 +68,12 @@ static int bpf_qdisc_qdisc_access(struct bpf_verifier_log *log, size_t end; switch (off) { + case offsetof(struct Qdisc, limit): + end = offsetofend(struct Qdisc, limit); + break; + case offsetof(struct Qdisc, q) + offsetof(struct qdisc_skb_head, qlen): + end = offsetof(struct Qdisc, q) + offsetofend(struct qdisc_skb_head, qlen); + break; case offsetof(struct Qdisc, qstats) ... offsetofend(struct Qdisc, qstats) - 1: end = offsetofend(struct Qdisc, qstats); break; From patchwork Thu Mar 13 19:03:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015818 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA0991F3FEE; Thu, 13 Mar 2025 19:03:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892610; cv=none; b=FHvvJXlN9JUZyhBij0LfCKIdsntcXx7O0y/ttWLg7CgLX/vV4/z3nEC2/FsMF6gQZucjWg+JzhG4C75l4kFYjQosj9wR9A2mr1gzYesyRBL730q8y3XOxjAVqB+U2iQ0mOwq4lnW5hSWeBiftfraLbmliI/CGGoYRrXx9oEwFuY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892610; c=relaxed/simple; bh=70fK2D1VKNnq07QhB2X+UwPEhOlQN3WCUcZ4aBXmKGs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aZicpdmRi2dfMbWxe/biaF1VgkUtcoqVMJ6SxZKTKwwcvw3N78IcLyMNc0dJTI+/eRTRV2UWfk0J/wBAfx55S1tJCY9LIvqhjY6bFL3iIvrCeGHvAiY0JAEkunts84h8OxeVvvth8gNIiE0bUGvGfugu53AAaZLKDTWuMlSjOgo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jwJ3s/8y; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jwJ3s/8y" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-219f8263ae0so26220135ad.0; Thu, 13 Mar 2025 12:03:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892608; x=1742497408; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aFDTynPkfE2pHRJC+9xprWx2iQpT2oTsma7USZIPR7A=; b=jwJ3s/8yM2eQtsWXGqnaH8FnOx6qebU5pN4WNMXskJFt1ZUMCpxO/i8QXybz5N4Yor Y5xaKSXOLLDe0ErnQDj9uP7gny9U3kknekChRhk7gramuCwKJt8cpmzNYebEnGrsJ4DK rVcKOhUhALXtzl3NqweSYGq/S5gMGp7FgTjf+LWNWE0SF2zF7gb7DUsgMqp1RVjDp8Th iCn+JSs7sEesZGTzD/JviaSk42DXixfFZNWXjhjORR2StxL3hsh2KjjqetSI6Obukubg /dDTrmBxmNoz48e7R+apCgDdCEOLa2I5xtg5yRgywYBCKkM0UtdlKN/bILLHF6nXnDNZ osag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892608; x=1742497408; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aFDTynPkfE2pHRJC+9xprWx2iQpT2oTsma7USZIPR7A=; b=gEg6FMhyWTc8aexcjqF0eYpI8nvWoxsw2q9vG8LP9Y/FZ7GGGQ4/AIVVuw4o8zLBml rnBEjzrXSdpVQqP/nY8JgvOVXfkNFevpCMxeXKOS2M3l2q++go/PHUsic7O7UzMWj37t +/gnemZtOeJmB8vOa849N9kznheXoEGBB9XE/XvBJEzRefb3JvIls9jUe7vHC5LnHDr+ FvkeL8K8jb+sToQWLJ+UqxfJvlahBk9kzKZT0NwZdNl5pc5Ozoax82ZZBUnp3uZlI1YD qdDOptuPY01OvbOWu0WLSEd16Brg/Yc2/vc6jn3Y8GZxFgsrOv+8XbD1ICoZgL7nwP6x /liw== X-Gm-Message-State: AOJu0YzEcT/xZE3iiEor2tTSUSOYOPTdWx9+n2oyKeIyrc9nad/TrRqj q3mtsC9vJpO/CGkrVJiz1/S+PkFlatdNpJ8OceDMZ/A8jM/BaH0ZgRgjWr4qp9Qvlg== X-Gm-Gg: ASbGncsuYMlDKkar+CrCUuFoi10VnAghKOpyga1S2KvRhQ5ATE6pcAdSZm4bbwWd4MS AMsK7awbjETAgf2cGc67C6iH0FdcUi96sqlZwSUMNVkuHnQLyOVnUXFFexoYnJG78Mf8Lc1j1nv ILlslqjRkCUdCp7hKQeE3timQBHPV1dqLRyQdLbAcDwChC943HLKR3JnxOvg90GAWjceNxjo7u4 TYLQS2YEmgwQma4tLSlhjvg6jad5AGsJdbbv2sLPN+Tfid7uE/SjIk1vDTx+SkPM1xuNz07JbnK RYrCClVytJW9TqOeU4KKrS81o9wAKxLbmG46iKtL04qt+y7IZHlpZIbpkbr89FCEGpUDiAiIklI dFBANyuKXjLPyy9OWR2o= X-Google-Smtp-Source: AGHT+IGYFzJg++LlVwbp0OBA+5YiTMxibihqcJ86fzzwPBn3xdcqJxXhZItZqAbfAOF5s2RaExnCdA== X-Received: by 2002:a05:6a20:ce4b:b0:1ee:e96a:d9ed with SMTP id adf61e73a8af0-1f58cad4a5dmr20835403637.7.1741892607793; Thu, 13 Mar 2025 12:03:27 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:27 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 09/13] bpf: net_sched: Disable attaching bpf qdisc to non root Date: Thu, 13 Mar 2025 12:03:03 -0700 Message-ID: <20250313190309.2545711-10-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Do not allow users to attach bpf qdiscs to classful qdiscs. This is to prevent accidentally breaking existings classful qdiscs if they rely on some data in the child qdisc. This restriction can potentially be lifted in the future. Note that, we still allow bpf qdisc to be attached to mq. Signed-off-by: Amery Hung --- net/sched/bpf_qdisc.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index e4e7a5879869..c2f33cd35674 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -170,8 +170,11 @@ static int bpf_qdisc_gen_prologue(struct bpf_insn *insn_buf, bool direct_write, return 0; *insn++ = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1); + *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 16); *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0); *insn++ = BPF_CALL_KFUNC(0, bpf_qdisc_init_prologue_ids[0]); + *insn++ = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1); + *insn++ = BPF_EXIT_INSN(); *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6); *insn++ = prog->insnsi[0]; @@ -239,11 +242,26 @@ __bpf_kfunc void bpf_qdisc_watchdog_schedule(struct Qdisc *sch, u64 expire, u64 } /* bpf_qdisc_init_prologue - Hidden kfunc called in prologue of .init. */ -__bpf_kfunc void bpf_qdisc_init_prologue(struct Qdisc *sch) +__bpf_kfunc int bpf_qdisc_init_prologue(struct Qdisc *sch, + struct netlink_ext_ack *extack) { struct bpf_sched_data *q = qdisc_priv(sch); + struct net_device *dev = qdisc_dev(sch); + struct Qdisc *p; + + if (sch->parent != TC_H_ROOT) { + p = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); + if (!p) + return -ENOENT; + + if (!(p->flags & TCQ_F_MQROOT)) { + NL_SET_ERR_MSG(extack, "BPF qdisc only supported on root or mq"); + return -EINVAL; + } + } qdisc_watchdog_init(&q->watchdog, sch); + return 0; } /* bpf_qdisc_reset_destroy_epilogue - Hidden kfunc called in epilogue of .reset From patchwork Thu Mar 13 19:03:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015819 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F1F21F4186; Thu, 13 Mar 2025 19:03:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892611; cv=none; b=pTByKLduqFVcce2DQdPNvbmzwyFZbOuwwkF2R3+m4PJbjJVCWI54ZcE7uEsLB0M/oTMwDRCNL0zuKMFG95rSOxkiEgDpn3LUxin+Tyy4cSFfJcZIuEtrluSkbJ2Zof6yZ0sR4kusP9du7FpF7kXIpI1wfqG4iJz2iA1xsHYvBgk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892611; c=relaxed/simple; bh=jpOgH4a8Ds1xnL1nmdR7TDa9aI0Ex8U6aEF/JjDBYOo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PfUHZycVJz47ykLcp7IAaIdO3qwEF7NPAsGVRt+hxTNq3MQNxPKnipS/N1jJyHxsRCycUBonPAaF6PB1Xz+2a/CvEQQz8ItYfudWIaaG7BkoIQ6PlXQwUzeSuxEaPpQRee9YwP4hlGbRovDDsE0yamV5RN7xochuEjT88mZSd1Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BH2LH7Ac; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BH2LH7Ac" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-22355618fd9so28387515ad.3; Thu, 13 Mar 2025 12:03:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892609; x=1742497409; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=slC/xxmyiHhZuV5shK7ICE09JWvyZwyxSejcvp1dZss=; b=BH2LH7AcNTfSgsBC0MuG8imw5dp/8j1sUCxHlorGaaWh2K/9i384hPiq+vkL+JvRfr /YfUdD8H1RAXXmsuCFsfpADQvjxxF3XAUK3tv+uTF0qneYtCc9YjMdfYufylsJsMzEUL FDxw1DVT6m2RDdxbjCK4w94xSsO7WjhS0Pe/O/SRVFl52et+qeQFImC9qfM961h/wrUV rxzqWMLwKkBGwGY10Ge0oLCqMMN4jaPujOJX3+44OhyMMy8nfs9bp4/HSUOeEbkKHwVi 3yaspfg849CGuUe5eP6TQGuSbr7YnCkLJqb+CzZhihqqumFwxtAGmbZO1UXHBOe3FQNy v9nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892609; x=1742497409; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=slC/xxmyiHhZuV5shK7ICE09JWvyZwyxSejcvp1dZss=; b=Og4GpN4S0O4+puj9YEq0hsDt3VAtKkuv3iCr/L5wGvasGr5F4pngbe8sguDMuwpuv8 jL/SPWanBaX2PjIbyc3cgtdJzkw8OD5dExte8n2CJiLrUXKwqTgmTE4bkFrsw6lmDSdJ j8/qvIcstoN2rbkaLRXHKPWZ+StJdt8hSxo3Ol2Yz3RAHR5OecDmVJnBH5d4shTCWjTW cuhmroT5XStdmMVMeA3oAJ8r2F5Evq941wJxc8Y8U0JCcMtgQgI90J5ztYPPEXWvi/nn K0fHvtxCdxXPcOCiB5gJ3AEteVBSFQSQCD6wfOXBHmMo8UTVd4/12hpz3uFCZKjRV5Pm I0JQ== X-Gm-Message-State: AOJu0YwSG9ciyOaePClXgpVMo+A0/A+t4mX8HS7Xphs/KPX81iGJes5G /GTLFrsmBTJTHwwLhT625DleGUabgPhudYVTzGxWxc+necjI10anSJD+3s0P39ZUxQ== X-Gm-Gg: ASbGncvPTEjJH9SJQH7zMd/U090KYmHxdL1XCF9VkphUZaPIlGUS2AgAr8szL1pntd+ fpUwsKln0iElKRnAByhoVnrfIcQC9aPBy+Lw/+nRt1TH1hnQf6nTIAA0bSWbXIpihJ+asJI+sB6 UmRYt4JmQM1ytGOFqyLF8nhOrLoL2z9EqRRkafApH25KiBmDPH0AIGTCM6nIZ6qky2NgSArKtUe Pd9DGpPyK647BBNuTCqblsKApHfrR3dTvHrecNgcPdvtIsgfCDyVlhLNlxMXCXo98O1t9TVKp/K Q7XvNq5KGWq71zuuGqyTU6IZZ+5SlvusfM82eEZZsvDQJHlMD/g1rbZabwAidlyLlPqwv6r7MLZ IIJcHNOAGPPZEACBqNYU= X-Google-Smtp-Source: AGHT+IFudgtJbiQ9GR0vEaYspoRX+BDnwDdo9jMQMExrkrVoic2iL+mX29vH9/DUnwRmXI/n2Y5MMA== X-Received: by 2002:a05:6a21:6e93:b0:1f5:6abb:7cbb with SMTP id adf61e73a8af0-1f5bf775535mr521232637.23.1741892608812; Thu, 13 Mar 2025 12:03:28 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:28 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 10/13] libbpf: Support creating and destroying qdisc Date: Thu, 13 Mar 2025 12:03:04 -0700 Message-ID: <20250313190309.2545711-11-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung Extend struct bpf_tc_hook with handle, qdisc name and a new attach type, BPF_TC_QDISC, to allow users to add or remove any qdisc specified in addition to clsact. Signed-off-by: Amery Hung --- tools/lib/bpf/libbpf.h | 5 ++++- tools/lib/bpf/netlink.c | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index e0605403f977..fdcee6a71e0f 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -1283,6 +1283,7 @@ enum bpf_tc_attach_point { BPF_TC_INGRESS = 1 << 0, BPF_TC_EGRESS = 1 << 1, BPF_TC_CUSTOM = 1 << 2, + BPF_TC_QDISC = 1 << 3, }; #define BPF_TC_PARENT(a, b) \ @@ -1297,9 +1298,11 @@ struct bpf_tc_hook { int ifindex; enum bpf_tc_attach_point attach_point; __u32 parent; + __u32 handle; + const char *qdisc; size_t :0; }; -#define bpf_tc_hook__last_field parent +#define bpf_tc_hook__last_field qdisc struct bpf_tc_opts { size_t sz; diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c index 68a2def17175..c997e69d507f 100644 --- a/tools/lib/bpf/netlink.c +++ b/tools/lib/bpf/netlink.c @@ -529,9 +529,9 @@ int bpf_xdp_query_id(int ifindex, int flags, __u32 *prog_id) } -typedef int (*qdisc_config_t)(struct libbpf_nla_req *req); +typedef int (*qdisc_config_t)(struct libbpf_nla_req *req, const struct bpf_tc_hook *hook); -static int clsact_config(struct libbpf_nla_req *req) +static int clsact_config(struct libbpf_nla_req *req, const struct bpf_tc_hook *hook) { req->tc.tcm_parent = TC_H_CLSACT; req->tc.tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0); @@ -539,6 +539,16 @@ static int clsact_config(struct libbpf_nla_req *req) return nlattr_add(req, TCA_KIND, "clsact", sizeof("clsact")); } +static int qdisc_config(struct libbpf_nla_req *req, const struct bpf_tc_hook *hook) +{ + const char *qdisc = OPTS_GET(hook, qdisc, NULL); + + req->tc.tcm_parent = OPTS_GET(hook, parent, TC_H_ROOT); + req->tc.tcm_handle = OPTS_GET(hook, handle, 0); + + return nlattr_add(req, TCA_KIND, qdisc, strlen(qdisc) + 1); +} + static int attach_point_to_config(struct bpf_tc_hook *hook, qdisc_config_t *config) { @@ -552,6 +562,9 @@ static int attach_point_to_config(struct bpf_tc_hook *hook, return 0; case BPF_TC_CUSTOM: return -EOPNOTSUPP; + case BPF_TC_QDISC: + *config = &qdisc_config; + return 0; default: return -EINVAL; } @@ -596,7 +609,7 @@ static int tc_qdisc_modify(struct bpf_tc_hook *hook, int cmd, int flags) req.tc.tcm_family = AF_UNSPEC; req.tc.tcm_ifindex = OPTS_GET(hook, ifindex, 0); - ret = config(&req); + ret = config(&req, hook); if (ret < 0) return ret; @@ -639,6 +652,7 @@ int bpf_tc_hook_destroy(struct bpf_tc_hook *hook) case BPF_TC_INGRESS: case BPF_TC_EGRESS: return libbpf_err(__bpf_tc_detach(hook, NULL, true)); + case BPF_TC_QDISC: case BPF_TC_INGRESS | BPF_TC_EGRESS: return libbpf_err(tc_qdisc_delete(hook)); case BPF_TC_CUSTOM: From patchwork Thu Mar 13 19:03:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015820 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB7D41F4284; Thu, 13 Mar 2025 19:03:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892612; cv=none; b=jokMyWsuZxiwRKiqCGjU5oa872z8fq5mp1ELD6lO234waMBcMYWMEpV4vzPYEpkXt2wuZuxkDam+sXVuC0ZziH90P1IOyhA0Ag19CYyPTFERPl4t5kOtKvtTGRUDtnjtDAOWYBbwU9l8rK6NQM6i7ELcYwBDqiRIYtbontqGzes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892612; c=relaxed/simple; bh=RFTb05MOTvQ1XNo5zRefdOckyFOYcGFeYSohdaoDjRI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DYdVrw7wYwebSdvztSizBiAkRd6lckxpNzqn1dQFbs/jEyglr1fq0KZn/oDqju6wQ9+pokaz+NoYSDQgDFKJ8F1LphXB8Hp+tVQI5QSq9iJlTckeM6Q7ZvPle3p187taaNmUfs6pLmSxYo+s+R/7detdgfRbRIjeWkUjFre7byY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=LmQUlX8D; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LmQUlX8D" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-22398e09e39so29040305ad.3; Thu, 13 Mar 2025 12:03:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892610; x=1742497410; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uj2Ol0TrAZxxMAWaqZASaKyaG7rHi/lbAJ67oVFmDO8=; b=LmQUlX8DSVIGQH6zLQ8Pjr+VoQ1JH5yfao7W0a2KMVGh0+kWjlQtMuIM+Lp/69NqFN A49rWsVy8FM6hAKuJNc/1vX5b5Fg5bLD45L5oKbCHP2h0QokaboK4jlNRzOJhB4PRsmP xgLEDNzdRcspZn4/38aNmikWoGiIIiop/P06WsUXzoCnuwTdPm+YmmI97p6IMH8vk3H7 rO/T0bZLXz9yv3wyY2jxlM4EHVpdy0o94jG2IKiby+RerVPI7yelpTdvtlk19Hln/1wd WA+BY0Fa2b0+ZcuKvGUrQBRxKtLE/VsELNHP9FgP7M4/bAioG6GWb5LMEBv1bNe5qdhb 0Xog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892610; x=1742497410; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uj2Ol0TrAZxxMAWaqZASaKyaG7rHi/lbAJ67oVFmDO8=; b=aAY6w4C5M+sQcZpSQK6WU6PN5ynuy3gOO9noxAYxbSAw2C/x3eIosc50T6JVQHmjsf waJwVUiZFjyMYdNdo8cdn8ydgr5xlZb3GGgXLSZaNJOGMV/14CyI6LKr2B8AJebwxVGq txKlwXldFm4hNqszKSeSdHA0N7NQWoBBrXlosBM960VYWCkwq84PYPvGdOp+/xJaQai1 MxZp8vdYc6xFD/mAEBdQpZYWdwUP57LpuzJcSXDCb2RnMUzrJ+Je+Kg2q8HQjpwxVVFC 0LrUMuK39wiI2jkR/dXPQ7mkjDQ7Rr+l0qF2xU65QhzD/V8BnsKLKUnonD0PWgYM4vJV E9LA== X-Gm-Message-State: AOJu0YwWwrm6kTNZTmSQ6k/huFtwbVsdcCMv/sv6eu+SV7wasNujXSwr nDUOZY7iWn7zszVkXrWjGc3vlA4dc2P627hygbHkWQlpDL9uhEulzxMTZUIwUaui/g== X-Gm-Gg: ASbGnctFSJ++8VOcrb49ClYSVdWFiiJznSeRoJztCwvbUGFzHOJot4YBWHu+9ALWGV2 KartlZmr62Qh+TlAMTs7n3+twFoENMNy7FXNG9cicQO9fxwwwjOSh4OeNvbuZB826Nu8jchqqfs 4FlSih3icHJURFre9yDUM2eE7zRywAs/UP+42PshYD6Qgi9R4GS0b2TWuKrWakUeqwH31QCdHkK XLu0DNnHJFeupcjfiDxr40gckiihTM/0FCHXtuazqDquiee4FUkbwrrnu8pFic95t9rmjasEaT9 tYl7K8O8RfRpQeFmdUcFz/oa0ru4T2gz7m1JNA2RoMDd72wphqaqIB8fGdBQ9o22JevKeFh2AMp ZwXurmGt2ORRKgOh047s= X-Google-Smtp-Source: AGHT+IFkRgRGR3e8eA+mzEY5bk2juvLiCAbfN8lGzjxyPO9UmOxlQb974X5DyIsq/jmmHjsDVGO8wQ== X-Received: by 2002:a05:6a21:62c8:b0:1d9:c615:d1e6 with SMTP id adf61e73a8af0-1f5bd5b7d9cmr1355525637.0.1741892609816; Thu, 13 Mar 2025 12:03:29 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:29 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 11/13] selftests/bpf: Add a basic fifo qdisc test Date: Thu, 13 Mar 2025 12:03:05 -0700 Message-ID: <20250313190309.2545711-12-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung This selftest includes a bare minimum fifo qdisc, which simply enqueues sk_buffs into the back of a bpf list and dequeues from the front of the list. Signed-off-by: Amery Hung --- tools/testing/selftests/bpf/config | 1 + .../selftests/bpf/prog_tests/bpf_qdisc.c | 79 ++++++++++++ .../selftests/bpf/progs/bpf_qdisc_common.h | 27 ++++ .../selftests/bpf/progs/bpf_qdisc_fifo.c | 117 ++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c create mode 100644 tools/testing/selftests/bpf/progs/bpf_qdisc_common.h create mode 100644 tools/testing/selftests/bpf/progs/bpf_qdisc_fifo.c diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config index c378d5d07e02..6b0cab55bd2d 100644 --- a/tools/testing/selftests/bpf/config +++ b/tools/testing/selftests/bpf/config @@ -71,6 +71,7 @@ CONFIG_NET_IPGRE=y CONFIG_NET_IPGRE_DEMUX=y CONFIG_NET_IPIP=y CONFIG_NET_MPLS_GSO=y +CONFIG_NET_SCH_BPF=y CONFIG_NET_SCH_FQ=y CONFIG_NET_SCH_INGRESS=y CONFIG_NET_SCHED=y diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c new file mode 100644 index 000000000000..f2efc69af348 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c @@ -0,0 +1,79 @@ +#include +#include +#include + +#include "network_helpers.h" +#include "bpf_qdisc_fifo.skel.h" + +#define LO_IFINDEX 1 + +static const unsigned int total_bytes = 10 * 1024 * 1024; + +static void do_test(char *qdisc) +{ + DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX, + .attach_point = BPF_TC_QDISC, + .parent = TC_H_ROOT, + .handle = 0x8000000, + .qdisc = qdisc); + int srv_fd = -1, cli_fd = -1; + int err; + + err = bpf_tc_hook_create(&hook); + if (!ASSERT_OK(err, "attach qdisc")) + return; + + srv_fd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0); + if (!ASSERT_OK_FD(srv_fd, "start server")) + goto done; + + cli_fd = connect_to_fd(srv_fd, 0); + if (!ASSERT_OK_FD(cli_fd, "connect to client")) + goto done; + + err = send_recv_data(srv_fd, cli_fd, total_bytes); + ASSERT_OK(err, "send_recv_data"); + +done: + if (srv_fd != -1) + close(srv_fd); + if (cli_fd != -1) + close(cli_fd); + + bpf_tc_hook_destroy(&hook); +} + +static void test_fifo(void) +{ + struct bpf_qdisc_fifo *fifo_skel; + struct bpf_link *link; + + fifo_skel = bpf_qdisc_fifo__open_and_load(); + if (!ASSERT_OK_PTR(fifo_skel, "bpf_qdisc_fifo__open_and_load")) + return; + + link = bpf_map__attach_struct_ops(fifo_skel->maps.fifo); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) { + bpf_qdisc_fifo__destroy(fifo_skel); + return; + } + + do_test("bpf_fifo"); + + bpf_link__destroy(link); + bpf_qdisc_fifo__destroy(fifo_skel); +} + +void test_bpf_qdisc(void) +{ + struct netns_obj *netns; + + netns = netns_new("bpf_qdisc_ns", true); + if (!ASSERT_OK_PTR(netns, "netns_new")) + return; + + if (test__start_subtest("fifo")) + test_fifo(); + + netns_free(netns); +} diff --git a/tools/testing/selftests/bpf/progs/bpf_qdisc_common.h b/tools/testing/selftests/bpf/progs/bpf_qdisc_common.h new file mode 100644 index 000000000000..62a778f94908 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_qdisc_common.h @@ -0,0 +1,27 @@ +#ifndef _BPF_QDISC_COMMON_H +#define _BPF_QDISC_COMMON_H + +#define NET_XMIT_SUCCESS 0x00 +#define NET_XMIT_DROP 0x01 /* skb dropped */ +#define NET_XMIT_CN 0x02 /* congestion notification */ + +#define TC_PRIO_CONTROL 7 +#define TC_PRIO_MAX 15 + +u32 bpf_skb_get_hash(struct sk_buff *p) __ksym; +void bpf_kfree_skb(struct sk_buff *p) __ksym; +void bpf_qdisc_skb_drop(struct sk_buff *p, struct bpf_sk_buff_ptr *to_free) __ksym; +void bpf_qdisc_watchdog_schedule(struct Qdisc *sch, u64 expire, u64 delta_ns) __ksym; +void bpf_qdisc_bstats_update(struct Qdisc *sch, const struct sk_buff *skb) __ksym; + +static struct qdisc_skb_cb *qdisc_skb_cb(const struct sk_buff *skb) +{ + return (struct qdisc_skb_cb *)skb->cb; +} + +static inline unsigned int qdisc_pkt_len(const struct sk_buff *skb) +{ + return qdisc_skb_cb(skb)->pkt_len; +} + +#endif diff --git a/tools/testing/selftests/bpf/progs/bpf_qdisc_fifo.c b/tools/testing/selftests/bpf/progs/bpf_qdisc_fifo.c new file mode 100644 index 000000000000..705e7da325da --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_qdisc_fifo.c @@ -0,0 +1,117 @@ +#include +#include "bpf_experimental.h" +#include "bpf_qdisc_common.h" + +char _license[] SEC("license") = "GPL"; + +struct skb_node { + struct sk_buff __kptr * skb; + struct bpf_list_node node; +}; + +#define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8))) + +private(A) struct bpf_spin_lock q_fifo_lock; +private(A) struct bpf_list_head q_fifo __contains(skb_node, node); + +SEC("struct_ops/bpf_fifo_enqueue") +int BPF_PROG(bpf_fifo_enqueue, struct sk_buff *skb, struct Qdisc *sch, + struct bpf_sk_buff_ptr *to_free) +{ + struct skb_node *skbn; + u32 pkt_len; + + if (sch->q.qlen == sch->limit) + goto drop; + + skbn = bpf_obj_new(typeof(*skbn)); + if (!skbn) + goto drop; + + pkt_len = qdisc_pkt_len(skb); + + sch->q.qlen++; + skb = bpf_kptr_xchg(&skbn->skb, skb); + if (skb) + bpf_qdisc_skb_drop(skb, to_free); + + bpf_spin_lock(&q_fifo_lock); + bpf_list_push_back(&q_fifo, &skbn->node); + bpf_spin_unlock(&q_fifo_lock); + + sch->qstats.backlog += pkt_len; + return NET_XMIT_SUCCESS; +drop: + bpf_qdisc_skb_drop(skb, to_free); + return NET_XMIT_DROP; +} + +SEC("struct_ops/bpf_fifo_dequeue") +struct sk_buff *BPF_PROG(bpf_fifo_dequeue, struct Qdisc *sch) +{ + struct bpf_list_node *node; + struct sk_buff *skb = NULL; + struct skb_node *skbn; + + bpf_spin_lock(&q_fifo_lock); + node = bpf_list_pop_front(&q_fifo); + bpf_spin_unlock(&q_fifo_lock); + if (!node) + return NULL; + + skbn = container_of(node, struct skb_node, node); + skb = bpf_kptr_xchg(&skbn->skb, skb); + bpf_obj_drop(skbn); + if (!skb) + return NULL; + + sch->qstats.backlog -= qdisc_pkt_len(skb); + bpf_qdisc_bstats_update(sch, skb); + sch->q.qlen--; + + return skb; +} + +SEC("struct_ops/bpf_fifo_init") +int BPF_PROG(bpf_fifo_init, struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) +{ + sch->limit = 1000; + return 0; +} + +SEC("struct_ops/bpf_fifo_reset") +void BPF_PROG(bpf_fifo_reset, struct Qdisc *sch) +{ + struct bpf_list_node *node; + struct skb_node *skbn; + int i; + + bpf_for(i, 0, sch->q.qlen) { + struct sk_buff *skb = NULL; + + bpf_spin_lock(&q_fifo_lock); + node = bpf_list_pop_front(&q_fifo); + bpf_spin_unlock(&q_fifo_lock); + + if (!node) + break; + + skbn = container_of(node, struct skb_node, node); + skb = bpf_kptr_xchg(&skbn->skb, skb); + if (skb) + bpf_kfree_skb(skb); + bpf_obj_drop(skbn); + } + sch->q.qlen = 0; +} + +SEC(".struct_ops") +struct Qdisc_ops fifo = { + .enqueue = (void *)bpf_fifo_enqueue, + .dequeue = (void *)bpf_fifo_dequeue, + .init = (void *)bpf_fifo_init, + .reset = (void *)bpf_fifo_reset, + .id = "bpf_fifo", +}; + From patchwork Thu Mar 13 19:03:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015821 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08A651F4619; Thu, 13 Mar 2025 19:03:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892614; cv=none; b=GZ/asaAEA63Xf8A1DB+N23OchpNuWJRmomozb7fvTPnNCBmacQlNb3940dDkWvjNvw5G/0iTbuDtzHqpW6Qxt3h5fDkT+6b3YuQZDKqLBwkToR+ovzLdXlBfP8RmWpGMBP2nzqbBIIxQOu3L+NwnrQq6sa/yYBZA9K6/MKG3dJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892614; c=relaxed/simple; bh=l/EG2Hv2+qR3NhHzVmwDAf8x8ODiqMG1OgRk1D0eEXw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mv7azrZg6kcslIcr/COq8lUBqvBuHuiYTkqKZ7YzcA5f+30wa9Z1mUe8efApc7BmJvZCKdDpErGN0IRQjMhojcQdoM9bp6zv6HNLYQQnxJw7n+6OlQVIDc4vC3/hD+vgszSkMSxdYAyWn/7ulM7SSXTgnYuRSrRYkwvo3xVwhQA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OnHHGzGQ; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OnHHGzGQ" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-224191d92e4so28974955ad.3; Thu, 13 Mar 2025 12:03:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892611; x=1742497411; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=f4h19YQiBcyrtSA3sf0+MDRnNgbjNX1BgikaozoMEP4=; b=OnHHGzGQjw7ENOF2fFhoKRyGZr4OaWc0wBEUDW9DIjnXGE6bCwafmQ8i+t5SIlDtAM rrwNM7jSOkTiCN+DTdRZOOnZuhQIonm4D+996GDAz3sVxOWpztzYN675MATFMwNzPyDN mTIhhQy8V55do/rGopq47x9IVYM4ijgDpS+0GvN5IWpPqNMljgbPVH8Wqawkva7er5U0 hD0Je3KVdT6bVY1WO386HgjyXgZF6MIVMWzTt/jEgy9fC+ZUOf6ewEBroACTy1ZBbpom kWTdvV1jUkcqLOmluRi8xKBGFed03SYFCDyh/LJJYxQ288tHSB4cr+en9Erq3dUm0tQP 937Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892611; x=1742497411; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=f4h19YQiBcyrtSA3sf0+MDRnNgbjNX1BgikaozoMEP4=; b=tBLGI6aY8qJJDXdDKGJUtihgQuhY+x7pT8Rc6LpEs5xmiJ5CXSMrz62TV1fxhlojxU GD/K92gh4QpOJR1ImotGU/ZCMnyURTdbrpsYSN7RPftBEUhOJJIh0CCpiofOaLorKtDz HaafPwcrYxnCg4HCjgEj9OuCYvDWWG6M2CF0nB6pOB8qHFNwa7shJ/WqoYOdYfb1b8aP Njyvv0f4n0HZXYfdT61lqeEiu4vH3Th4BEOhtYgwuy+gRxmk3FUC2fIfLP0aAkSPiNa+ Nvwpkb1jkQs96w5SBKXQ6poTsYtGT3FKS1A/CzEilKHN+23qX3ydl2s1+pmjhXQTU6Bl P1zQ== X-Gm-Message-State: AOJu0YwT5WetYGKDnbZv6D1EQSg0p+oq5jSLnxiPbnRuHweqpsCeSOi3 HAr/K++ZgK+1Q8FUWjiMU76zOEUOBkayG63YpWYiof8YLP8dHvhylZ6ieR7GOmODRQ== X-Gm-Gg: ASbGncslG0H8C/r91ZFfB0OrUjiusngGXjiddofLxGNhiYe2zlgC3WNLbhMicD6ZXEr klF/HucgKbZ6SKtiqgDDK/AsmKqc0sqXiqT4y39qSSVykqtk/Rola3HK0Oj5pk+MTGpQB+qU9VY LP1LcVTDRnlD0TjiN1eHPvlPHgK6BUu52h8lTJWQJwYZStStMGoObbMOz4B4yLTdyEjISNEh8a7 x6usSd7GUJ88luwcowSZMozLmFMV6BQzcuhq1m33ER9BNLmDAl7NdiqwyR/C3XDvpaBKwJQUAXe XolirYBjuBDOnUrb2uO9vf/C46rVZM4sqaLGYmbh8dmdE+/sEPcKHkC1XdFN0eZuafXg9kvZLm8 iE6GUonyIIezyflJPpPrukvnx5KHPAg== X-Google-Smtp-Source: AGHT+IHLfx1syiPekBmd1jECOoul1TU1rVonnrv48dnpb85B8hAwdAduAK9U3S9kOr+M2SagOGiRJg== X-Received: by 2002:a17:902:ce89:b0:21f:4c8b:c514 with SMTP id d9443c01a7336-225dd8d720emr7622005ad.45.1741892611078; Thu, 13 Mar 2025 12:03:31 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:30 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 12/13] selftests/bpf: Add a bpf fq qdisc to selftest Date: Thu, 13 Mar 2025 12:03:06 -0700 Message-ID: <20250313190309.2545711-13-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Amery Hung This test implements a more sophisticated qdisc using bpf. The bpf fair- queueing (fq) qdisc gives each flow an equal chance to transmit data. It also respects the timestamp of skb for rate limiting. Signed-off-by: Amery Hung --- .../selftests/bpf/prog_tests/bpf_qdisc.c | 24 + .../selftests/bpf/progs/bpf_qdisc_fq.c | 718 ++++++++++++++++++ 2 files changed, 742 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/bpf_qdisc_fq.c diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c index f2efc69af348..7e8e3170e6b6 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c @@ -4,6 +4,7 @@ #include "network_helpers.h" #include "bpf_qdisc_fifo.skel.h" +#include "bpf_qdisc_fq.skel.h" #define LO_IFINDEX 1 @@ -64,6 +65,27 @@ static void test_fifo(void) bpf_qdisc_fifo__destroy(fifo_skel); } +static void test_fq(void) +{ + struct bpf_qdisc_fq *fq_skel; + struct bpf_link *link; + + fq_skel = bpf_qdisc_fq__open_and_load(); + if (!ASSERT_OK_PTR(fq_skel, "bpf_qdisc_fq__open_and_load")) + return; + + link = bpf_map__attach_struct_ops(fq_skel->maps.fq); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) { + bpf_qdisc_fq__destroy(fq_skel); + return; + } + + do_test("bpf_fq"); + + bpf_link__destroy(link); + bpf_qdisc_fq__destroy(fq_skel); +} + void test_bpf_qdisc(void) { struct netns_obj *netns; @@ -74,6 +96,8 @@ void test_bpf_qdisc(void) if (test__start_subtest("fifo")) test_fifo(); + if (test__start_subtest("fq")) + test_fq(); netns_free(netns); } diff --git a/tools/testing/selftests/bpf/progs/bpf_qdisc_fq.c b/tools/testing/selftests/bpf/progs/bpf_qdisc_fq.c new file mode 100644 index 000000000000..36ef53b10d98 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_qdisc_fq.c @@ -0,0 +1,718 @@ +#include +#include +#include +#include "bpf_experimental.h" +#include "bpf_qdisc_common.h" + +char _license[] SEC("license") = "GPL"; + +#define NSEC_PER_USEC 1000L +#define NSEC_PER_SEC 1000000000L + +#define NUM_QUEUE (1 << 20) + +struct fq_bpf_data { + u32 quantum; + u32 initial_quantum; + u32 flow_refill_delay; + u32 flow_plimit; + u64 horizon; + u32 orphan_mask; + u32 timer_slack; + u64 time_next_delayed_flow; + u64 unthrottle_latency_ns; + u8 horizon_drop; + u32 new_flow_cnt; + u32 old_flow_cnt; + u64 ktime_cache; +}; + +enum { + CLS_RET_PRIO = 0, + CLS_RET_NONPRIO = 1, + CLS_RET_ERR = 2, +}; + +struct skb_node { + u64 tstamp; + struct sk_buff __kptr * skb; + struct bpf_rb_node node; +}; + +struct fq_flow_node { + int credit; + u32 qlen; + u64 age; + u64 time_next_packet; + struct bpf_list_node list_node; + struct bpf_rb_node rb_node; + struct bpf_rb_root queue __contains(skb_node, node); + struct bpf_spin_lock lock; + struct bpf_refcount refcount; +}; + +struct dequeue_nonprio_ctx { + bool stop_iter; + u64 expire; + u64 now; +}; + +struct remove_flows_ctx { + bool gc_only; + u32 reset_cnt; + u32 reset_max; +}; + +struct unset_throttled_flows_ctx { + bool unset_all; + u64 now; +}; + +struct fq_stashed_flow { + struct fq_flow_node __kptr * flow; +}; + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u64); + __type(value, struct fq_stashed_flow); + __uint(max_entries, NUM_QUEUE); +} fq_nonprio_flows SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, __u64); + __type(value, struct fq_stashed_flow); + __uint(max_entries, 1); +} fq_prio_flows SEC(".maps"); + +#define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8))) + +private(A) struct bpf_spin_lock fq_delayed_lock; +private(A) struct bpf_rb_root fq_delayed __contains(fq_flow_node, rb_node); + +private(B) struct bpf_spin_lock fq_new_flows_lock; +private(B) struct bpf_list_head fq_new_flows __contains(fq_flow_node, list_node); + +private(C) struct bpf_spin_lock fq_old_flows_lock; +private(C) struct bpf_list_head fq_old_flows __contains(fq_flow_node, list_node); + +private(D) struct fq_bpf_data q; + +/* Wrapper for bpf_kptr_xchg that expects NULL dst */ +static void bpf_kptr_xchg_back(void *map_val, void *ptr) +{ + void *ret; + + ret = bpf_kptr_xchg(map_val, ptr); + if (ret) + bpf_obj_drop(ret); +} + +static bool skbn_tstamp_less(struct bpf_rb_node *a, const struct bpf_rb_node *b) +{ + struct skb_node *skbn_a; + struct skb_node *skbn_b; + + skbn_a = container_of(a, struct skb_node, node); + skbn_b = container_of(b, struct skb_node, node); + + return skbn_a->tstamp < skbn_b->tstamp; +} + +static bool fn_time_next_packet_less(struct bpf_rb_node *a, const struct bpf_rb_node *b) +{ + struct fq_flow_node *flow_a; + struct fq_flow_node *flow_b; + + flow_a = container_of(a, struct fq_flow_node, rb_node); + flow_b = container_of(b, struct fq_flow_node, rb_node); + + return flow_a->time_next_packet < flow_b->time_next_packet; +} + +static void +fq_flows_add_head(struct bpf_list_head *head, struct bpf_spin_lock *lock, + struct fq_flow_node *flow, u32 *flow_cnt) +{ + bpf_spin_lock(lock); + bpf_list_push_front(head, &flow->list_node); + bpf_spin_unlock(lock); + *flow_cnt += 1; +} + +static void +fq_flows_add_tail(struct bpf_list_head *head, struct bpf_spin_lock *lock, + struct fq_flow_node *flow, u32 *flow_cnt) +{ + bpf_spin_lock(lock); + bpf_list_push_back(head, &flow->list_node); + bpf_spin_unlock(lock); + *flow_cnt += 1; +} + +static void +fq_flows_remove_front(struct bpf_list_head *head, struct bpf_spin_lock *lock, + struct bpf_list_node **node, u32 *flow_cnt) +{ + bpf_spin_lock(lock); + *node = bpf_list_pop_front(head); + bpf_spin_unlock(lock); + *flow_cnt -= 1; +} + +static bool +fq_flows_is_empty(struct bpf_list_head *head, struct bpf_spin_lock *lock) +{ + struct bpf_list_node *node; + + bpf_spin_lock(lock); + node = bpf_list_pop_front(head); + if (node) { + bpf_list_push_front(head, node); + bpf_spin_unlock(lock); + return false; + } + bpf_spin_unlock(lock); + + return true; +} + +/* flow->age is used to denote the state of the flow (not-detached, detached, throttled) + * as well as the timestamp when the flow is detached. + * + * 0: not-detached + * 1 - (~0ULL-1): detached + * ~0ULL: throttled + */ +static void fq_flow_set_detached(struct fq_flow_node *flow) +{ + flow->age = bpf_jiffies64(); +} + +static bool fq_flow_is_detached(struct fq_flow_node *flow) +{ + return flow->age != 0 && flow->age != ~0ULL; +} + +static bool sk_listener(struct sock *sk) +{ + return (1 << sk->__sk_common.skc_state) & (TCPF_LISTEN | TCPF_NEW_SYN_RECV); +} + +static void fq_gc(void); + +static int fq_new_flow(void *flow_map, struct fq_stashed_flow **sflow, u64 hash) +{ + struct fq_stashed_flow tmp = {}; + struct fq_flow_node *flow; + int ret; + + flow = bpf_obj_new(typeof(*flow)); + if (!flow) + return -ENOMEM; + + flow->credit = q.initial_quantum, + flow->qlen = 0, + flow->age = 1, + flow->time_next_packet = 0, + + ret = bpf_map_update_elem(flow_map, &hash, &tmp, 0); + if (ret == -ENOMEM || ret == -E2BIG) { + fq_gc(); + bpf_map_update_elem(&fq_nonprio_flows, &hash, &tmp, 0); + } + + *sflow = bpf_map_lookup_elem(flow_map, &hash); + if (!*sflow) { + bpf_obj_drop(flow); + return -ENOMEM; + } + + bpf_kptr_xchg_back(&(*sflow)->flow, flow); + return 0; +} + +static int +fq_classify(struct sk_buff *skb, struct fq_stashed_flow **sflow) +{ + struct sock *sk = skb->sk; + int ret = CLS_RET_NONPRIO; + u64 hash = 0; + + if ((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL) { + *sflow = bpf_map_lookup_elem(&fq_prio_flows, &hash); + ret = CLS_RET_PRIO; + } else { + if (!sk || sk_listener(sk)) { + hash = bpf_skb_get_hash(skb) & q.orphan_mask; + /* Avoid collision with an existing flow hash, which + * only uses the lower 32 bits of hash, by setting the + * upper half of hash to 1. + */ + hash |= (1ULL << 32); + } else if (sk->__sk_common.skc_state == TCP_CLOSE) { + hash = bpf_skb_get_hash(skb) & q.orphan_mask; + hash |= (1ULL << 32); + } else { + hash = sk->__sk_common.skc_hash; + } + *sflow = bpf_map_lookup_elem(&fq_nonprio_flows, &hash); + } + + if (!*sflow) + ret = fq_new_flow(&fq_nonprio_flows, sflow, hash) < 0 ? + CLS_RET_ERR : CLS_RET_NONPRIO; + + return ret; +} + +static bool fq_packet_beyond_horizon(struct sk_buff *skb) +{ + return (s64)skb->tstamp > (s64)(q.ktime_cache + q.horizon); +} + +SEC("struct_ops/bpf_fq_enqueue") +int BPF_PROG(bpf_fq_enqueue, struct sk_buff *skb, struct Qdisc *sch, + struct bpf_sk_buff_ptr *to_free) +{ + struct fq_flow_node *flow = NULL, *flow_copy; + struct fq_stashed_flow *sflow; + u64 time_to_send, jiffies; + struct skb_node *skbn; + int ret; + + if (sch->q.qlen >= sch->limit) + goto drop; + + if (!skb->tstamp) { + time_to_send = q.ktime_cache = bpf_ktime_get_ns(); + } else { + if (fq_packet_beyond_horizon(skb)) { + q.ktime_cache = bpf_ktime_get_ns(); + if (fq_packet_beyond_horizon(skb)) { + if (q.horizon_drop) + goto drop; + + skb->tstamp = q.ktime_cache + q.horizon; + } + } + time_to_send = skb->tstamp; + } + + ret = fq_classify(skb, &sflow); + if (ret == CLS_RET_ERR) + goto drop; + + flow = bpf_kptr_xchg(&sflow->flow, flow); + if (!flow) + goto drop; + + if (ret == CLS_RET_NONPRIO) { + if (flow->qlen >= q.flow_plimit) { + bpf_kptr_xchg_back(&sflow->flow, flow); + goto drop; + } + + if (fq_flow_is_detached(flow)) { + flow_copy = bpf_refcount_acquire(flow); + + jiffies = bpf_jiffies64(); + if ((s64)(jiffies - (flow_copy->age + q.flow_refill_delay)) > 0) { + if (flow_copy->credit < q.quantum) + flow_copy->credit = q.quantum; + } + flow_copy->age = 0; + fq_flows_add_tail(&fq_new_flows, &fq_new_flows_lock, flow_copy, + &q.new_flow_cnt); + } + } + + skbn = bpf_obj_new(typeof(*skbn)); + if (!skbn) { + bpf_kptr_xchg_back(&sflow->flow, flow); + goto drop; + } + + skbn->tstamp = skb->tstamp = time_to_send; + + sch->qstats.backlog += qdisc_pkt_len(skb); + + skb = bpf_kptr_xchg(&skbn->skb, skb); + if (skb) + bpf_qdisc_skb_drop(skb, to_free); + + bpf_spin_lock(&flow->lock); + bpf_rbtree_add(&flow->queue, &skbn->node, skbn_tstamp_less); + bpf_spin_unlock(&flow->lock); + + flow->qlen++; + bpf_kptr_xchg_back(&sflow->flow, flow); + + sch->q.qlen++; + return NET_XMIT_SUCCESS; + +drop: + bpf_qdisc_skb_drop(skb, to_free); + sch->qstats.drops++; + return NET_XMIT_DROP; +} + +static int fq_unset_throttled_flows(u32 index, struct unset_throttled_flows_ctx *ctx) +{ + struct bpf_rb_node *node = NULL; + struct fq_flow_node *flow; + + bpf_spin_lock(&fq_delayed_lock); + + node = bpf_rbtree_first(&fq_delayed); + if (!node) { + bpf_spin_unlock(&fq_delayed_lock); + return 1; + } + + flow = container_of(node, struct fq_flow_node, rb_node); + if (!ctx->unset_all && flow->time_next_packet > ctx->now) { + q.time_next_delayed_flow = flow->time_next_packet; + bpf_spin_unlock(&fq_delayed_lock); + return 1; + } + + node = bpf_rbtree_remove(&fq_delayed, &flow->rb_node); + + bpf_spin_unlock(&fq_delayed_lock); + + if (!node) + return 1; + + flow = container_of(node, struct fq_flow_node, rb_node); + flow->age = 0; + fq_flows_add_tail(&fq_old_flows, &fq_old_flows_lock, flow, &q.old_flow_cnt); + + return 0; +} + +static void fq_flow_set_throttled(struct fq_flow_node *flow) +{ + flow->age = ~0ULL; + + if (q.time_next_delayed_flow > flow->time_next_packet) + q.time_next_delayed_flow = flow->time_next_packet; + + bpf_spin_lock(&fq_delayed_lock); + bpf_rbtree_add(&fq_delayed, &flow->rb_node, fn_time_next_packet_less); + bpf_spin_unlock(&fq_delayed_lock); +} + +static void fq_check_throttled(u64 now) +{ + struct unset_throttled_flows_ctx ctx = { + .unset_all = false, + .now = now, + }; + unsigned long sample; + + if (q.time_next_delayed_flow > now) + return; + + sample = (unsigned long)(now - q.time_next_delayed_flow); + q.unthrottle_latency_ns -= q.unthrottle_latency_ns >> 3; + q.unthrottle_latency_ns += sample >> 3; + + q.time_next_delayed_flow = ~0ULL; + bpf_loop(NUM_QUEUE, fq_unset_throttled_flows, &ctx, 0); +} + +static struct sk_buff* +fq_dequeue_nonprio_flows(u32 index, struct dequeue_nonprio_ctx *ctx) +{ + u64 time_next_packet, time_to_send; + struct bpf_rb_node *rb_node; + struct sk_buff *skb = NULL; + struct bpf_list_head *head; + struct bpf_list_node *node; + struct bpf_spin_lock *lock; + struct fq_flow_node *flow; + struct skb_node *skbn; + bool is_empty; + u32 *cnt; + + if (q.new_flow_cnt) { + head = &fq_new_flows; + lock = &fq_new_flows_lock; + cnt = &q.new_flow_cnt; + } else if (q.old_flow_cnt) { + head = &fq_old_flows; + lock = &fq_old_flows_lock; + cnt = &q.old_flow_cnt; + } else { + if (q.time_next_delayed_flow != ~0ULL) + ctx->expire = q.time_next_delayed_flow; + goto break_loop; + } + + fq_flows_remove_front(head, lock, &node, cnt); + if (!node) + goto break_loop; + + flow = container_of(node, struct fq_flow_node, list_node); + if (flow->credit <= 0) { + flow->credit += q.quantum; + fq_flows_add_tail(&fq_old_flows, &fq_old_flows_lock, flow, &q.old_flow_cnt); + return NULL; + } + + bpf_spin_lock(&flow->lock); + rb_node = bpf_rbtree_first(&flow->queue); + if (!rb_node) { + bpf_spin_unlock(&flow->lock); + is_empty = fq_flows_is_empty(&fq_old_flows, &fq_old_flows_lock); + if (head == &fq_new_flows && !is_empty) { + fq_flows_add_tail(&fq_old_flows, &fq_old_flows_lock, flow, &q.old_flow_cnt); + } else { + fq_flow_set_detached(flow); + bpf_obj_drop(flow); + } + return NULL; + } + + skbn = container_of(rb_node, struct skb_node, node); + time_to_send = skbn->tstamp; + + time_next_packet = (time_to_send > flow->time_next_packet) ? + time_to_send : flow->time_next_packet; + if (ctx->now < time_next_packet) { + bpf_spin_unlock(&flow->lock); + flow->time_next_packet = time_next_packet; + fq_flow_set_throttled(flow); + return NULL; + } + + rb_node = bpf_rbtree_remove(&flow->queue, rb_node); + bpf_spin_unlock(&flow->lock); + + if (!rb_node) + goto add_flow_and_break; + + skbn = container_of(rb_node, struct skb_node, node); + skb = bpf_kptr_xchg(&skbn->skb, skb); + bpf_obj_drop(skbn); + + if (!skb) + goto add_flow_and_break; + + flow->credit -= qdisc_skb_cb(skb)->pkt_len; + flow->qlen--; + +add_flow_and_break: + fq_flows_add_head(head, lock, flow, cnt); + +break_loop: + ctx->stop_iter = true; + return skb; +} + +static struct sk_buff *fq_dequeue_prio(void) +{ + struct fq_flow_node *flow = NULL; + struct fq_stashed_flow *sflow; + struct bpf_rb_node *rb_node; + struct sk_buff *skb = NULL; + struct skb_node *skbn; + u64 hash = 0; + + sflow = bpf_map_lookup_elem(&fq_prio_flows, &hash); + if (!sflow) + return NULL; + + flow = bpf_kptr_xchg(&sflow->flow, flow); + if (!flow) + return NULL; + + bpf_spin_lock(&flow->lock); + rb_node = bpf_rbtree_first(&flow->queue); + if (!rb_node) { + bpf_spin_unlock(&flow->lock); + goto out; + } + + skbn = container_of(rb_node, struct skb_node, node); + rb_node = bpf_rbtree_remove(&flow->queue, &skbn->node); + bpf_spin_unlock(&flow->lock); + + if (!rb_node) + goto out; + + skbn = container_of(rb_node, struct skb_node, node); + skb = bpf_kptr_xchg(&skbn->skb, skb); + bpf_obj_drop(skbn); + +out: + bpf_kptr_xchg_back(&sflow->flow, flow); + + return skb; +} + +SEC("struct_ops/bpf_fq_dequeue") +struct sk_buff *BPF_PROG(bpf_fq_dequeue, struct Qdisc *sch) +{ + struct dequeue_nonprio_ctx cb_ctx = {}; + struct sk_buff *skb = NULL; + int i; + + if (!sch->q.qlen) + goto out; + + skb = fq_dequeue_prio(); + if (skb) + goto dequeue; + + q.ktime_cache = cb_ctx.now = bpf_ktime_get_ns(); + fq_check_throttled(q.ktime_cache); + bpf_for(i, 0, sch->limit) { + skb = fq_dequeue_nonprio_flows(i, &cb_ctx); + if (cb_ctx.stop_iter) + break; + }; + + if (skb) { +dequeue: + sch->q.qlen--; + sch->qstats.backlog -= qdisc_pkt_len(skb); + bpf_qdisc_bstats_update(sch, skb); + return skb; + } + + if (cb_ctx.expire) + bpf_qdisc_watchdog_schedule(sch, cb_ctx.expire, q.timer_slack); +out: + return NULL; +} + +static int fq_remove_flows_in_list(u32 index, void *ctx) +{ + struct bpf_list_node *node; + struct fq_flow_node *flow; + + bpf_spin_lock(&fq_new_flows_lock); + node = bpf_list_pop_front(&fq_new_flows); + bpf_spin_unlock(&fq_new_flows_lock); + if (!node) { + bpf_spin_lock(&fq_old_flows_lock); + node = bpf_list_pop_front(&fq_old_flows); + bpf_spin_unlock(&fq_old_flows_lock); + if (!node) + return 1; + } + + flow = container_of(node, struct fq_flow_node, list_node); + bpf_obj_drop(flow); + + return 0; +} + +extern unsigned CONFIG_HZ __kconfig; + +/* limit number of collected flows per round */ +#define FQ_GC_MAX 8 +#define FQ_GC_AGE (3*CONFIG_HZ) + +static bool fq_gc_candidate(struct fq_flow_node *flow) +{ + u64 jiffies = bpf_jiffies64(); + + return fq_flow_is_detached(flow) && + ((s64)(jiffies - (flow->age + FQ_GC_AGE)) > 0); +} + +static int +fq_remove_flows(struct bpf_map *flow_map, u64 *hash, + struct fq_stashed_flow *sflow, struct remove_flows_ctx *ctx) +{ + if (sflow->flow && + (!ctx->gc_only || fq_gc_candidate(sflow->flow))) { + bpf_map_delete_elem(flow_map, hash); + ctx->reset_cnt++; + } + + return ctx->reset_cnt < ctx->reset_max ? 0 : 1; +} + +static void fq_gc(void) +{ + struct remove_flows_ctx cb_ctx = { + .gc_only = true, + .reset_cnt = 0, + .reset_max = FQ_GC_MAX, + }; + + bpf_for_each_map_elem(&fq_nonprio_flows, fq_remove_flows, &cb_ctx, 0); +} + +SEC("struct_ops/bpf_fq_reset") +void BPF_PROG(bpf_fq_reset, struct Qdisc *sch) +{ + struct unset_throttled_flows_ctx utf_ctx = { + .unset_all = true, + }; + struct remove_flows_ctx rf_ctx = { + .gc_only = false, + .reset_cnt = 0, + .reset_max = NUM_QUEUE, + }; + struct fq_stashed_flow *sflow; + u64 hash = 0; + + sch->q.qlen = 0; + sch->qstats.backlog = 0; + + bpf_for_each_map_elem(&fq_nonprio_flows, fq_remove_flows, &rf_ctx, 0); + + rf_ctx.reset_cnt = 0; + bpf_for_each_map_elem(&fq_prio_flows, fq_remove_flows, &rf_ctx, 0); + fq_new_flow(&fq_prio_flows, &sflow, hash); + + bpf_loop(NUM_QUEUE, fq_remove_flows_in_list, NULL, 0); + q.new_flow_cnt = 0; + q.old_flow_cnt = 0; + + bpf_loop(NUM_QUEUE, fq_unset_throttled_flows, &utf_ctx, 0); +} + +SEC("struct_ops/bpf_fq_init") +int BPF_PROG(bpf_fq_init, struct Qdisc *sch, struct nlattr *opt, + struct netlink_ext_ack *extack) +{ + struct net_device *dev = sch->dev_queue->dev; + u32 psched_mtu = dev->mtu + dev->hard_header_len; + struct fq_stashed_flow *sflow; + u64 hash = 0; + + if (fq_new_flow(&fq_prio_flows, &sflow, hash) < 0) + return -ENOMEM; + + sch->limit = 10000; + q.initial_quantum = 10 * psched_mtu; + q.quantum = 2 * psched_mtu; + q.flow_refill_delay = 40; + q.flow_plimit = 100; + q.horizon = 10ULL * NSEC_PER_SEC; + q.horizon_drop = 1; + q.orphan_mask = 1024 - 1; + q.timer_slack = 10 * NSEC_PER_USEC; + q.time_next_delayed_flow = ~0ULL; + q.unthrottle_latency_ns = 0ULL; + q.new_flow_cnt = 0; + q.old_flow_cnt = 0; + + return 0; +} + +SEC(".struct_ops") +struct Qdisc_ops fq = { + .enqueue = (void *)bpf_fq_enqueue, + .dequeue = (void *)bpf_fq_dequeue, + .reset = (void *)bpf_fq_reset, + .init = (void *)bpf_fq_init, + .id = "bpf_fq", +}; From patchwork Thu Mar 13 19:03:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amery Hung X-Patchwork-Id: 14015822 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-pl1-f180.google.com (mail-pl1-f180.google.com [209.85.214.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2ED261F462C; Thu, 13 Mar 2025 19:03:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892614; cv=none; b=CU9khicWmD+gsYD2u5KczBUSEDx2Hc/S4z5zX7yAVcDvFhigClgDkfBzPxh9BpTDSYCiGwv2OeZQ0zBwuHg0T5y5P6CJdipUBby/JCImYZVPUut8+H8SPbVSVY90S+/bSCpo3v1pIxqrlyAdsHOLgRdH07qp23DUd7lQsXuWFsk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741892614; c=relaxed/simple; bh=sVVkbk0Gn1THhmgFQQYZXWJ516ceqWV7SjuSKbWsCVg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J0lPNYwN0b1T2vVRjNlALrx0jhOBRVOz/wUYOY6oA76ejfewFNffPx7Q4oyaf+GSSLfktD2WKlp+0SkPXRHfjbnn0mEfxZ8X74Lh+vJFENVrWBWWe8PZB6Hye2VYhpA2v+7/BNFCBCFIP9hmtRpadHWuUgKji14YhUiWuJkZbk8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=eydlmvif; arc=none smtp.client-ip=209.85.214.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eydlmvif" Received: by mail-pl1-f180.google.com with SMTP id d9443c01a7336-2239c066347so29308425ad.2; Thu, 13 Mar 2025 12:03:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741892612; x=1742497412; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tCot4AmKUdSjbCpz+84y1dF8CcLEygWZ6VcGHROBKi0=; b=eydlmvifiu4V47qAOr84ZA8ekI8XGsU22C7eoYiotnJDh8b0Z2rj3Fx3mafBfbP/Uy GnUNM2qG6bXePN8lcbMtQLH+tFeQT3ZgW9kVzst2/Va6Y/nP3NjA985IUNrIrcldqROx iofDyc5EAcizvEh/268t5gDHEnQftnPSDapNwr3oNZ5O+vF56UcxoqKcXQm2fAGWREsI za2YPGW55InbWFsKWd5fEPVMWvNb+f3P1Fww1LuUeYnoshEKlAV1PL95z0fFYnPFVvLW jPeg7uOOBip2xK14u1taTDyVpEF0eZR6+aG1Bp5g5B5MDoz7q1nmfKN4jBcpNCBh4+pd UTig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741892612; x=1742497412; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tCot4AmKUdSjbCpz+84y1dF8CcLEygWZ6VcGHROBKi0=; b=b5Ayl9QHg7EJVVkIv1KWP0wKBHovWZ5FHtOLSgm09CYMSOMGw9ozJoGuULts//8KyI 1bkJQYLlcgIRkOiARq3yD2XQNsVYtummA1msyYm96jswDXKL2fa4609HpnNxykJcbG6N EsjoTJv5bsqCUZLXbzoZnW/CyBHgyGC118ZQ1u378M8xicj7XcxeoBWycAVbX2n49ySu tEtEov9LBkJj09FGKvv8GQ4gVMxmedm3AbQlMPXCKZZ9Y7ExADaAxxahPpbZqKGFgd+j POr5OThlA71P4amJhPe7za4BrjEQOdSawHX16avMzFw0U18SbyYiR69rFhGT1zdRB4LR gtSg== X-Gm-Message-State: AOJu0YzRy/qf3HhRVixLSdDhJGX/Sq9tqMQ5IRaDwfK4t9E7HbRTpJ3i QzdXQjLxNRaIAx2Ne3rpsVIj9DLhPEMAmUQZCMN0H6HYBSSXcSRUcrLqeyaMuXKltQ== X-Gm-Gg: ASbGncs+SlHdA4zUOW0MbDIhYocfNQ/fPEWPyBw0bEpTKPwQDlqbWiVApi8flDL5eXY 71qhlbHhUIQbBrUrLDW+snVyNnOrjIN273UUAx8aehUcsbQDV0PKNoOGilpuMIS4edJEbJk9jQs gRkhCXaXGHHBRKjhO3kobyK7qevXmMiXP//2yE7oZDGcU3ze5iE17OcJCgcyPmSLifQSZe5bKUh WxBuJN9e4K0HTvvILu9HbJwFMqe1M1ptPkap3pQBvIP4ABwTMO0Owf6tSAEiS0urD8PFocagamX 2wbcaJGBMICxkTsoL1TpGNzUB0pIjaV+dGwifMuiPQNntJjryiBbkKZNJOVHZ3KuXl60uzUj548 a60WgMHHuDVbTeE19t2M= X-Google-Smtp-Source: AGHT+IFcgckZIHb7EgaqKgDoLhpaDOmWYBrHtekFHUNMF3R+5I8Lmmus5FfGtN8IseJYr0qbpesiGQ== X-Received: by 2002:a05:6a00:c83:b0:736:34a2:8a20 with SMTP id d2e1a72fcca58-7371f19f4e0mr853476b3a.21.1741892612098; Thu, 13 Mar 2025 12:03:32 -0700 (PDT) Received: from localhost.localdomain (c-76-146-13-146.hsd1.wa.comcast.net. [76.146.13.146]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-af56e9e2f45sm1652505a12.29.2025.03.13.12.03.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Mar 2025 12:03:31 -0700 (PDT) From: Amery Hung To: netdev@vger.kernel.org Cc: bpf@vger.kernel.org, daniel@iogearbox.net, andrii@kernel.org, alexei.starovoitov@gmail.com, martin.lau@kernel.org, kuba@kernel.org, edumazet@google.com, xiyou.wangcong@gmail.com, jhs@mojatatu.com, sinquersw@gmail.com, toke@redhat.com, jiri@resnulli.us, stfomichev@gmail.com, ekarani.silvestre@ccc.ufcg.edu.br, yangpeihao@sjtu.edu.cn, yepeilin.cs@gmail.com, ameryhung@gmail.com, kernel-team@meta.com Subject: [PATCH bpf-next v5 13/13] selftests/bpf: Test attaching bpf qdisc to mq and non root Date: Thu, 13 Mar 2025 12:03:07 -0700 Message-ID: <20250313190309.2545711-14-ameryhung@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250313190309.2545711-1-ameryhung@gmail.com> References: <20250313190309.2545711-1-ameryhung@gmail.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Until we are certain that existing classful qdiscs work with bpf qdisc, make sure we don't allow attaching a bpf qdisc to non root. Meanwhile, attaching to mq is allowed. Signed-off-by: Amery Hung --- tools/testing/selftests/bpf/config | 1 + .../selftests/bpf/prog_tests/bpf_qdisc.c | 75 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config index 6b0cab55bd2d..3201a962b3dc 100644 --- a/tools/testing/selftests/bpf/config +++ b/tools/testing/selftests/bpf/config @@ -74,6 +74,7 @@ CONFIG_NET_MPLS_GSO=y CONFIG_NET_SCH_BPF=y CONFIG_NET_SCH_FQ=y CONFIG_NET_SCH_INGRESS=y +CONFIG_NET_SCH_HTB=y CONFIG_NET_SCHED=y CONFIG_NETDEVSIM=y CONFIG_NETFILTER=y diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c index 7e8e3170e6b6..5d4fa5ad40e1 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_qdisc.c @@ -86,6 +86,77 @@ static void test_fq(void) bpf_qdisc_fq__destroy(fq_skel); } +static void test_qdisc_attach_to_mq(void) +{ + DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, + .attach_point = BPF_TC_QDISC, + .parent = TC_H_MAKE(1 << 16, 1), + .handle = 0x11 << 16, + .qdisc = "bpf_fifo"); + struct bpf_qdisc_fifo *fifo_skel; + struct bpf_link *link; + int err; + + fifo_skel = bpf_qdisc_fifo__open_and_load(); + if (!ASSERT_OK_PTR(fifo_skel, "bpf_qdisc_fifo__open_and_load")) + return; + + link = bpf_map__attach_struct_ops(fifo_skel->maps.fifo); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) { + bpf_qdisc_fifo__destroy(fifo_skel); + return; + } + + SYS(out, "ip link add veth0 type veth peer veth1"); + hook.ifindex = if_nametoindex("veth0"); + SYS(out, "tc qdisc add dev veth0 root handle 1: mq"); + + err = bpf_tc_hook_create(&hook); + ASSERT_OK(err, "attach qdisc"); + + bpf_tc_hook_destroy(&hook); + + SYS(out, "tc qdisc delete dev veth0 root mq"); +out: + bpf_link__destroy(link); + bpf_qdisc_fifo__destroy(fifo_skel); +} + +static void test_qdisc_attach_to_non_root(void) +{ + DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = LO_IFINDEX, + .attach_point = BPF_TC_QDISC, + .parent = TC_H_MAKE(1 << 16, 1), + .handle = 0x11 << 16, + .qdisc = "bpf_fifo"); + struct bpf_qdisc_fifo *fifo_skel; + struct bpf_link *link; + int err; + + fifo_skel = bpf_qdisc_fifo__open_and_load(); + if (!ASSERT_OK_PTR(fifo_skel, "bpf_qdisc_fifo__open_and_load")) + return; + + link = bpf_map__attach_struct_ops(fifo_skel->maps.fifo); + if (!ASSERT_OK_PTR(link, "bpf_map__attach_struct_ops")) { + bpf_qdisc_fifo__destroy(fifo_skel); + return; + } + + SYS(out, "tc qdisc add dev lo root handle 1: htb"); + SYS(out_del_htb, "tc class add dev lo parent 1: classid 1:1 htb rate 75Kbit"); + + err = bpf_tc_hook_create(&hook); + if (!ASSERT_ERR(err, "attach qdisc")) + bpf_tc_hook_destroy(&hook); + +out_del_htb: + SYS(out, "tc qdisc delete dev lo root htb"); +out: + bpf_link__destroy(link); + bpf_qdisc_fifo__destroy(fifo_skel); +} + void test_bpf_qdisc(void) { struct netns_obj *netns; @@ -98,6 +169,10 @@ void test_bpf_qdisc(void) test_fifo(); if (test__start_subtest("fq")) test_fq(); + if (test__start_subtest("attach to mq")) + test_qdisc_attach_to_mq(); + if (test__start_subtest("attach to non root")) + test_qdisc_attach_to_non_root(); netns_free(netns); }