diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 91668b1cd3d1745b87bdec68870a4a4660ee2b0f..7f500a230757d2b8af34f138ca9e745f2d2dc86e 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -240,10 +240,11 @@ struct inet_sock { nodefrag:1; __u8 bind_address_no_port:1, recverr_rfc4884:1, - defer_connect:1; /* Indicates that fastopen_connect is set + defer_connect:1, /* Indicates that fastopen_connect is set * and cookie exists so we defer connect * until first data frame is written */ + bpf_defer_connect:1; __u8 rcv_tos; __u8 convert_csum; int uc_index; diff --git a/include/trace/events/sock.h b/include/trace/events/sock.h index 905b151bc3dd9a7ac865b0595f1d3739d9bf2f9c..841627e153148b6461a99a3baa6d9a80f52bb93c 100644 --- a/include/trace/events/sock.h +++ b/include/trace/events/sock.h @@ -203,6 +203,20 @@ TRACE_EVENT(inet_sock_set_state, show_tcp_state_name(__entry->newstate)) ); +#undef NET_DECLARE_TRACE +#ifdef DECLARE_TRACE_WRITABLE +#define NET_DECLARE_TRACE(call, proto, args, size) \ + DECLARE_TRACE_WRITABLE(call, PARAMS(proto), PARAMS(args), size) +#else +#define NET_DECLARE_TRACE(call, proto, args, size) \ + DECLARE_TRACE(call, PARAMS(proto), PARAMS(args)) +#endif + +NET_DECLARE_TRACE(connect_ret, + TP_PROTO(int *err), + TP_ARGS(err), + sizeof(int)); + #endif /* _TRACE_SOCK_H */ /* This part must be outside protection */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 9e64dac44d606d484f6350509c984668a9b35e26..79d5e5850bf60b670500bda621ba28496802de2e 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -4872,6 +4872,7 @@ enum { * by the kernel or the * earlier bpf-progs. */ + BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB,/* call ebpf to defer connect*/ }; /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect diff --git a/net/core/filter.c b/net/core/filter.c index 012a5070a9e578b1f39153fc941f2692ba339c01..904f65aa2f14cd17fd34a8eacb5234f24160fa3f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4837,6 +4837,13 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, TCP_CA_NAME_MAX-1)); name[TCP_CA_NAME_MAX-1] = 0; ret = tcp_set_congestion_control(sk, name, false, true); + } else if (optname == TCP_ULP) { + char name[TCP_ULP_NAME_MAX]; + + strncpy(name, optval, min_t(long, optlen, + TCP_ULP_NAME_MAX - 1)); + name[TCP_ULP_NAME_MAX - 1] = 0; + return tcp_set_ulp(sk, name); } else { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 4ddbfccfd0c86ba0582272318cee14cdfda0541d..6c9b39e96592f27515da1d5f00b788e35527eb82 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -729,6 +729,7 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, lock_sock(sock->sk); err = __inet_stream_connect(sock, uaddr, addr_len, flags, 0); release_sock(sock->sk); + trace_connect_ret(&err); return err; } EXPORT_SYMBOL(inet_stream_connect); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e7ac3555d7982faaf35bab29040da1eb07d9f3b4..c687995f64b6aceaa14280f060e0f50138c0f567 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -590,7 +590,8 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) if (tp->urg_data & TCP_URG_VALID) mask |= EPOLLPRI; - } else if (state == TCP_SYN_SENT && inet_sk(sk)->defer_connect) { + } else if (state == TCP_SYN_SENT && + (inet_sk(sk)->defer_connect || inet_sk(sk)->bpf_defer_connect)) { /* Active TCP fastopen socket with defer_connect * Return EPOLLOUT so application can call write() * in order for kernel to generate SYN+data diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index abf8023d606b631966d3a0f1d848c735fad73e1a..807232f0c7e086f2ff0b0872a2fc738b9dab4422 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -4872,6 +4872,7 @@ enum { * by the kernel or the * earlier bpf-progs. */ + BPF_SOCK_OPS_TCP_DEFER_CONNECT_CB,/* call ebpf to defer connect*/ }; /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect