All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libbpf: Add bpf_object__set_name(obj, name) api.
@ 2021-07-29 23:41 Yucong Sun
  2021-07-29 23:57 ` [PATCH v2 bpf-next] " Yucong Sun
  0 siblings, 1 reply; 5+ messages in thread
From: Yucong Sun @ 2021-07-29 23:41 UTC (permalink / raw)
  To: bpf; +Cc: fallentree

From: fallentree <fallentree@fb.com>

Tracking: libbpf/libbpf#291

Signed-off-by: Yucong Sun <fallentree@fb.com>
---
 tools/lib/bpf/libbpf.c                                 | 10 ++++++++++
 tools/lib/bpf/libbpf.h                                 |  1 +
 tools/lib/bpf/libbpf.map                               |  1 +
 .../selftests/bpf/prog_tests/reference_tracking.c      |  7 +++++++
 4 files changed, 19 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index a1ca6fb0c6d8..654fa638743f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -7545,6 +7545,16 @@ const char *bpf_object__name(const struct bpf_object *obj)
 	return obj ? obj->name : libbpf_err_ptr(-EINVAL);
 }
 
+int bpf_object__set_name(struct bpf_object *obj, const char* name)
+{
+	if (!name)
+		return libbpf_err(-EINVAL);
+
+	strncpy(obj->name, name, sizeof(obj->name) - 1);
+
+	return 0;
+}
+
 unsigned int bpf_object__kversion(const struct bpf_object *obj)
 {
 	return obj ? obj->kern_version : 0;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 1271d99bb7aa..7d28c7c600d4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -161,6 +161,7 @@ LIBBPF_API int bpf_object__load_xattr(struct bpf_object_load_attr *attr);
 LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
 
 LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
+LIBBPF_API int bpf_object__set_name(struct bpf_object *obj, const char* name);
 LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
 LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
 
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c240d488eb5e..3c15aefeb6e0 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -377,4 +377,5 @@ LIBBPF_0.5.0 {
 		bpf_object__gen_loader;
 		btf_dump__dump_type_data;
 		libbpf_set_strict_mode;
+		bpf_object__set_name;
 } LIBBPF_0.4.0;
diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
index de2688166696..4d3d0a4aec03 100644
--- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
+++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
@@ -5,6 +5,7 @@ void test_reference_tracking(void)
 {
 	const char *file = "test_sk_lookup_kern.o";
 	const char *obj_name = "ref_track";
+	const char *obj_name2 = "ref_track2";
 	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
 		.object_name = obj_name,
 		.relaxed_maps = true,
@@ -23,6 +24,12 @@ void test_reference_tracking(void)
 		  bpf_object__name(obj), obj_name))
 		goto cleanup;
 
+	bpf_object__set_name(obj, obj_name2);
+	if (CHECK(strcmp(bpf_object__name(obj), obj_name2), "obj_name",
+		  "wrong obj name '%s', expected '%s'\n",
+		  bpf_object__name(obj), obj_name2))
+		goto cleanup;
+
 	bpf_object__for_each_program(prog, obj) {
 		const char *title;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 bpf-next] libbpf: Add bpf_object__set_name(obj, name) api.
  2021-07-29 23:41 [PATCH] libbpf: Add bpf_object__set_name(obj, name) api Yucong Sun
@ 2021-07-29 23:57 ` Yucong Sun
  2021-07-30  0:18   ` [PATCH v3 " Yucong Sun
  0 siblings, 1 reply; 5+ messages in thread
From: Yucong Sun @ 2021-07-29 23:57 UTC (permalink / raw)
  To: bpf; +Cc: sunyucong, Yucong Sun

Tracking: libbpf/libbpf#291

Signed-off-by: Yucong Sun <fallentree@fb.com>
---
 tools/lib/bpf/libbpf.c                                 | 10 ++++++++++
 tools/lib/bpf/libbpf.h                                 |  1 +
 tools/lib/bpf/libbpf.map                               |  1 +
 .../selftests/bpf/prog_tests/reference_tracking.c      |  7 +++++++
 4 files changed, 19 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index a1ca6fb0c6d8..654fa638743f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -7545,6 +7545,16 @@ const char *bpf_object__name(const struct bpf_object *obj)
 	return obj ? obj->name : libbpf_err_ptr(-EINVAL);
 }
 
+int bpf_object__set_name(struct bpf_object *obj, const char* name)
+{
+	if (!name)
+		return libbpf_err(-EINVAL);
+
+	strncpy(obj->name, name, sizeof(obj->name) - 1);
+
+	return 0;
+}
+
 unsigned int bpf_object__kversion(const struct bpf_object *obj)
 {
 	return obj ? obj->kern_version : 0;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 1271d99bb7aa..7d28c7c600d4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -161,6 +161,7 @@ LIBBPF_API int bpf_object__load_xattr(struct bpf_object_load_attr *attr);
 LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
 
 LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
+LIBBPF_API int bpf_object__set_name(struct bpf_object *obj, const char* name);
 LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
 LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
 
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c240d488eb5e..3c15aefeb6e0 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -377,4 +377,5 @@ LIBBPF_0.5.0 {
 		bpf_object__gen_loader;
 		btf_dump__dump_type_data;
 		libbpf_set_strict_mode;
+		bpf_object__set_name;
 } LIBBPF_0.4.0;
diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
index de2688166696..4d3d0a4aec03 100644
--- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
+++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
@@ -5,6 +5,7 @@ void test_reference_tracking(void)
 {
 	const char *file = "test_sk_lookup_kern.o";
 	const char *obj_name = "ref_track";
+	const char *obj_name2 = "ref_track2";
 	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
 		.object_name = obj_name,
 		.relaxed_maps = true,
@@ -23,6 +24,12 @@ void test_reference_tracking(void)
 		  bpf_object__name(obj), obj_name))
 		goto cleanup;
 
+	bpf_object__set_name(obj, obj_name2);
+	if (CHECK(strcmp(bpf_object__name(obj), obj_name2), "obj_name",
+		  "wrong obj name '%s', expected '%s'\n",
+		  bpf_object__name(obj), obj_name2))
+		goto cleanup;
+
 	bpf_object__for_each_program(prog, obj) {
 		const char *title;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 bpf-next] libbpf: Add bpf_object__set_name(obj, name) api.
  2021-07-29 23:57 ` [PATCH v2 bpf-next] " Yucong Sun
