Add a helper to iterate bpf_prog_arrays, which are a hybrid between
and array and a linked list. Hide this behind a for each macro.

Signed-off-by: Lorenz Bauer <l...@cloudflare.com>
---
 include/linux/bpf.h    | 11 +++++------
 include/linux/filter.h |  4 +---
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index cccaef1088ea..875f6bc4bf1d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1070,6 +1070,9 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array,
 /* BPF program asks to set CN on the packet. */
 #define BPF_RET_SET_CN                                         (1 << 0)
 
+#define for_each_bpf_prog(_array, _item, _prog) \
+       for ((_item) = &(_array)->items[0]; ((_prog) = 
READ_ONCE((_item)->prog)); (_item)++)
+
 #define BPF_PROG_RUN_ARRAY_FLAGS(array, ctx, func, ret_flags)          \
        ({                                                              \
                struct bpf_prog_array_item *_item;                      \
@@ -1080,13 +1083,11 @@ int bpf_prog_array_copy(struct bpf_prog_array 
*old_array,
                migrate_disable();                                      \
                rcu_read_lock();                                        \
                _array = rcu_dereference(array);                        \
-               _item = &_array->items[0];                              \
-               while ((_prog = READ_ONCE(_item->prog))) {              \
+               for_each_bpf_prog(_array, _item, _prog) {               \
                        bpf_cgroup_storage_set(_item->cgroup_storage);  \
                        func_ret = func(_prog, ctx);                    \
                        _ret &= (func_ret & 1);                         \
                        *(ret_flags) |= (func_ret >> 1);                        
\
-                       _item++;                                        \
                }                                                       \
                rcu_read_unlock();                                      \
                migrate_enable();                                       \
@@ -1104,11 +1105,9 @@ int bpf_prog_array_copy(struct bpf_prog_array *old_array,
                _array = rcu_dereference(array);        \
                if (unlikely(check_non_null && !_array))\
                        goto _out;                      \
-               _item = &_array->items[0];              \
-               while ((_prog = READ_ONCE(_item->prog))) {              \
+               for_each_bpf_prog(_array, _item, _prog) {               \
                        bpf_cgroup_storage_set(_item->cgroup_storage);  \
                        _ret &= func(_prog, ctx);       \
-                       _item++;                        \
                }                                       \
 _out:                                                  \
                rcu_read_unlock();                      \
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 3b00fc906ccd..9ed20ff29d9a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -1376,8 +1376,7 @@ extern struct static_key_false bpf_sk_lookup_enabled;
                u32 _ret;                                               \
                                                                        \
                migrate_disable();                                      \
-               _item = &(array)->items[0];                             \
-               while ((_prog = READ_ONCE(_item->prog))) {              \
+               for_each_bpf_prog(array, _item, _prog) {                \
                        /* restore most recent selection */             \
                        _ctx->selected_sk = _selected_sk;               \
                        _ctx->no_reuseport = _no_reuseport;             \
@@ -1390,7 +1389,6 @@ extern struct static_key_false bpf_sk_lookup_enabled;
                        } else if (_ret == SK_DROP && _all_pass) {      \
                                _all_pass = false;                      \
                        }                                               \
-                       _item++;                                        \
                }                                                       \
                _ctx->selected_sk = _selected_sk;                       \
                _ctx->no_reuseport = _no_reuseport;                     \
-- 
2.27.0

Reply via email to