// SPDX-License-Identifier: GPL-2.0
 /*
- * Test that the flow_dissector program can be updated with a single
- * syscall by attaching a new program that replaces the existing one.
- *
- * Corner case - the same program cannot be attached twice.
+ * Tests for attaching, detaching, and replacing flow_dissector BPF program.
  */
 
 #define _GNU_SOURCE
        CHECK_FAIL(prog_is_attached(netns));
 }
 
+static void test_link_update_same_prog(int netns, int prog1, int prog2)
+{
+       DECLARE_LIBBPF_OPTS(bpf_link_create_opts, create_opts);
+       DECLARE_LIBBPF_OPTS(bpf_link_update_opts, update_opts);
+       int err, link;
+
+       link = bpf_link_create(prog1, netns, BPF_FLOW_DISSECTOR, &create_opts);
+       if (CHECK_FAIL(link < 0)) {
+               perror("bpf_link_create(prog1)");
+               return;
+       }
+       CHECK_FAIL(query_attached_prog_id(netns) != query_prog_id(prog1));
+
+       /* Expect success updating the prog with the same one */
+       update_opts.flags = 0;
+       update_opts.old_prog_fd = 0;
+       err = bpf_link_update(link, prog1, &update_opts);
+       if (CHECK_FAIL(err))
+               perror("bpf_link_update");
+       CHECK_FAIL(query_attached_prog_id(netns) != query_prog_id(prog1));
+
+       close(link);
+       CHECK_FAIL(prog_is_attached(netns));
+}
+
 static void test_link_update_invalid_opts(int netns, int prog1, int prog2)
 {
        DECLARE_LIBBPF_OPTS(bpf_link_create_opts, create_opts);
                  test_link_update_no_old_prog },
                { "link update with replace old prog",
                  test_link_update_replace_old_prog },
+               { "link update with same prog",
+                 test_link_update_same_prog },
                { "link update invalid opts",
                  test_link_update_invalid_opts },
                { "link update invalid prog",