@ 2021-07-30  0:18   ` Yucong Sun
  2021-07-30  0:29     ` [PATCH v4 " Yucong Sun
  0 siblings, 1 reply; 5+ messages in thread
From: Yucong Sun @ 2021-07-30  0:18 UTC (permalink / raw)
  To: bpf; +Cc: sunyucong, Yucong Sun

Tracking: libbpf/libbpf#291

Signed-off-by: Yucong Sun <fallentree@fb.com>

--

V2 -> V3: fix code style errors
---
 tools/lib/bpf/libbpf.c                                 | 10 ++++++++++
 tools/lib/bpf/libbpf.h                                 |  1 +
 tools/lib/bpf/libbpf.map                               |  1 +
 .../selftests/bpf/prog_tests/reference_tracking.c      |  7 +++++++
 4 files changed, 19 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index a1ca6fb0c6d8..654fa638743f 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -7545,6 +7545,16 @@ const char *bpf_object__name(const struct bpf_object *obj)
 	return obj ? obj->name : libbpf_err_ptr(-EINVAL);
 }
 
+int bpf_object__set_name(struct bpf_object *obj, const char* name)
+{
+	if (!name)
+		return libbpf_err(-EINVAL);
+
+	strncpy(obj->name, name, sizeof(obj->name) - 1);
+
+	return 0;
+}
+
 unsigned int bpf_object__kversion(const struct bpf_object *obj)
 {
 	return obj ? obj->kern_version : 0;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 1271d99bb7aa..36a2946e3373 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -161,6 +161,7 @@ LIBBPF_API int bpf_object__load_xattr(struct bpf_object_load_attr *attr);
 LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
 
 LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
+LIBBPF_API int bpf_object__set_name(struct bpf_object *obj, const char *name);
 LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
 LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
 
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c240d488eb5e..3c15aefeb6e0 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -377,4 +377,5 @@ LIBBPF_0.5.0 {
 		bpf_object__gen_loader;
 		btf_dump__dump_type_data;
 		libbpf_set_strict_mode;
+		bpf_object__set_name;
 } LIBBPF_0.4.0;
diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
index de2688166696..4d3d0a4aec03 100644
--- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
+++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
@@ -5,6 +5,7 @@ void test_reference_tracking(void)
 {
 	const char *file = "test_sk_lookup_kern.o";
 	const char *obj_name = "ref_track";
+	const char *obj_name2 = "ref_track2";
 	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
 		.object_name = obj_name,
 		.relaxed_maps = true,
@@ -23,6 +24,12 @@ void test_reference_tracking(void)
 		  bpf_object__name(obj), obj_name))
 		goto cleanup;
 
