1. Aug 22, 2023
  2. Aug 19, 2023
    • Yonghong Song's avatar
      selftests/bpf: Fix a selftest compilation error · 0a55264c
      Yonghong Song authored
      When building the kernel and selftest with clang compiler (llvm17 or llvm18),
      I hit the following compilation failure:
        In file included from progs/test_lwt_redirect.c:3:
        In file included from /usr/include/linux/ip.h:21:
        In file included from /usr/include/asm/byteorder.h:5:
        In file included from /usr/include/linux/byteorder/little_endian.h:13:
        /usr/include/linux/swab.h:136:8: error: unknown type name '__always_inline'
          136 | static __always_inline unsigned long __swab(const unsigned long y)
              |        ^
        /usr/include/linux/swab.h:171:8: error: unknown type name '__always_inline'
          171 | static __always_inline __u16 __swab16p(const __u16 *p)
        ...
      
      bpf_helpers.h file provided a definition for __always_inline.
      Putting 'ip.h' after 'bpf_helpers.h' fixed the issue.
      
      Fixes: 43a7c3ef
      
       ("selftests/bpf: Add lwt_xmit tests for BPF_REDIRECT")
      Signed-off-by: default avatarYonghong Song <yonghong.song@linux.dev>
      Link: https://lore.kernel.org/r/20230818174312.1883381-1-yonghong.song@linux.dev
      
      
      Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
      0a55264c
    • Dave Marchevsky's avatar
      selftests/bpf: Add CO-RE relocs kfunc flavors tests · 63ae8eb2
      Dave Marchevsky authored
      
      
      This patch adds selftests that exercise kfunc flavor relocation
      functionality added in the previous patch. The actual kfunc defined
      in kernel/bpf/helpers.c is:
      
        struct task_struct *bpf_task_acquire(struct task_struct *p)
      
      The following relocation behaviors are checked:
      
        struct task_struct *bpf_task_acquire___one(struct task_struct *name)
          * Should succeed despite differing param name
      
        struct task_struct *bpf_task_acquire___two(struct task_struct *p, void *ctx)
          * Should fail because there is no two-param bpf_task_acquire
      
        struct task_struct *bpf_task_acquire___three(void *ctx)
          * Should fail because, despite vmlinux's bpf_task_acquire having one param,
            the types don't match
      
      Signed-off-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarDavid Vernet <void@manifault.com>
      Link: https://lore.kernel.org/bpf/20230817225353.2570845-2-davemarchevsky@fb.com
      63ae8eb2
    • Dave Marchevsky's avatar
      libbpf: Support triple-underscore flavors for kfunc relocation · 5964a223
      Dave Marchevsky authored
      
      
      The function signature of kfuncs can change at any time due to their
      intentional lack of stability guarantees. As kfuncs become more widely
      used, BPF program writers will need facilities to support calling
      different versions of a kfunc from a single BPF object. Consider this
      simplified example based on a real scenario we ran into at Meta:
      
        /* initial kfunc signature */
        int some_kfunc(void *ptr)
      
        /* Oops, we need to add some flag to modify behavior. No problem,
          change the kfunc. flags = 0 retains original behavior */
        int some_kfunc(void *ptr, long flags)
      
      If the initial version of the kfunc is deployed on some portion of the
      fleet and the new version on the rest, a fleetwide service that uses
      some_kfunc will currently need to load different BPF programs depending
      on which some_kfunc is available.
      
      Luckily CO-RE provides a facility to solve a very similar problem,
      struct definition changes, by allowing program writers to declare
      my_struct___old and my_struct___new, with ___suffix being considered a
      'flavor' of the non-suffixed name and being ignored by
      bpf_core_type_exists and similar calls.
      
      This patch extends the 'flavor' facility to the kfunc extern
      relocation process. BPF program writers can now declare
      
        extern int some_kfunc___old(void *ptr)
        extern int some_kfunc___new(void *ptr, int flags)
      
      then test which version of the kfunc exists with bpf_ksym_exists.
      Relocation and verifier's dead code elimination will work in concert as
      expected, allowing this pattern:
      
        if (bpf_ksym_exists(some_kfunc___old))
          some_kfunc___old(ptr);
        else
          some_kfunc___new(ptr, 0);
      
      Signed-off-by: default avatarDave Marchevsky <davemarchevsky@fb.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarDavid Vernet <void@manifault.com>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Link: https://lore.kernel.org/bpf/20230817225353.2570845-1-davemarchevsky@fb.com
      5964a223
  3. Aug 18, 2023
  4. Aug 17, 2023
  5. Aug 16, 2023
    • Yafang Shao's avatar
      selftests/bpf: Add selftest for fill_link_info · 23cf7aa5
      Yafang Shao authored
      
      
      Add selftest for the fill_link_info of uprobe, kprobe and tracepoint.
      The result:
      
        $ tools/testing/selftests/bpf/test_progs --name=fill_link_info
        #79/1    fill_link_info/kprobe_link_info:OK
        #79/2    fill_link_info/kretprobe_link_info:OK
        #79/3    fill_link_info/kprobe_invalid_ubuff:OK
        #79/4    fill_link_info/tracepoint_link_info:OK
        #79/5    fill_link_info/uprobe_link_info:OK
        #79/6    fill_link_info/uretprobe_link_info:OK
        #79/7    fill_link_info/kprobe_multi_link_info:OK
        #79/8    fill_link_info/kretprobe_multi_link_info:OK
        #79/9    fill_link_info/kprobe_multi_invalid_ubuff:OK
        #79      fill_link_info:OK
        Summary: 1/9 PASSED, 0 SKIPPED, 0 FAILED
      
      The test case for kprobe_multi won't be run on aarch64, as it is not
      supported.
      
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarYonghong Song <yonghong.song@linux.dev>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Link: https://lore.kernel.org/bpf/20230813141900.1268-3-laoar.shao@gmail.com
      23cf7aa5
    • Yafang Shao's avatar
      bpf: Fix uninitialized symbol in bpf_perf_link_fill_kprobe() · 0aa35162
      Yafang Shao authored
      The commit 1b715e1b ("bpf: Support ->fill_link_info for perf_event") leads
      to the following Smatch static checker warning:
      
          kernel/bpf/syscall.c:3416 bpf_perf_link_fill_kprobe()
          error: uninitialized symbol 'type'.
      
      That can happens when uname is NULL. So fix it by verifying the uname when we
      really need to fill it.
      
      Fixes: 1b715e1b
      
       ("bpf: Support ->fill_link_info for perf_event")
      Reported-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
      Signed-off-by: default avatarYafang Shao <laoar.shao@gmail.com>
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: default avatarYonghong Song <yonghong.song@linux.dev>
      Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
      Closes: https://lore.kernel.org/bpf/85697a7e-f897-4f74-8b43-82721bebc462@kili.mountain
      Link: https://lore.kernel.org/bpf/20230813141900.1268-2-laoar.shao@gmail.com
      0aa35162
    • David S. Miller's avatar
      Merge branch 'ipv6-expired-routes' · 950fe358
      David S. Miller authored
      Kui-Feng Lee says:
      
      ====================
      Remove expired routes with a separated list of routes.
      
      FIB6 GC walks trees of fib6_tables to remove expired routes. Walking a tree
      can be expensive if the number of routes in a table is big, even if most of
      them are permanent. Checking routes in a separated list of routes having
      expiration will avoid this potential issue.
      
      Background
      ==========
      
      The size of a Linux IPv6 routing table can become a big problem if not
      managed appropriately.  Now, Linux has a garbage collector to remove
      expired routes periodically.  However, this may lead to a situation in
      which the routing path is blocked for a long period due to an
      excessive number of routes.
      
      For example, years ago, there is a commit c7bb4b89
      
       ("ipv6: tcp:
      drop silly ICMPv6 packet too big messages").  The root cause is that
      malicious ICMPv6 packets were sent back for every small packet sent to
      them. These packets add routes with an expiration time that prompts
      the GC to periodically check all routes in the tables, including
      permanent ones.
      
      Why Route Expires
      =================
      
      Users can add IPv6 routes with an expiration time manually. However,
      the Neighbor Discovery protocol may also generate routes that can
      expire.  For example, Router Advertisement (RA) messages may create a
      default route with an expiration time. [RFC 4861] For IPv4, it is not
      possible to set an expiration time for a route, and there is no RA, so
      there is no need to worry about such issues.
      
      Create Routes with Expires
      ==========================
      
      You can create routes with expires with the  command.
      
      For example,
      
          ip -6 route add 2001:b000:591::3 via fe80::5054:ff:fe12:3457 \
              dev enp0s3 expires 30
      
      The route that has been generated will be deleted automatically in 30
      seconds.
      
      GC of FIB6
      ==========
      
      The function called fib6_run_gc() is responsible for performing
      garbage collection (GC) for the Linux IPv6 stack. It checks for the
      expiration of every route by traversing the trees of routing
      tables. The time taken to traverse a routing table increases with its
      size. Holding the routing table lock during traversal is particularly
      undesirable. Therefore, it is preferable to keep the lock for the
      shortest possible duration.
      
      Solution
      ========
      
      The cause of the issue is keeping the routing table locked during the
      traversal of large trees. To solve this problem, we can create a separate
      list of routes that have expiration. This will prevent GC from checking
      permanent routes.
      
      Result
      ======
      
      We conducted a test to measure the execution times of fib6_gc_timer_cb()
      and observed that it enhances the GC of FIB6. During the test, we added
      permanent routes with the following numbers: 1000, 3000, 6000, and
      9000. Additionally, we added a route with an expiration time.
      
      Here are the average execution times for the kernel without the patch.
       - 120020 ns with 1000 permanent routes
       - 308920 ns with 3000 ...
       - 581470 ns with 6000 ...
       - 855310 ns with 9000 ...
      
      The kernel with the patch consistently takes around 14000 ns to execute,
      regardless of the number of permanent routes that are installed.
      
      Major changes from v7:
      
       - Fix warings raised by the patchwork.
      
      Major changes from v6:
      
       - Remove unnecessary check of tb6 in fib6_clean_expires_locked().
      
       - Use ib6_clean_expires_locked() instead in fib6_purge_rt().
      
      Major changes from v5:
      
       - Change the order of adding new routes to the GC list and starting
         GC timer.
      
       - Remove time measurements from the test case.
      
       - Stop forcing GC flush.
      
      Major changes from v4:
      
       - Detect existence of 'strace' in the test case.
      
      Major changes from v3:
      
       - Fix the type of arg according to feedback.
      
       - Add 1k temporary routes and 5K permanent routes in the test case.
         Measure time spending on GC with strace.
      
      Major changes from v2:
      
       - Remove unnecessary and incorrect sysctl restoring in the test case.
      
      Major changes from v1:
      
       - Moved gc_link to avoid creating a hole in fib6_info.
      
       - Moved fib6_set_expires*() and fib6_clean_expires*() to the header
         file and inlined. And removed duplicated lines.
      
       - Added a test case.
      ====================
      
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      950fe358