1. 29 9月, 2020 23 次提交
  2. 26 9月, 2020 17 次提交
    • J
      bpf: Add comment to document BTF type PTR_TO_BTF_ID_OR_NULL · ba5f4cfe
      John Fastabend 提交于
      The meaning of PTR_TO_BTF_ID_OR_NULL differs slightly from other types
      denoted with the *_OR_NULL type. For example the types PTR_TO_SOCKET
      and PTR_TO_SOCKET_OR_NULL can be used for branch analysis because the
      type PTR_TO_SOCKET is guaranteed to _not_ have a null value.
      
      In contrast PTR_TO_BTF_ID and BTF_TO_BTF_ID_OR_NULL have slightly
      different meanings. A PTR_TO_BTF_TO_ID may be a pointer to NULL value,
      but it is safe to read this pointer in the program context because
      the program context will handle any faults. The fallout is for
      PTR_TO_BTF_ID the verifier can assume reads are safe, but can not
      use the type in branch analysis. Additionally, authors need to be
      extra careful when passing PTR_TO_BTF_ID into helpers. In general
      helpers consuming type PTR_TO_BTF_ID will need to assume it may
      be null.
      
      Seeing the above is not obvious to readers without the back knowledge
      lets add a comment in the type definition.
      
      Editorial comment, as networking and tracing programs get closer
      and more tightly merged we may need to consider a new type that we
      can ensure is non-null for branch analysis and also passing into
      helpers.
      Signed-off-by: NJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NLorenz Bauer <lmb@cloudflare.com>
      ba5f4cfe
    • J
      bpf: Add AND verifier test case where 32bit and 64bit bounds differ · 99d4def4
      John Fastabend 提交于
      If we AND two values together that are known in the 32bit subregs, but not
      known in the 64bit registers we rely on the tnum value to report the 32bit
      subreg is known. And do not use mark_reg_known() directly from
      scalar32_min_max_and()
      
      Add an AND test to cover the case with known 32bit subreg, but unknown
      64bit reg.
      Signed-off-by: NJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      99d4def4
    • J
      bpf, verifier: Remove redundant var_off.value ops in scalar known reg cases · 4fbb38a3
      John Fastabend 提交于
      In BPF_AND and BPF_OR alu cases we have this pattern when the src and dst
      tnum is a constant.
      
       1 dst_reg->var_off = tnum_[op](dst_reg->var_off, src_reg.var_off)
       2 scalar32_min_max_[op]
       3       if (known) return
       4 scalar_min_max_[op]
       5       if (known)
       6          __mark_reg_known(dst_reg,
                         dst_reg->var_off.value [op] src_reg.var_off.value)
      
      The result is in 1 we calculate the var_off value and store it in the
      dst_reg. Then in 6 we duplicate this logic doing the op again on the
      value.
      
      The duplication comes from the the tnum_[op] handlers because they have
      already done the value calcuation. For example this is tnum_and().
      
       struct tnum tnum_and(struct tnum a, struct tnum b)
       {
      	u64 alpha, beta, v;
      
      	alpha = a.value | a.mask;
      	beta = b.value | b.mask;
      	v = a.value & b.value;
      	return TNUM(v, alpha & beta & ~v);
       }
      
      So lets remove the redundant op calculation. Its confusing for readers
      and unnecessary. Its also not harmful because those ops have the
      property, r1 & r1 = r1 and r1 | r1 = r1.
      Signed-off-by: NJohn Fastabend <john.fastabend@gmail.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      4fbb38a3
    • A
      Merge branch 'enable-bpf_skc-cast-for-networking-progs' · 84085f87
      Alexei Starovoitov 提交于
      Martin KaFai Lau says:
      
      ====================
      This set allows networking prog type to directly read fields from
      the in-kernel socket type, e.g. "struct tcp_sock".
      
      Patch 2 has the details on the use case.
      
      v3:
      - Pass arg_btf_id instead of fn into check_reg_type() in Patch 1 (Lorenz)
      - Move arg_btf_id from func_proto to struct bpf_reg_types in Patch 2 (Lorenz)
      - Remove test_sock_fields from .gitignore in Patch 8 (Andrii)
      - Add tests to have better coverage on the modified helpers (Alexei)
        Patch 13 is added.
      - Use "void *sk" as the helper argument in UAPI bpf.h
      
      v3:
      - ARG_PTR_TO_SOCK_COMMON_OR_NULL was attempted in v2.  The _OR_NULL was
        needed because the PTR_TO_BTF_ID could be NULL but note that a could be NULL
        PTR_TO_BTF_ID is not a scalar NULL to the verifier.  "_OR_NULL" implicitly
        gives an expectation that the helper can take a scalar NULL which does
        not make sense in most (except one) helpers.  Passing scalar NULL
        should be rejected at the verification time.
      
        Thus, this patch uses ARG_PTR_TO_BTF_ID_SOCK_COMMON to specify that the
        helper can take both the btf-id ptr or the legacy PTR_TO_SOCK_COMMON but
        not scalar NULL.  It requires the func_proto to explicitly specify the
        arg_btf_id such that there is a very clear expectation that the helper
        can handle a NULL PTR_TO_BTF_ID.
      
      v2:
      - Add ARG_PTR_TO_SOCK_COMMON_OR_NULL (Lorenz)
      ====================
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      84085f87
    • M
      bpf: selftest: Add test_btf_skc_cls_ingress · 9a856cae
      Martin KaFai Lau 提交于
      This patch attaches a classifier prog to the ingress filter.
      It exercises the following helpers with different socket pointer
      types in different logical branches:
      1. bpf_sk_release()
      2. bpf_sk_assign()
      3. bpf_skc_to_tcp_request_sock(), bpf_skc_to_tcp_sock()
      4. bpf_tcp_gen_syncookie, bpf_tcp_check_syncookie
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000458.3859627-1-kafai@fb.com
      9a856cae
    • M
      bpf: selftest: Remove enum tcp_ca_state from bpf_tcp_helpers.h · 0c402c6c
      Martin KaFai Lau 提交于
      The enum tcp_ca_state is available in <linux/tcp.h>.
      Remove it from the bpf_tcp_helpers.h to avoid conflict when the bpf prog
      needs to include both both <linux/tcp.h> and bpf_tcp_helpers.h.
      
      Modify the bpf_cubic.c and bpf_dctcp.c to use <linux/tcp.h> instead.
      The <linux/stddef.h> is needed by <linux/tcp.h>.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000452.3859313-1-kafai@fb.com
      0c402c6c
    • M
      bpf: selftest: Use bpf_skc_to_tcp_sock() in the sock_fields test · edc2d66a
      Martin KaFai Lau 提交于
      This test uses bpf_skc_to_tcp_sock() to get a kernel tcp_sock ptr "ktp".
      Access the ktp->lsndtime and also pass ktp to bpf_sk_storage_get().
      
      It also exercises the bpf_sk_cgroup_id() and bpf_sk_ancestor_cgroup_id()
      with the "ktp".  To do that, a parent cgroup and a child cgroup are
      created.  The bpf prog is attached to the child cgroup.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000446.3858975-1-kafai@fb.com
      edc2d66a
    • M
      bpf: selftest: Use network_helpers in the sock_fields test · c40a565a
      Martin KaFai Lau 提交于
      This patch uses start_server() and connect_to_fd() from network_helpers.h
      to remove the network testing boiler plate codes.  epoll is no longer
      needed also since the timeout has already been taken care of also.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000440.3858639-1-kafai@fb.com
      c40a565a
    • M
      bpf: selftest: Adapt sock_fields test to use skel and global variables · b18c1f0a
      Martin KaFai Lau 提交于
      skel is used.
      
      Global variables are used to store the result from bpf prog.
      addr_map, sock_result_map, and tcp_sock_result_map are gone.
      Instead, global variables listen_tp, srv_sa6, cli_tp,, srv_tp,
      listen_sk, srv_sk, and cli_sk are added.
      Because of that, bpf_addr_array_idx and bpf_result_array_idx are also
      no longer needed.
      
      CHECK() macro from test_progs.h is reused and bail as soon as
      a CHECK failure.
      
      shutdown() is used to ensure the previous data-ack is received.
      The bytes_acked, bytes_received, and the pkt_out_cnt checks are
      using "<" to accommodate the final ack may not have been received/sent.
      It is enough since it is not the focus of this test.
      
      The sk local storage is all initialized to 0xeB9F now, so the
      check_sk_pkt_out_cnt() always checks with the 0xeB9F base.  It is to
      keep things simple.
      
      The next patch will reuse helpers from network_helpers.h to simplify
      things further.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000434.3858204-1-kafai@fb.com
      b18c1f0a
    • M
      bpf: selftest: Move sock_fields test into test_progs · 6f521a2b
      Martin KaFai Lau 提交于
      This is a mechanical change to
      1. move test_sock_fields.c to prog_tests/sock_fields.c
      2. rename progs/test_sock_fields_kern.c to progs/test_sock_fields.c
      
      Minimal change is made to the code itself.  Next patch will make
      changes to use new ways of writing test, e.g. use skel and global
      variables.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000427.3857814-1-kafai@fb.com
      6f521a2b
    • M
      bpf: selftest: Add ref_tracking verifier test for bpf_skc casting · 5d13746d
      Martin KaFai Lau 提交于
      The patch tests for:
      1. bpf_sk_release() can be called on a tcp_sock btf_id ptr.
      
      2. Ensure the tcp_sock btf_id pointer cannot be used
         after bpf_sk_release().
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NLorenz Bauer <lmb@cloudflare.com>
      Link: https://lore.kernel.org/bpf/20200925000421.3857616-1-kafai@fb.com
      5d13746d
    • M
      bpf: Change bpf_sk_assign to accept ARG_PTR_TO_BTF_ID_SOCK_COMMON · 27e5203b
      Martin KaFai Lau 提交于
      This patch changes the bpf_sk_assign() to take
      ARG_PTR_TO_BTF_ID_SOCK_COMMON such that they will work with the pointer
      returned by the bpf_skc_to_*() helpers also.
      
      The bpf_sk_lookup_assign() is taking ARG_PTR_TO_SOCKET_"OR_NULL".  Meaning
      it specifically takes a literal NULL.  ARG_PTR_TO_BTF_ID_SOCK_COMMON
      does not allow a literal NULL, so another ARG type is required
      for this purpose and another follow-up patch can be used if
      there is such need.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000415.3857374-1-kafai@fb.com
      27e5203b
    • M
      bpf: Change bpf_tcp_*_syncookie to accept ARG_PTR_TO_BTF_ID_SOCK_COMMON · c0df236e
      Martin KaFai Lau 提交于
      This patch changes the bpf_tcp_*_syncookie() to take
      ARG_PTR_TO_BTF_ID_SOCK_COMMON such that they will work with the pointer
      returned by the bpf_skc_to_*() helpers also.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NLorenz Bauer <lmb@cloudflare.com>
      Link: https://lore.kernel.org/bpf/20200925000409.3856725-1-kafai@fb.com
      c0df236e
    • M
      bpf: Change bpf_sk_storage_*() to accept ARG_PTR_TO_BTF_ID_SOCK_COMMON · 592a3498
      Martin KaFai Lau 提交于
      This patch changes the bpf_sk_storage_*() to take
      ARG_PTR_TO_BTF_ID_SOCK_COMMON such that they will work with the pointer
      returned by the bpf_skc_to_*() helpers also.
      
      A micro benchmark has been done on a "cgroup_skb/egress" bpf program
      which does a bpf_sk_storage_get().  It was driven by netperf doing
      a 4096 connected UDP_STREAM test with 64bytes packet.
      The stats from "kernel.bpf_stats_enabled" shows no meaningful difference.
      
      The sk_storage_get_btf_proto, sk_storage_delete_btf_proto,
      btf_sk_storage_get_proto, and btf_sk_storage_delete_proto are
      no longer needed, so they are removed.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NLorenz Bauer <lmb@cloudflare.com>
      Link: https://lore.kernel.org/bpf/20200925000402.3856307-1-kafai@fb.com
      592a3498
    • M
      bpf: Change bpf_sk_release and bpf_sk_*cgroup_id to accept ARG_PTR_TO_BTF_ID_SOCK_COMMON · a5fa25ad
      Martin KaFai Lau 提交于
      The previous patch allows the networking bpf prog to use the
      bpf_skc_to_*() helpers to get a PTR_TO_BTF_ID socket pointer,
      e.g. "struct tcp_sock *".  It allows the bpf prog to read all the
      fields of the tcp_sock.
      
      This patch changes the bpf_sk_release() and bpf_sk_*cgroup_id()
      to take ARG_PTR_TO_BTF_ID_SOCK_COMMON such that they will
      work with the pointer returned by the bpf_skc_to_*() helpers
      also.  For example, the following will work:
      
      	sk = bpf_skc_lookup_tcp(skb, tuple, tuplen, BPF_F_CURRENT_NETNS, 0);
      	if (!sk)
      		return;
      	tp = bpf_skc_to_tcp_sock(sk);
      	if (!tp) {
      		bpf_sk_release(sk);
      		return;
      	}
      	lsndtime = tp->lsndtime;
      	/* Pass tp to bpf_sk_release() will also work */
      	bpf_sk_release(tp);
      
      Since PTR_TO_BTF_ID could be NULL, the helper taking
      ARG_PTR_TO_BTF_ID_SOCK_COMMON has to check for NULL at runtime.
      
      A btf_id of "struct sock" may not always mean a fullsock.  Regardless
      the helper's running context may get a non-fullsock or not,
      considering fullsock check/handling is pretty cheap, it is better to
      keep the same verifier expectation on helper that takes ARG_PTR_TO_BTF_ID*
      will be able to handle the minisock situation.  In the bpf_sk_*cgroup_id()
      case,  it will try to get a fullsock by using sk_to_full_sk() as its
      skb variant bpf_sk"b"_*cgroup_id() has already been doing.
      
      bpf_sk_release can already handle minisock, so nothing special has to
      be done.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20200925000356.3856047-1-kafai@fb.com
      a5fa25ad
    • M
      bpf: Enable bpf_skc_to_* sock casting helper to networking prog type · 1df8f55a
      Martin KaFai Lau 提交于
      There is a constant need to add more fields into the bpf_tcp_sock
      for the bpf programs running at tc, sock_ops...etc.
      
      A current workaround could be to use bpf_probe_read_kernel().  However,
      other than making another helper call for reading each field and missing
      CO-RE, it is also not as intuitive to use as directly reading
      "tp->lsndtime" for example.  While already having perfmon cap to do
      bpf_probe_read_kernel(), it will be much easier if the bpf prog can
      directly read from the tcp_sock.
      
      This patch tries to do that by using the existing casting-helpers
      bpf_skc_to_*() whose func_proto returns a btf_id.  For example, the
      func_proto of bpf_skc_to_tcp_sock returns the btf_id of the
      kernel "struct tcp_sock".
      
      These helpers are also added to is_ptr_cast_function().
      It ensures the returning reg (BPF_REF_0) will also carries the ref_obj_id.
      That will keep the ref-tracking works properly.
      
      The bpf_skc_to_* helpers are made available to most of the bpf prog
      types in filter.c. The bpf_skc_to_* helpers will be limited by
      perfmon cap.
      
      This patch adds a ARG_PTR_TO_BTF_ID_SOCK_COMMON.  The helper accepting
      this arg can accept a btf-id-ptr (PTR_TO_BTF_ID + &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON])
      or a legacy-ctx-convert-skc-ptr (PTR_TO_SOCK_COMMON).  The bpf_skc_to_*()
      helpers are changed to take ARG_PTR_TO_BTF_ID_SOCK_COMMON such that
      they will accept pointer obtained from skb->sk.
      
      Instead of specifying both arg_type and arg_btf_id in the same func_proto
      which is how the current ARG_PTR_TO_BTF_ID does, the arg_btf_id of
      the new ARG_PTR_TO_BTF_ID_SOCK_COMMON is specified in the
      compatible_reg_types[] in verifier.c.  The reason is the arg_btf_id is
      always the same.  Discussion in this thread:
      https://lore.kernel.org/bpf/20200922070422.1917351-1-kafai@fb.com/
      
      The ARG_PTR_TO_BTF_ID_ part gives a clear expectation that the helper is
      expecting a PTR_TO_BTF_ID which could be NULL.  This is the same
      behavior as the existing helper taking ARG_PTR_TO_BTF_ID.
      
      The _SOCK_COMMON part means the helper is also expecting the legacy
      SOCK_COMMON pointer.
      
      By excluding the _OR_NULL part, the bpf prog cannot call helper
      with a literal NULL which doesn't make sense in most cases.
      e.g. bpf_skc_to_tcp_sock(NULL) will be rejected.  All PTR_TO_*_OR_NULL
      reg has to do a NULL check first before passing into the helper or else
      the bpf prog will be rejected.  This behavior is nothing new and
      consistent with the current expectation during bpf-prog-load.
      
      [ ARG_PTR_TO_BTF_ID_SOCK_COMMON will be used to replace
        ARG_PTR_TO_SOCK* of other existing helpers later such that
        those existing helpers can take the PTR_TO_BTF_ID returned by
        the bpf_skc_to_*() helpers.
      
        The only special case is bpf_sk_lookup_assign() which can accept a
        literal NULL ptr.  It has to be handled specially in another follow
        up patch if there is a need (e.g. by renaming ARG_PTR_TO_SOCKET_OR_NULL
        to ARG_PTR_TO_BTF_ID_SOCK_COMMON_OR_NULL). ]
      
      [ When converting the older helpers that take ARG_PTR_TO_SOCK* in
        the later patch, if the kernel does not support BTF,
        ARG_PTR_TO_BTF_ID_SOCK_COMMON will behave like ARG_PTR_TO_SOCK_COMMON
        because no reg->type could have PTR_TO_BTF_ID in this case.
      
        It is not a concern for the newer-btf-only helper like the bpf_skc_to_*()
        here though because these helpers must require BTF vmlinux to begin
        with. ]
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20200925000350.3855720-1-kafai@fb.com
      1df8f55a
    • M
      bpf: Move the PTR_TO_BTF_ID check to check_reg_type() · a968d5e2
      Martin KaFai Lau 提交于
      check_reg_type() checks whether a reg can be used as an arg of a
      func_proto.  For PTR_TO_BTF_ID, the check is actually not
      completely done until the reg->btf_id is pointing to a
      kernel struct that is acceptable by the func_proto.
      
      Thus, this patch moves the btf_id check into check_reg_type().
      "arg_type" and "arg_btf_id" are passed to check_reg_type() instead of
      "compatible".  The compatible_reg_types[] usage is localized in
      check_reg_type() now.
      
      The "if (!btf_id) verbose(...); " is also removed since it won't happen.
      Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NLorenz Bauer <lmb@cloudflare.com>
      Acked-by: NJohn Fastabend <john.fastabend@gmail.com>
      Link: https://lore.kernel.org/bpf/20200925000344.3854828-1-kafai@fb.com
      a968d5e2