+	bpf_object__set_name(obj, obj_name2);
+	if (CHECK(strcmp(bpf_object__name(obj), obj_name2), "obj_name",
+		  "wrong obj name '%s', expected '%s'\n",
+		  bpf_object__name(obj), obj_name2))
+		goto cleanup;
+
 	bpf_object__for_each_program(prog, obj) {
 		const char *title;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v4 bpf-next] libbpf: Add bpf_object__set_name(obj, name) api.
  2021-07-30  0:18   ` [PATCH v3 " Yucong Sun
@ 2021-07-30  0:29     ` Yucong Sun
  2021-07-30  0:58       ` Andrii Nakryiko
  0 siblings, 1 reply; 5+ messages in thread
From: Yucong Sun @ 2021-07-30  0:29 UTC (permalink / raw)
  To: bpf; +Cc: sunyucong, Yucong Sun

Tracking: libbpf/libbpf#291

Signed-off-by: Yucong Sun <fallentree@fb.com>

---

V3 -> V4: handle obj is NULL case.
V2 -> V3: fix code style errors
---
 tools/lib/bpf/libbpf.c                                 | 10 ++++++++++
 tools/lib/bpf/libbpf.h                                 |  1 +
 tools/lib/bpf/libbpf.map                               |  1 +
 .../selftests/bpf/prog_tests/reference_tracking.c      |  7 +++++++
 4 files changed, 19 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index a1ca6fb0c6d8..a628e94a41a4 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -7545,6 +7545,16 @@ const char *bpf_object__name(const struct bpf_object *obj)
 	return obj ? obj->name : libbpf_err_ptr(-EINVAL);
 }
 
+int bpf_object__set_name(struct bpf_object *obj, const char *name)
+{
+	if (!obj || !name)
+		return libbpf_err(-EINVAL);
+
+	strncpy(obj->name, name, sizeof(obj->name) - 1);
+
+	return 0;
+}
+
 unsigned int bpf_object__kversion(const struct bpf_object *obj)
 {
 	return obj ? obj->kern_version : 0;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 1271d99bb7aa..36a2946e3373 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -161,6 +161,7 @@ LIBBPF_API int bpf_object__load_xattr(struct bpf_object_load_attr *attr);
 LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
 
 LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
+LIBBPF_API int bpf_object__set_name(struct bpf_object *obj, const char *name);
 LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
 LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
 
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index c240d488eb5e..3c15aefeb6e0 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -377,4 +377,5 @@ LIBBPF_0.5.0 {
 		bpf_object__gen_loader;
 		btf_dump__dump_type_data;
 		libbpf_set_strict_mode;
+		bpf_object__set_name;
 } LIBBPF_0.4.0;
diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
index de2688166696..4d3d0a4aec03 100644
--- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
+++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
@@ -5,6 +5,7 @@ void test_reference_tracking(void)
 {
 	const char *file = "test_sk_lookup_kern.o";
 	const char *obj_name = "ref_track";
+	const char *obj_name2 = "ref_track2";
 	DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
 		.object_name = obj_name,
 		.relaxed_maps = true,
@@ -23,6 +24,12 @@ void test_reference_tracking(void)
 		  bpf_object__name(obj), obj_name))
 		goto cleanup;
 
+	bpf_object__set_name(obj, obj_name2);
+	if (CHECK(strcmp(bpf_object__name(obj), obj_name2), "obj_name",
+		  "wrong obj name '%s', expected '%s'\n",
+		  bpf_object__name(obj), obj_name2))
+		goto cleanup;
+
 	bpf_object__for_each_program(prog, obj) {
 		const char *title;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v4 bpf-next] libbpf: Add bpf_object__set_name(obj, name) api.
  2021-07-30  0:29     ` [PATCH v4 " Yucong Sun
@ 2021-07-30  0:58       ` Andrii Nakryiko
  0 siblings, 0 replies; 5+ messages in thread
From: Andrii Nakryiko @ 2021-07-30  0:58 UTC (permalink / raw)
  To: Yucong Sun; +Cc: bpf, sunyucong

On Thu, Jul 29, 2021 at 5:31 PM Yucong Sun <fallentree@fb.com> wrote:
>
> Tracking: libbpf/libbpf#291

Please provide a bit more elaborate commit summary. Just a link to
libbpf Github PR isn't a good commit message. Please explain
succinctly what is being added and why.

As for the PR reference itself, please include the full link. You can
use this form (which Quentin used pretty consistently already):

Reference: https://github.com/libbpf/libbpf/issues/291

>
> Signed-off-by: Yucong Sun <fallentree@fb.com>
>
> ---
>
> V3 -> V4: handle obj is NULL case.
> V2 -> V3: fix code style errors
> ---
>  tools/lib/bpf/libbpf.c                                 | 10 ++++++++++
>  tools/lib/bpf/libbpf.h                                 |  1 +
>  tools/lib/bpf/libbpf.map                               |  1 +
>  .../selftests/bpf/prog_tests/reference_tracking.c      |  7 +++++++
>  4 files changed, 19 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index a1ca6fb0c6d8..a628e94a41a4 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -7545,6 +7545,16 @@ const char *bpf_object__name(const struct bpf_object *obj)
>         return obj ? obj->name : libbpf_err_ptr(-EINVAL);
>  }
>
> +int bpf_object__set_name(struct bpf_object *obj, const char *name)
> +{
> +       if (!obj || !name)
> +               return libbpf_err(-EINVAL);

I think we shouldn't be checking !obj in every bpf_object's API (even
though we have a bunch of APIs like that). If user can't make sure
they pass non-NULL proper pointer, it's fine for them to debug
SIGSEGV.

> +
> +       strncpy(obj->name, name, sizeof(obj->name) - 1);

let's do two extra checks:

1. if bpf_object was already loaded, it's too late (maps were named
with its name, etc), so error out in that case
2. if provided name is too long, we can still truncate and set it, but
let's also return -E2BIG maybe?

BTW, static analyzers like to complain about strncpy not zero
terminating, add extra obj->name[sizeof(obj->name) - 1] = '\0'; at the
end to make them happier


Also, please add selftest validating that this name is actually taken
into account properly. First thing that comes to mind to check this
would be .data/.rodata map names check, but look around the source
code to see if there is something other that can be used as a check.


> +
> +       return 0;
> +}
> +
>  unsigned int bpf_object__kversion(const struct bpf_object *obj)
>  {
>         return obj ? obj->kern_version : 0;
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index 1271d99bb7aa..36a2946e3373 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -161,6 +161,7 @@ LIBBPF_API int bpf_object__load_xattr(struct bpf_object_load_attr *attr);
>  LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
>
>  LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
> +LIBBPF_API int bpf_object__set_name(struct bpf_object *obj, const char *name);
>  LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
>  LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
>
> diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
> index c240d488eb5e..3c15aefeb6e0 100644
> --- a/tools/lib/bpf/libbpf.map
> +++ b/tools/lib/bpf/libbpf.map
> @@ -377,4 +377,5 @@ LIBBPF_0.5.0 {
>                 bpf_object__gen_loader;
>                 btf_dump__dump_type_data;
>                 libbpf_set_strict_mode;
> +               bpf_object__set_name;

please keep that list alphabetically sorted

>  } LIBBPF_0.4.0;
> diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
> index de2688166696..4d3d0a4aec03 100644
> --- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
> +++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c
> @@ -5,6 +5,7 @@ void test_reference_tracking(void)
>  {
>         const char *file = "test_sk_lookup_kern.o";
>         const char *obj_name = "ref_track";
> +       const char *obj_name2 = "ref_track2";
>         DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
>                 .object_name = obj_name,
>                 .relaxed_maps = true,
> @@ -23,6 +24,12 @@ void test_reference_tracking(void)
>                   bpf_object__name(obj), obj_name))
>                 goto cleanup;
>
> +       bpf_object__set_name(obj, obj_name2);
> +       if (CHECK(strcmp(bpf_object__name(obj), obj_name2), "obj_name",
> +                 "wrong obj name '%s', expected '%s'\n",
> +                 bpf_object__name(obj), obj_name2))
> +               goto cleanup;
> +

it's a bit too simple and doesn't test much. See how obj->name is used
for naming maps (and maybe something else as well), and validate that
it gets propagated properly

>         bpf_object__for_each_program(prog, obj) {
>                 const char *title;
>
> --
> 2.30.2
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-07-30  0:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-29 23:41 [PATCH] libbpf: Add bpf_object__set_name(obj, name) api Yucong Sun
2021-07-29 23:57 ` [PATCH v2 bpf-next] " Yucong Sun
2021-07-30  0:18   ` [PATCH v3 " Yucong Sun
2021-07-30  0:29     ` [PATCH v4 " Yucong Sun
2021-07-30  0:58       ` Andrii Nakryiko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.