diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2be6dfd68df9..5e8df7bda6c4 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2157,6 +2157,7 @@ extern const struct bpf_func_proto bpf_btf_find_by_name_kind_proto;
extern const struct bpf_func_proto bpf_sk_setsockopt_proto;
extern const struct bpf_func_proto bpf_sk_getsockopt_proto;
extern const struct bpf_func_proto bpf_kallsyms_lookup_name_proto;
+extern const struct bpf_func_proto bpf_strncmp_proto;
const struct bpf_func_proto *tracing_prog_func_proto(
enum bpf_func_id func_id, const struct bpf_prog *prog);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index ba5af15e25f5..899274d3906e 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -4938,6 +4938,16 @@ union bpf_attr {
* **-ENOENT** if symbol is not found.
*
* **-EPERM** if caller does not have permission to obtain kernel address.
+ *
+ * long bpf_strncmp(const char *s1, const char *s2, u32 s2_sz)
+ * Description
+ * Do strncmp() between **s1** and **s2**. **s1** must be a
+ * read-only string. **s2_sz** is the maximum storage size of
+ * **s2**.
+ * Return
+ * Return an integer less than, equal to, or greater than zero
+ * if the first **s2_sz** bytes of **s2** is found to be
+ * less than, to match, or be greater than **s1**.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \@@ -5120,6 +5130,7 @@ union bpf_attr {
FN(trace_vprintk), \
FN(skc_to_unix_sock), \
FN(kallsyms_lookup_name), \
+ FN(strncmp), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helperdiff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 1ffd469c217f..e73ebd8e2623 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -565,6 +565,20 @@ const struct bpf_func_proto bpf_strtoul_proto = {
};
#endif
+BPF_CALL_3(bpf_strncmp, const char *, s1, const char *, s2, size_t, s2_sz)
+{
+ return strncmp(s1, s2, s2_sz);
+}
+
+const struct bpf_func_proto bpf_strncmp_proto = {
+ .func = bpf_strncmp,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_CONST_STR,
+ .arg2_type = ARG_PTR_TO_MEM,
+ .arg3_type = ARG_CONST_SIZE,
+};
+
BPF_CALL_4(bpf_get_ns_current_pid_tgid, u64, dev, u64, ino,
struct bpf_pidns_info *, nsdata, u32, size)
{diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 7396488793ff..37d2a52ddcb4 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1210,6 +1210,8 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
return &bpf_get_branch_snapshot_proto;
case BPF_FUNC_trace_vprintk:
return bpf_get_trace_vprintk_proto();
+ case BPF_FUNC_strncmp:
+ return &bpf_strncmp_proto;
default:
return bpf_base_func_proto(func_id);
}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index ba5af15e25f5..899274d3906e 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -4938,6 +4938,16 @@ union bpf_attr {
* **-ENOENT** if symbol is not found.
*
* **-EPERM** if caller does not have permission to obtain kernel address.
+ *
+ * long bpf_strncmp(const char *s1, const char *s2, u32 s2_sz)
+ * Description
+ * Do strncmp() between **s1** and **s2**. **s1** must be a
+ * read-only string. **s2_sz** is the maximum storage size of
+ * **s2**.
+ * Return
+ * Return an integer less than, equal to, or greater than zero
+ * if the first **s2_sz** bytes of **s2** is found to be
+ * less than, to match, or be greater than **s1**.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \@@ -5120,6 +5130,7 @@ union bpf_attr {
FN(trace_vprintk), \
FN(skc_to_unix_sock), \
FN(kallsyms_lookup_name), \
+ FN(strncmp), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper--
2.29.2