1. 01 Mar, 2023 10 commits
    • Joanne Koong's avatar
      selftests/bpf: tests for using dynptrs to parse skb and xdp buffers · cfa7b011
      Joanne Koong authored
      Test skb and xdp dynptr functionality in the following ways:
      
      1) progs/test_cls_redirect_dynptr.c
         * Rewrite "progs/test_cls_redirect.c" test to use dynptrs to parse
           skb data
      
         * This is a great example of how dynptrs can be used to simplify a
           lot of the parsing logic for non-statically known values.
      
           When measuring the user + system time between the original version
           vs. using dynptrs, and averaging the time for 10 runs (using
           "time ./test_progs -t cls_redirect"):
               original version: 0.092 sec
               with dynptrs: 0.078 sec
      
      2) progs/test_xdp_dynptr.c
         * Rewrite "progs/test_xdp.c" test to use dynptrs to parse xdp data
      
           When measuring the user + system time between the original version
           vs. using dynptrs, and averaging the time for 10 runs (using
           "time ./test_progs -t xdp_attach"):
               original version: 0.118 sec
               with dynptrs: 0.094 sec
      
      3) progs/test_l4lb_noinline_dynptr.c
         * Rewrite "progs/test_l4lb_noinline.c" test to use dynptrs to parse
           skb data
      
           When measuring the user + system time between the original version
           vs. using dynptrs, and averaging the time for 10 runs (using
           "time ./test_progs -t l4lb_all"):
               original version: 0.062 sec
               with dynptrs: 0.081 sec
      
           For number of processed verifier instructions:
               original version: 6268 insns
               with dynptrs: 2588 insns
      
      4) progs/test_parse_tcp_hdr_opt_dynptr.c
         * Add sample code for parsing tcp hdr opt lookup using dynptrs.
           This logic is lifted from a real-world use case of packet parsing
           in katran [0], a layer 4 load balancer. The original version
           "progs/test_parse_tcp_hdr_opt.c" (not using dynptrs) is included
           here as well, for comparison.
      
           When measuring the user + system time between the original version
           vs. using dynptrs, and averaging the time for 10 runs (using
           "time ./test_progs -t parse_tcp_hdr_opt"):
               original version: 0.031 sec
               with dynptrs: 0.045 sec
      
      5) progs/dynptr_success.c
         * Add test case "test_skb_readonly" for testing attempts at writes
           on a prog type with read-only skb ctx.
         * Add "test_dynptr_skb_data" for testing that bpf_dynptr_data isn't
           supported for skb progs.
      
      6) progs/dynptr_fail.c
         * Add test cases "skb_invalid_data_slice{1,2,3,4}" and
           "xdp_invalid_data_slice{1,2}" for testing that helpers that modify the
           underlying packet buffer automatically invalidate the associated
           data slice.
         * Add test cases "skb_invalid_ctx" and "xdp_invalid_ctx" for testing
           that prog types that do not support bpf_dynptr_from_skb/xdp don't
           have access to the API.
         * Add test case "dynptr_slice_var_len{1,2}" for testing that
           variable-sized len can't be passed in to bpf_dynptr_slice
         * Add test case "skb_invalid_slice_write" for testing that writes to a
           read-only data slice are rejected by the verifier.
         * Add test case "data_slice_out_of_bounds_skb" for testing that
           writes to an area outside the slice are rejected.
         * Add test case "invalid_slice_rdwr_rdonly" for testing that prog
           types that don't allow writes to packet data don't accept any calls
           to bpf_dynptr_slice_rdwr.
      
      [0] https://github.com/facebookincubator/katran/blob/main/katran/lib/bpf/pckt_parsing.hSigned-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/r/20230301154953.641654-11-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      cfa7b011
    • Joanne Koong's avatar
      bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr · 66e3a13e
      Joanne Koong authored
      Two new kfuncs are added, bpf_dynptr_slice and bpf_dynptr_slice_rdwr.
      The user must pass in a buffer to store the contents of the data slice
      if a direct pointer to the data cannot be obtained.
      
      For skb and xdp type dynptrs, these two APIs are the only way to obtain
      a data slice. However, for other types of dynptrs, there is no
      difference between bpf_dynptr_slice(_rdwr) and bpf_dynptr_data.
      
      For skb type dynptrs, the data is copied into the user provided buffer
      if any of the data is not in the linear portion of the skb. For xdp type
      dynptrs, the data is copied into the user provided buffer if the data is
      between xdp frags.
      
      If the skb is cloned and a call to bpf_dynptr_data_rdwr is made, then
      the skb will be uncloned (see bpf_unclone_prologue()).
      
      Please note that any bpf_dynptr_write() automatically invalidates any prior
      data slices of the skb dynptr. This is because the skb may be cloned or
      may need to pull its paged buffer into the head. As such, any
      bpf_dynptr_write() will automatically have its prior data slices
      invalidated, even if the write is to data in the skb head of an uncloned
      skb. Please note as well that any other helper calls that change the
      underlying packet buffer (eg bpf_skb_pull_data()) invalidates any data
      slices of the skb dynptr as well, for the same reasons.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-10-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      66e3a13e
    • Joanne Koong's avatar
      bpf: Add xdp dynptrs · 05421aec
      Joanne Koong authored
      Add xdp dynptrs, which are dynptrs whose underlying pointer points
      to a xdp_buff. The dynptr acts on xdp data. xdp dynptrs have two main
      benefits. One is that they allow operations on sizes that are not
      statically known at compile-time (eg variable-sized accesses).
      Another is that parsing the packet data through dynptrs (instead of
      through direct access of xdp->data and xdp->data_end) can be more
      ergonomic and less brittle (eg does not need manual if checking for
      being within bounds of data_end).
      
      For reads and writes on the dynptr, this includes reading/writing
      from/to and across fragments. Data slices through the bpf_dynptr_data
      API are not supported; instead bpf_dynptr_slice() and
      bpf_dynptr_slice_rdwr() should be used.
      
      For examples of how xdp dynptrs can be used, please see the attached
      selftests.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-9-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      05421aec
    • Joanne Koong's avatar
      bpf: Add skb dynptrs · b5964b96
      Joanne Koong authored
      Add skb dynptrs, which are dynptrs whose underlying pointer points
      to a skb. The dynptr acts on skb data. skb dynptrs have two main
      benefits. One is that they allow operations on sizes that are not
      statically known at compile-time (eg variable-sized accesses).
      Another is that parsing the packet data through dynptrs (instead of
      through direct access of skb->data and skb->data_end) can be more
      ergonomic and less brittle (eg does not need manual if checking for
      being within bounds of data_end).
      
      For bpf prog types that don't support writes on skb data, the dynptr is
      read-only (bpf_dynptr_write() will return an error)
      
      For reads and writes through the bpf_dynptr_read() and bpf_dynptr_write()
      interfaces, reading and writing from/to data in the head as well as from/to
      non-linear paged buffers is supported. Data slices through the
      bpf_dynptr_data API are not supported; instead bpf_dynptr_slice() and
      bpf_dynptr_slice_rdwr() (added in subsequent commit) should be used.
      
      For examples of how skb dynptrs can be used, please see the attached
      selftests.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-8-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      b5964b96
    • Joanne Koong's avatar
      bpf: Add __uninit kfunc annotation · d96d937d
      Joanne Koong authored
      This patch adds __uninit as a kfunc annotation.
      
      This will be useful for scenarios such as for example in dynptrs,
      indicating whether the dynptr should be checked by the verifier as an
      initialized or an uninitialized dynptr.
      
      Without this annotation, the alternative would be needing to hard-code
      in the verifier the specific kfunc to indicate that arg should be
      treated as an uninitialized arg.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-7-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      d96d937d
    • Joanne Koong's avatar
      bpf: Refactor verifier dynptr into get_dynptr_arg_reg · 485ec51e
      Joanne Koong authored
      This commit refactors the logic for determining which register in a
      function is the dynptr into "get_dynptr_arg_reg". This will be used
      in the future when the dynptr reg for BPF_FUNC_dynptr_write will need
      to be obtained in order to support writes for skb dynptrs.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-6-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      485ec51e
    • Joanne Koong's avatar
      bpf: Define no-ops for externally called bpf dynptr functions · 8357b366
      Joanne Koong authored
      Some bpf dynptr functions will be called from places where
      if CONFIG_BPF_SYSCALL is not set, then the dynptr function is
      undefined. For example, when skb type dynptrs are added in the
      next commit, dynptr functions are called from net/core/filter.c
      
      This patch defines no-op implementations of these dynptr functions
      so that they do not break compilation by being an undefined reference.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-5-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      8357b366
    • Joanne Koong's avatar
      bpf: Allow initializing dynptrs in kfuncs · 1d18feb2
      Joanne Koong authored
      This change allows kfuncs to take in an uninitialized dynptr as a
      parameter. Before this change, only helper functions could successfully
      use uninitialized dynptrs. This change moves the memory access check
      (including stack state growing and slot marking) into
      process_dynptr_func(), which both helpers and kfuncs call into.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-4-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      1d18feb2
    • Joanne Koong's avatar
      bpf: Refactor process_dynptr_func · 7e0dac28
      Joanne Koong authored
      This change cleans up process_dynptr_func's flow to be more intuitive
      and updates some comments with more context.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-3-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      7e0dac28
    • Joanne Koong's avatar
      bpf: Support "sk_buff" and "xdp_buff" as valid kfunc arg types · 2f464393
      Joanne Koong authored
      The bpf mirror of the in-kernel sk_buff and xdp_buff data structures are
      __sk_buff and xdp_md. Currently, when we pass in the program ctx to a
      kfunc where the program ctx is a skb or xdp buffer, we reject the
      program if the in-kernel definition is sk_buff/xdp_buff instead of
      __sk_buff/xdp_md.
      
      This change allows "sk_buff <--> __sk_buff" and "xdp_buff <--> xdp_md"
      to be recognized as valid matches. The user program may pass in their
      program ctx as a __sk_buff or xdp_md, and the in-kernel definition
      of the kfunc may define this arg as a sk_buff or xdp_buff.
      Signed-off-by: default avatarJoanne Koong <joannelkoong@gmail.com>
      Link: https://lore.kernel.org/r/20230301154953.641654-2-joannelkoong@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      2f464393
  2. 28 Feb, 2023 4 commits
  3. 27 Feb, 2023 7 commits
  4. 25 Feb, 2023 3 commits
  5. 23 Feb, 2023 2 commits
  6. 22 Feb, 2023 14 commits