linux net子系统-套接口层

套接口层框图


核心数据结构

struct socket
struct proto_ops
struct sock
struct proto

结构体之间的关系

结构体之间的关系


socket创建

注册struct net_proto_family与struct inet_protosw

static const struct net_proto_family inet_family_ops = {
    .family = PF_INET,
    .create = inet_create,
    .owner  = THIS_MODULE,
};

static struct inet_protosw inetsw_array[] =
{
    {
        .type =       SOCK_STREAM,
        .protocol =   IPPROTO_TCP,
        .prot =       &tcp_prot,
        .ops =        &inet_stream_ops,
        .no_check =   0,
        .flags =      INET_PROTOSW_PERMANENT |
                  INET_PROTOSW_ICSK,
    },

    {
        .type =       SOCK_DGRAM,
        .protocol =   IPPROTO_UDP,
        .prot =       &udp_prot,
        .ops =        &inet_dgram_ops,
        .no_check =   UDP_CSUM_DEFAULT,
        .flags =      INET_PROTOSW_PERMANENT,
       },

       {
        .type =       SOCK_DGRAM,
        .protocol =   IPPROTO_ICMP,
        .prot =       &ping_prot,
        .ops =        &inet_dgram_ops,
        .no_check =   UDP_CSUM_DEFAULT,
        .flags =      INET_PROTOSW_REUSE,
       },

       {
           .type =       SOCK_RAW,
           .protocol =   IPPROTO_IP,    /* wild card */
           .prot =       &raw_prot,
           .ops =        &inet_sockraw_ops,
           .no_check =   UDP_CSUM_DEFAULT,
           .flags =      INET_PROTOSW_REUSE,
       }
};
fs_initcall(inet_init);
        (void)sock_register(&inet_family_ops);

        for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
            inet_register_protosw(q);

在struct inet_protosw inetsw_array[]数组中的每个元素的struct proto_ops和struct proto都会被初始化,并且通过inet_register_protosw将数组中的每个元素注册到全局static struct list_head inetsw[SOCK_MAX];


sys_socket

sys_socket
    sock_create
        __sock_create
            struct socket *sock = sock_alloc
            //下面这个inet_create是之前通过sock_register注册的inet_family_ops中的create函数
            pf->create(net, sock, protocol) == inet_create
                //在inet_create这个函数中会将之前通过inet_register_protosw
                //注册的inetsw_array数组中的struct proto_ops和struct proto
                //分别赋值给struct socket和struct sock
                sock->ops = answer->ops
                struct sock *sk = sk_alloc
                sk->sk_prot = sk->sk_prot_create = answer->prot

struct proto_ops

对应tcp的struct proto_ops位于net/ipv4/af_inet.c

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,
    .sendmsg       = inet_sendmsg,
    .recvmsg       = inet_recvmsg,
    .mmap          = sock_no_mmap,
    .sendpage      = inet_sendpage,
    .splice_read       = tcp_splice_read,
};

sock_sendmsg

sock_sendmsg位于net/socket.c文件

sock_sendmsg
    __sock_sendmsg
        struct socket *sock;
        sock->ops->sendmsg //这个ops是struct socket结构体中的struct proto_ops
            inet_sendmsg
                struct sock *sk = sock->sk;
                sk->sk_prot->sendmsg //这个ops是struct sock结构体中的struct proto

sock_recvmsg

sock_recvmsg位于net/socket.c文件

sock_recvmsg
    __sock_recvmsg
        struct socket *sock;
        sock->ops->recvmsg //这个ops是struct socket结构体中的struct proto_ops
            sock_common_recvmsg
                struct sock *sk = sock->sk;
                sk->sk_prot->recvmsg //这个ops是struct sock结构体中的struct proto
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckywang1103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值