当前位置:网站首页>SYSCALL_ Define5 setsockopt code flow

SYSCALL_ Define5 setsockopt code flow

2022-06-24 21:24:00 already_ skb

SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
        char __user *, optval, int, optlen)
{
    int err, fput_needed;
    struct socket *sock;

    if (optlen < 0)
        return -EINVAL;

    sock = sockfd_lookup_light(fd, &err, &fput_needed);
    if (sock != NULL) {
        err = security_socket_setsockopt(sock, level, optname);
        if (err)
            goto out_put;

        if (level == SOL_SOCKET)
            err =
                sock_setsockopt(sock, level, optname, optval,
                        optlen);
        else
            err =
                sock->ops->setsockopt(sock, level, optname, optval,
                          optlen);
out_put:
        fput_light(sock->file, fput_needed);
    }
    return err;
}


const struct proto_ops inet_stream_ops = {
    .family           = PF_INET,
    .owner           = THIS_MODULE,
    .release       = inet_release,
    .bind           = inet_bind,
    .connect       = inet_stream_connect,
    .socketpair       = sock_no_socketpair,
    .accept           = inet_accept,
    .getname       = inet_getname,
    .poll           = tcp_poll,
    .ioctl           = inet_ioctl,
    .listen           = inet_listen,
    .shutdown       = inet_shutdown,
    .setsockopt       = sock_common_setsockopt,
    .getsockopt       = sock_common_getsockopt,
    

    err = -ENOBUFS;
    sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
    if (sk == NULL)
        goto out;    
    

    /*
 *    Set socket options on an inet socket.
 */
int sock_common_setsockopt(struct socket *sock, int level, int optname,
               char __user *optval, unsigned int optlen)
{
    struct sock *sk = sock->sk;

    //call tcp_prot setsockopt api
    return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}


int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
           unsigned int optlen)
{
    const struct inet_connection_sock *icsk = inet_csk(sk);

    //IP option handler
    if (level != SOL_TCP)
        return icsk->icsk_af_ops->setsockopt(sk, level, optname,
                             optval, optlen);
                             
    //TCP option handler
    return do_tcp_setsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(tcp_setsockopt);

原网站

版权声明
本文为[already_ skb]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202211315156124.html