@@ -1654,15 +1654,24 @@ int sk_reuseport_attach_bpf(u32 ufd, struct sock *sk)
16541654 return err ;
16551655}
16561656
1657+ static void sk_reuseport_prog_free_rcu (struct rcu_head * rcu )
1658+ {
1659+ struct bpf_prog_aux * aux = container_of (rcu , struct bpf_prog_aux , rcu );
1660+ struct bpf_prog * prog = aux -> prog ;
1661+
1662+ bpf_release_orig_filter (prog );
1663+ bpf_prog_free (prog );
1664+ }
1665+
16571666void sk_reuseport_prog_free (struct bpf_prog * prog )
16581667{
16591668 if (!prog )
16601669 return ;
16611670
1662- if (prog -> type == BPF_PROG_TYPE_SK_REUSEPORT )
1663- bpf_prog_put ( prog );
1671+ if (bpf_prog_was_classic ( prog ) )
1672+ call_rcu ( & prog -> aux -> rcu , sk_reuseport_prog_free_rcu );
16641673 else
1665- bpf_prog_destroy (prog );
1674+ bpf_prog_put (prog );
16661675}
16671676
16681677static inline int __bpf_try_make_writable (struct sk_buff * skb ,
@@ -5481,7 +5490,7 @@ static int sol_tcp_sockopt(struct sock *sk, int optname,
54815490 char * optval , int * optlen ,
54825491 bool getopt )
54835492{
5484- if (sk -> sk_protocol != IPPROTO_TCP )
5493+ if (! sk_is_tcp ( sk ) )
54855494 return - EINVAL ;
54865495
54875496 switch (optname ) {
@@ -5688,6 +5697,30 @@ const struct bpf_func_proto bpf_sk_getsockopt_proto = {
56885697 .arg5_type = ARG_CONST_SIZE ,
56895698};
56905699
5700+ BPF_CALL_5 (bpf_sk_setsockopt_nodelay , struct sock * , sk , int , level ,
5701+ int , optname , char * , optval , int , optlen )
5702+ {
5703+ /*
5704+ * TCP_NODELAY triggers tcp_push_pending_frames() and re-enters
5705+ * CA_EVENT_TX_START in bpf_tcp_cc.
5706+ */
5707+ if (level == SOL_TCP && optname == TCP_NODELAY )
5708+ return - EOPNOTSUPP ;
5709+
5710+ return _bpf_setsockopt (sk , level , optname , optval , optlen );
5711+ }
5712+
5713+ const struct bpf_func_proto bpf_sk_setsockopt_nodelay_proto = {
5714+ .func = bpf_sk_setsockopt_nodelay ,
5715+ .gpl_only = false,
5716+ .ret_type = RET_INTEGER ,
5717+ .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON ,
5718+ .arg2_type = ARG_ANYTHING ,
5719+ .arg3_type = ARG_ANYTHING ,
5720+ .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY ,
5721+ .arg5_type = ARG_CONST_SIZE ,
5722+ };
5723+
56915724BPF_CALL_5 (bpf_unlocked_sk_setsockopt , struct sock * , sk , int , level ,
56925725 int , optname , char * , optval , int , optlen )
56935726{
@@ -5833,6 +5866,12 @@ BPF_CALL_5(bpf_sock_ops_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
58335866 if (!is_locked_tcp_sock_ops (bpf_sock ))
58345867 return - EOPNOTSUPP ;
58355868
5869+ /* TCP_NODELAY triggers tcp_push_pending_frames() and re-enters these callbacks. */
5870+ if ((bpf_sock -> op == BPF_SOCK_OPS_HDR_OPT_LEN_CB ||
5871+ bpf_sock -> op == BPF_SOCK_OPS_WRITE_HDR_OPT_CB ) &&
5872+ level == SOL_TCP && optname == TCP_NODELAY )
5873+ return - EOPNOTSUPP ;
5874+
58365875 return _bpf_setsockopt (bpf_sock -> sk , level , optname , optval , optlen );
58375876}
58385877
@@ -6443,6 +6482,8 @@ BPF_CALL_4(bpf_skb_fib_lookup, struct sk_buff *, skb,
64436482 * against MTU of FIB lookup resulting net_device
64446483 */
64456484 dev = dev_get_by_index_rcu (net , params -> ifindex );
6485+ if (unlikely (!dev ))
6486+ return - ENODEV ;
64466487 if (!is_skb_forwardable (dev , skb ))
64476488 rc = BPF_FIB_LKUP_RET_FRAG_NEEDED ;
64486489
@@ -7443,7 +7484,7 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
74437484
74447485BPF_CALL_1 (bpf_tcp_sock , struct sock * , sk )
74457486{
7446- if (sk_fullsock (sk ) && sk -> sk_protocol == IPPROTO_TCP )
7487+ if (sk_fullsock (sk ) && sk_is_tcp ( sk ) )
74477488 return (unsigned long )sk ;
74487489
74497490 return (unsigned long )NULL ;
@@ -11915,7 +11956,7 @@ BPF_CALL_1(bpf_skc_to_tcp6_sock, struct sock *, sk)
1191511956 */
1191611957 BTF_TYPE_EMIT (struct tcp6_sock );
1191711958 if (sk && sk_fullsock (sk ) && sk -> sk_protocol == IPPROTO_TCP &&
11918- sk -> sk_family == AF_INET6 )
11959+ sk -> sk_type == SOCK_STREAM && sk -> sk_family == AF_INET6 )
1191911960 return (unsigned long )sk ;
1192011961
1192111962 return (unsigned long )NULL ;
@@ -11931,7 +11972,7 @@ const struct bpf_func_proto bpf_skc_to_tcp6_sock_proto = {
1193111972
1193211973BPF_CALL_1 (bpf_skc_to_tcp_sock , struct sock * , sk )
1193311974{
11934- if (sk && sk_fullsock (sk ) && sk -> sk_protocol == IPPROTO_TCP )
11975+ if (sk && sk_fullsock (sk ) && sk_is_tcp ( sk ) )
1193511976 return (unsigned long )sk ;
1193611977
1193711978 return (unsigned long )NULL ;
0 commit comments