Skip to content

Commit

Permalink
net: add ulp_list
Browse files Browse the repository at this point in the history
Signed-off-by: Geliang Tang <[email protected]>
  • Loading branch information
Geliang Tang committed May 29, 2024
1 parent 4ae716e commit a66bf9f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
13 changes: 13 additions & 0 deletions include/net/inet_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ struct inet_connection_sock_af_ops {
* @icsk_probes_tstamp: Probe timestamp (cleared by non-zero window ack)
* @icsk_user_timeout: TCP_USER_TIMEOUT value
*/

struct icsk_ulp {
struct list_head list;
char name[16];
const struct tcp_ulp_ops *icsk_ulp_ops;
void __rcu *icsk_ulp_data;
};

struct inet_connection_sock {
/* inet_sock has to be the first member! */
struct inet_sock icsk_inet;
Expand All @@ -88,6 +96,8 @@ struct inet_connection_sock {
unsigned long icsk_timeout;
struct timer_list icsk_retransmit_timer;
struct timer_list icsk_delack_timer;
spinlock_t icsk_ulp_lock;
struct list_head icsk_ulp_list;
__u32 icsk_rto;
__u32 icsk_rto_min;
__u32 icsk_delack_max;
Expand Down Expand Up @@ -361,6 +371,9 @@ static inline void inet_init_csk_locks(struct sock *sk)

spin_lock_init(&icsk->icsk_accept_queue.rskq_lock);
spin_lock_init(&icsk->icsk_accept_queue.fastopenq.lock);

spin_lock_init(&icsk->icsk_ulp_lock);
INIT_LIST_HEAD(&icsk->icsk_ulp_list);
}

#endif /* _INET_CONNECTION_SOCK_H */
34 changes: 34 additions & 0 deletions net/ipv4/tcp_ulp.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,23 @@ void tcp_update_ulp(struct sock *sk, struct proto *proto,
icsk->icsk_ulp_ops->update(sk, proto, write_space);
}

static void free_ulp_list(struct list_head *list)
{
struct icsk_ulp *ulp;

while (!list_empty(list)) {
ulp = list_entry(list->next, struct icsk_ulp, list);
pr_info("%s ulp->name=%s\n", __func__, ulp->name);
ulp->icsk_ulp_ops = NULL;
list_del(&ulp->list);
kfree(ulp);
}
}

void tcp_cleanup_ulp(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
LIST_HEAD(free_list);

/* No sock_owned_by_me() check here as at the time the
* stack calls this function, the socket is dead and
Expand All @@ -120,6 +134,12 @@ void tcp_cleanup_ulp(struct sock *sk)
if (!icsk->icsk_ulp_ops)
return;

spin_lock_bh(&icsk->icsk_ulp_lock);
list_splice_init(&icsk->icsk_ulp_list, &free_list);
spin_unlock_bh(&icsk->icsk_ulp_lock);

free_ulp_list(&free_list);

if (icsk->icsk_ulp_ops->release)
icsk->icsk_ulp_ops->release(sk);
module_put(icsk->icsk_ulp_ops->owner);
Expand All @@ -130,6 +150,7 @@ void tcp_cleanup_ulp(struct sock *sk)
static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct icsk_ulp *ulp;
int err;

err = -EEXIST;
Expand All @@ -147,6 +168,19 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
if (err)
goto out_err;

ulp = kzalloc(sizeof(*ulp), GFP_ATOMIC);
if (!ulp) {
goto out_err;
}

strncpy(ulp->name, ulp_ops->name, 16);
ulp->icsk_ulp_ops = ulp_ops;
ulp->icsk_ulp_data = NULL;

spin_lock_bh(&icsk->icsk_ulp_lock);
list_add(&ulp->list, &icsk->icsk_ulp_list);
spin_unlock_bh(&icsk->icsk_ulp_lock);

icsk->icsk_ulp_ops = ulp_ops;
return 0;
out_err:
Expand Down
6 changes: 6 additions & 0 deletions net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,7 @@ static struct mptcp_subflow_context *subflow_create_ctx(struct sock *sk,
{
struct inet_connection_sock *icsk = inet_csk(sk);
struct mptcp_subflow_context *ctx;
//struct icsk_ulp *ulp;

ctx = kzalloc(sizeof(*ctx), priority);
if (!ctx)
Expand All @@ -1759,6 +1760,11 @@ static struct mptcp_subflow_context *subflow_create_ctx(struct sock *sk,
INIT_LIST_HEAD(&ctx->node);
INIT_LIST_HEAD(&ctx->delegated_node);

//spin_lock_bh(&icsk->icsk_ulp_lock);
//list_for_each_entry(ulp, &icsk->icsk_ulp_list, list) {
// pr_info("%s ulp->name=%s\n", __func__, ulp->name);
//}
//spin_unlock_bh(&icsk->icsk_ulp_lock);
pr_debug("subflow=%p", ctx);

ctx->tcp_sock = sk;
Expand Down

0 comments on commit a66bf9f

Please sign in to comment.