Message ID | 20241207173803.90744-2-kerneljasonxing@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net-timestamp: bpf extension to equip applications transparently | expand |
Hi Jason, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Jason-Xing/net-timestamp-add-support-for-bpf_setsockopt/20241208-014111 base: net-next/main patch link: https://lore.kernel.org/r/20241207173803.90744-2-kerneljasonxing%40gmail.com patch subject: [PATCH net-next v4 01/11] net-timestamp: add support for bpf_setsockopt() config: i386-buildonly-randconfig-001-20241208 (https://download.01.org/0day-ci/archive/20241208/202412080315.koZqiF0Y-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412080315.koZqiF0Y-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202412080315.koZqiF0Y-lkp@intel.com/ All errors (new ones prefixed by >>): net/core/filter.c: In function 'sk_bpf_set_cb_flags': >> net/core/filter.c:5232:11: error: 'struct sock' has no member named 'sk_bpf_cb_flags' 5232 | sk->sk_bpf_cb_flags = sk_bpf_cb_flags; | ^~ vim +5232 net/core/filter.c 5218 5219 static int sk_bpf_set_cb_flags(struct sock *sk, sockptr_t optval, bool getopt) 5220 { 5221 int sk_bpf_cb_flags; 5222 5223 if (getopt) 5224 return -EINVAL; 5225 5226 if (copy_from_sockptr(&sk_bpf_cb_flags, optval, sizeof(sk_bpf_cb_flags))) 5227 return -EFAULT; 5228 5229 if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK) 5230 return -EINVAL; 5231 > 5232 sk->sk_bpf_cb_flags = sk_bpf_cb_flags; 5233 5234 return 0; 5235 } 5236
Hi Jason, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Jason-Xing/net-timestamp-add-support-for-bpf_setsockopt/20241208-014111 base: net-next/main patch link: https://lore.kernel.org/r/20241207173803.90744-2-kerneljasonxing%40gmail.com patch subject: [PATCH net-next v4 01/11] net-timestamp: add support for bpf_setsockopt() config: x86_64-buildonly-randconfig-004-20241208 (https://download.01.org/0day-ci/archive/20241208/202412080629.IyOW2oUA-lkp@intel.com/config) compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241208/202412080629.IyOW2oUA-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202412080629.IyOW2oUA-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from net/core/filter.c:21: In file included from include/linux/bpf_verifier.h:7: In file included from include/linux/bpf.h:21: In file included from include/linux/kallsyms.h:13: In file included from include/linux/mm.h:2223: include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 518 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ net/core/filter.c:1726:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 1726 | .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:2041:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 2041 | .arg1_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ net/core/filter.c:2043:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 2043 | .arg3_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ net/core/filter.c:2580:35: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 2580 | .arg2_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ net/core/filter.c:4643:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 4643 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:4657:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 4657 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:4857:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 4857 | .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:4885:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 4885 | .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5057:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5057 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5071:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5071 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5120:45: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5120 | .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON | PTR_MAYBE_NULL, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~ >> net/core/filter.c:5232:6: error: no member named 'sk_bpf_cb_flags' in 'struct sock' 5232 | sk->sk_bpf_cb_flags = sk_bpf_cb_flags; | ~~ ^ net/core/filter.c:5577:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5577 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5611:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5611 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5645:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5645 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5679:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5679 | .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:5854:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 5854 | .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:6391:46: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 6391 | .arg3_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_WRITE | MEM_ALIGNED, | ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~ net/core/filter.c:6403:46: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 6403 | .arg3_type = ARG_PTR_TO_FIXED_SIZE_MEM | MEM_WRITE | MEM_ALIGNED, | ~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~ net/core/filter.c:6489:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 6489 | .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ net/core/filter.c:6499:30: warning: bitwise operation between different enumeration types ('enum bpf_arg_type' and 'enum bpf_type_flag') [-Wenum-enum-conversion] 6499 | .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, | ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ 21 warnings and 1 error generated. vim +5232 net/core/filter.c 5049 5050 static const struct bpf_func_proto bpf_xdp_event_output_proto = { 5051 .func = bpf_xdp_event_output, 5052 .gpl_only = true, 5053 .ret_type = RET_INTEGER, 5054 .arg1_type = ARG_PTR_TO_CTX, 5055 .arg2_type = ARG_CONST_MAP_PTR, 5056 .arg3_type = ARG_ANYTHING, > 5057 .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5058 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 5059 }; 5060 5061 BTF_ID_LIST_SINGLE(bpf_xdp_output_btf_ids, struct, xdp_buff) 5062 5063 const struct bpf_func_proto bpf_xdp_output_proto = { 5064 .func = bpf_xdp_event_output, 5065 .gpl_only = true, 5066 .ret_type = RET_INTEGER, 5067 .arg1_type = ARG_PTR_TO_BTF_ID, 5068 .arg1_btf_id = &bpf_xdp_output_btf_ids[0], 5069 .arg2_type = ARG_CONST_MAP_PTR, 5070 .arg3_type = ARG_ANYTHING, 5071 .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5072 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 5073 }; 5074 5075 BPF_CALL_1(bpf_get_socket_cookie, struct sk_buff *, skb) 5076 { 5077 return skb->sk ? __sock_gen_cookie(skb->sk) : 0; 5078 } 5079 5080 static const struct bpf_func_proto bpf_get_socket_cookie_proto = { 5081 .func = bpf_get_socket_cookie, 5082 .gpl_only = false, 5083 .ret_type = RET_INTEGER, 5084 .arg1_type = ARG_PTR_TO_CTX, 5085 }; 5086 5087 BPF_CALL_1(bpf_get_socket_cookie_sock_addr, struct bpf_sock_addr_kern *, ctx) 5088 { 5089 return __sock_gen_cookie(ctx->sk); 5090 } 5091 5092 static const struct bpf_func_proto bpf_get_socket_cookie_sock_addr_proto = { 5093 .func = bpf_get_socket_cookie_sock_addr, 5094 .gpl_only = false, 5095 .ret_type = RET_INTEGER, 5096 .arg1_type = ARG_PTR_TO_CTX, 5097 }; 5098 5099 BPF_CALL_1(bpf_get_socket_cookie_sock, struct sock *, ctx) 5100 { 5101 return __sock_gen_cookie(ctx); 5102 } 5103 5104 static const struct bpf_func_proto bpf_get_socket_cookie_sock_proto = { 5105 .func = bpf_get_socket_cookie_sock, 5106 .gpl_only = false, 5107 .ret_type = RET_INTEGER, 5108 .arg1_type = ARG_PTR_TO_CTX, 5109 }; 5110 5111 BPF_CALL_1(bpf_get_socket_ptr_cookie, struct sock *, sk) 5112 { 5113 return sk ? sock_gen_cookie(sk) : 0; 5114 } 5115 5116 const struct bpf_func_proto bpf_get_socket_ptr_cookie_proto = { 5117 .func = bpf_get_socket_ptr_cookie, 5118 .gpl_only = false, 5119 .ret_type = RET_INTEGER, 5120 .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON | PTR_MAYBE_NULL, 5121 }; 5122 5123 BPF_CALL_1(bpf_get_socket_cookie_sock_ops, struct bpf_sock_ops_kern *, ctx) 5124 { 5125 return __sock_gen_cookie(ctx->sk); 5126 } 5127 5128 static const struct bpf_func_proto bpf_get_socket_cookie_sock_ops_proto = { 5129 .func = bpf_get_socket_cookie_sock_ops, 5130 .gpl_only = false, 5131 .ret_type = RET_INTEGER, 5132 .arg1_type = ARG_PTR_TO_CTX, 5133 }; 5134 5135 static u64 __bpf_get_netns_cookie(struct sock *sk) 5136 { 5137 const struct net *net = sk ? sock_net(sk) : &init_net; 5138 5139 return net->net_cookie; 5140 } 5141 5142 BPF_CALL_1(bpf_get_netns_cookie, struct sk_buff *, skb) 5143 { 5144 return __bpf_get_netns_cookie(skb && skb->sk ? skb->sk : NULL); 5145 } 5146 5147 static const struct bpf_func_proto bpf_get_netns_cookie_proto = { 5148 .func = bpf_get_netns_cookie, 5149 .ret_type = RET_INTEGER, 5150 .arg1_type = ARG_PTR_TO_CTX_OR_NULL, 5151 }; 5152 5153 BPF_CALL_1(bpf_get_netns_cookie_sock, struct sock *, ctx) 5154 { 5155 return __bpf_get_netns_cookie(ctx); 5156 } 5157 5158 static const struct bpf_func_proto bpf_get_netns_cookie_sock_proto = { 5159 .func = bpf_get_netns_cookie_sock, 5160 .gpl_only = false, 5161 .ret_type = RET_INTEGER, 5162 .arg1_type = ARG_PTR_TO_CTX_OR_NULL, 5163 }; 5164 5165 BPF_CALL_1(bpf_get_netns_cookie_sock_addr, struct bpf_sock_addr_kern *, ctx) 5166 { 5167 return __bpf_get_netns_cookie(ctx ? ctx->sk : NULL); 5168 } 5169 5170 static const struct bpf_func_proto bpf_get_netns_cookie_sock_addr_proto = { 5171 .func = bpf_get_netns_cookie_sock_addr, 5172 .gpl_only = false, 5173 .ret_type = RET_INTEGER, 5174 .arg1_type = ARG_PTR_TO_CTX_OR_NULL, 5175 }; 5176 5177 BPF_CALL_1(bpf_get_netns_cookie_sock_ops, struct bpf_sock_ops_kern *, ctx) 5178 { 5179 return __bpf_get_netns_cookie(ctx ? ctx->sk : NULL); 5180 } 5181 5182 static const struct bpf_func_proto bpf_get_netns_cookie_sock_ops_proto = { 5183 .func = bpf_get_netns_cookie_sock_ops, 5184 .gpl_only = false, 5185 .ret_type = RET_INTEGER, 5186 .arg1_type = ARG_PTR_TO_CTX_OR_NULL, 5187 }; 5188 5189 BPF_CALL_1(bpf_get_netns_cookie_sk_msg, struct sk_msg *, ctx) 5190 { 5191 return __bpf_get_netns_cookie(ctx ? ctx->sk : NULL); 5192 } 5193 5194 static const struct bpf_func_proto bpf_get_netns_cookie_sk_msg_proto = { 5195 .func = bpf_get_netns_cookie_sk_msg, 5196 .gpl_only = false, 5197 .ret_type = RET_INTEGER, 5198 .arg1_type = ARG_PTR_TO_CTX_OR_NULL, 5199 }; 5200 5201 BPF_CALL_1(bpf_get_socket_uid, struct sk_buff *, skb) 5202 { 5203 struct sock *sk = sk_to_full_sk(skb->sk); 5204 kuid_t kuid; 5205 5206 if (!sk || !sk_fullsock(sk)) 5207 return overflowuid; 5208 kuid = sock_net_uid(sock_net(sk), sk); 5209 return from_kuid_munged(sock_net(sk)->user_ns, kuid); 5210 } 5211 5212 static const struct bpf_func_proto bpf_get_socket_uid_proto = { 5213 .func = bpf_get_socket_uid, 5214 .gpl_only = false, 5215 .ret_type = RET_INTEGER, 5216 .arg1_type = ARG_PTR_TO_CTX, 5217 }; 5218 5219 static int sk_bpf_set_cb_flags(struct sock *sk, sockptr_t optval, bool getopt) 5220 { 5221 int sk_bpf_cb_flags; 5222 5223 if (getopt) 5224 return -EINVAL; 5225 5226 if (copy_from_sockptr(&sk_bpf_cb_flags, optval, sizeof(sk_bpf_cb_flags))) 5227 return -EFAULT; 5228 5229 if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK) 5230 return -EINVAL; 5231 > 5232 sk->sk_bpf_cb_flags = sk_bpf_cb_flags; 5233 5234 return 0; 5235 } 5236
On 12/7/24 9:37 AM, Jason Xing wrote: > diff --git a/net/core/filter.c b/net/core/filter.c > index 6625b3f563a4..f7e9f88e09b1 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -5214,6 +5214,24 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = { > .arg1_type = ARG_PTR_TO_CTX, > }; > > +static int sk_bpf_set_cb_flags(struct sock *sk, sockptr_t optval, bool getopt) It is confusing to take a sockptr_t argument. It is called by the kernel bpf prog only. It must be from the kernel memory. Directly pass the "int sk_bpf_cb_flags" as the argument. > +{ > + int sk_bpf_cb_flags; > + > + if (getopt) > + return -EINVAL; > + > + if (copy_from_sockptr(&sk_bpf_cb_flags, optval, sizeof(sk_bpf_cb_flags))) It is an unnecessary copy. Directly use the "int sk_bpf_cb_flags" arg instead. > + return -EFAULT; This should never happen. > + > + if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK) > + return -EINVAL; > + > + sk->sk_bpf_cb_flags = sk_bpf_cb_flags; > + > + return 0; > +} > + > static int sol_socket_sockopt(struct sock *sk, int optname, > char *optval, int *optlen, > bool getopt) > @@ -5230,6 +5248,7 @@ static int sol_socket_sockopt(struct sock *sk, int optname, > case SO_MAX_PACING_RATE: > case SO_BINDTOIFINDEX: > case SO_TXREHASH: > + case SK_BPF_CB_FLAGS: > if (*optlen != sizeof(int)) > return -EINVAL; > break; > @@ -5239,6 +5258,9 @@ static int sol_socket_sockopt(struct sock *sk, int optname, > return -EINVAL; > } > > + if (optname == SK_BPF_CB_FLAGS) > + return sk_bpf_set_cb_flags(sk, KERNEL_SOCKPTR(optval), getopt); > + > if (getopt) { > if (optname == SO_BINDTODEVICE) > return -EINVAL;
On Fri, Dec 13, 2024 at 3:35 AM Martin KaFai Lau <martin.lau@linux.dev> wrote: > > On 12/7/24 9:37 AM, Jason Xing wrote: > > diff --git a/net/core/filter.c b/net/core/filter.c > > index 6625b3f563a4..f7e9f88e09b1 100644 > > --- a/net/core/filter.c > > +++ b/net/core/filter.c > > @@ -5214,6 +5214,24 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = { > > .arg1_type = ARG_PTR_TO_CTX, > > }; > > > > +static int sk_bpf_set_cb_flags(struct sock *sk, sockptr_t optval, bool getopt) > > It is confusing to take a sockptr_t argument. It is called by the kernel bpf > prog only. It must be from the kernel memory. Directly pass the "int > sk_bpf_cb_flags" as the argument. Thanks. I will fix this. > > > +{ > > + int sk_bpf_cb_flags; > > + > > + if (getopt) > > + return -EINVAL; > > + > > + if (copy_from_sockptr(&sk_bpf_cb_flags, optval, sizeof(sk_bpf_cb_flags))) > > It is an unnecessary copy. Directly use the "int sk_bpf_cb_flags" arg instead. > > > + return -EFAULT; > > This should never happen. > > > + > > + if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK) > > + return -EINVAL; > > + > > + sk->sk_bpf_cb_flags = sk_bpf_cb_flags; > > + > > + return 0; > > +} > > + > > static int sol_socket_sockopt(struct sock *sk, int optname, > > char *optval, int *optlen, > > bool getopt) > > @@ -5230,6 +5248,7 @@ static int sol_socket_sockopt(struct sock *sk, int optname, > > case SO_MAX_PACING_RATE: > > case SO_BINDTOIFINDEX: > > case SO_TXREHASH: > > + case SK_BPF_CB_FLAGS: > > if (*optlen != sizeof(int)) > > return -EINVAL; > > break; > > @@ -5239,6 +5258,9 @@ static int sol_socket_sockopt(struct sock *sk, int optname, > > return -EINVAL; > > } > > > > + if (optname == SK_BPF_CB_FLAGS) > > + return sk_bpf_set_cb_flags(sk, KERNEL_SOCKPTR(optval), getopt); > > + > > if (getopt) { > > if (optname == SO_BINDTODEVICE) > > return -EINVAL;
diff --git a/include/net/sock.h b/include/net/sock.h index 7464e9f9f47c..0dd464ba9e46 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -303,6 +303,7 @@ struct sk_filter; * @sk_stamp: time stamp of last packet received * @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only * @sk_tsflags: SO_TIMESTAMPING flags + * @sk_bpf_cb_flags: used for bpf_setsockopt * @sk_use_task_frag: allow sk_page_frag() to use current->task_frag. * Sockets that can be used under memory reclaim should * set this to false. @@ -445,6 +446,12 @@ struct sock { u32 sk_reserved_mem; int sk_forward_alloc; u32 sk_tsflags; +#ifdef CONFIG_BPF_SYSCALL +#define SK_BPF_CB_FLAG_TEST(SK, FLAG) ((SK)->sk_bpf_cb_flags & (FLAG)) + u32 sk_bpf_cb_flags; +#else +#define SK_BPF_CB_FLAG_TEST(SK, FLAG) 0 +#endif __cacheline_group_end(sock_write_rxtx); __cacheline_group_begin(sock_write_tx); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 4162afc6b5d0..e629e09b0b31 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -6903,6 +6903,13 @@ enum { BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7F, }; +/* Definitions for bpf_sk_cb_flags */ +enum { + SK_BPF_CB_TX_TIMESTAMPING = 1<<0, + SK_BPF_CB_MASK = (SK_BPF_CB_TX_TIMESTAMPING - 1) | + SK_BPF_CB_TX_TIMESTAMPING +}; + /* List of known BPF sock_ops operators. * New entries can only be added at the end */ @@ -7081,6 +7088,7 @@ enum { TCP_BPF_SYN_IP = 1006, /* Copy the IP[46] and TCP header */ TCP_BPF_SYN_MAC = 1007, /* Copy the MAC, IP[46], and TCP header */ TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */ + SK_BPF_CB_FLAGS = 1009, /* Used to set socket bpf flags */ }; enum { diff --git a/net/core/filter.c b/net/core/filter.c index 6625b3f563a4..f7e9f88e09b1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -5214,6 +5214,24 @@ static const struct bpf_func_proto bpf_get_socket_uid_proto = { .arg1_type = ARG_PTR_TO_CTX, }; +static int sk_bpf_set_cb_flags(struct sock *sk, sockptr_t optval, bool getopt) +{ + int sk_bpf_cb_flags; + + if (getopt) + return -EINVAL; + + if (copy_from_sockptr(&sk_bpf_cb_flags, optval, sizeof(sk_bpf_cb_flags))) + return -EFAULT; + + if (sk_bpf_cb_flags & ~SK_BPF_CB_MASK) + return -EINVAL; + + sk->sk_bpf_cb_flags = sk_bpf_cb_flags; + + return 0; +} + static int sol_socket_sockopt(struct sock *sk, int optname, char *optval, int *optlen, bool getopt) @@ -5230,6 +5248,7 @@ static int sol_socket_sockopt(struct sock *sk, int optname, case SO_MAX_PACING_RATE: case SO_BINDTOIFINDEX: case SO_TXREHASH: + case SK_BPF_CB_FLAGS: if (*optlen != sizeof(int)) return -EINVAL; break; @@ -5239,6 +5258,9 @@ static int sol_socket_sockopt(struct sock *sk, int optname, return -EINVAL; } + if (optname == SK_BPF_CB_FLAGS) + return sk_bpf_set_cb_flags(sk, KERNEL_SOCKPTR(optval), getopt); + if (getopt) { if (optname == SO_BINDTODEVICE) return -EINVAL; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4162afc6b5d0..6b0a5b787b12 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -7081,6 +7081,7 @@ enum { TCP_BPF_SYN_IP = 1006, /* Copy the IP[46] and TCP header */ TCP_BPF_SYN_MAC = 1007, /* Copy the MAC, IP[46], and TCP header */ TCP_BPF_SOCK_OPS_CB_FLAGS = 1008, /* Get or Set TCP sock ops flags */ + SK_BPF_CB_FLAGS = 1009, /* Used to set socket bpf flags */ }; enum {