使用socket(AF_INET, SOCK_STREAM, 0)创建socket
struct proto tcp_prot = {
.name = "TCP",
......
.init = tcp_v4_init_sock,
......
};
/* NOTE: A lot of things set to zero explicitly by call to
* sk_alloc() so need not be done here.
*/
static int tcp_v4_init_sock(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
tcp_init_sock(sk);
icsk->icsk_af_ops = &ipv4_specific;
......
}
/* Upon startup we insert all the elements in inetsw_array[] into
* the linked list inetsw.
*/
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_RAW,
.protocol = IPPROTO_IP, /* wild card */
.prot = &raw_prot,
.ops = &inet_sockraw_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
}
};
static int __init inet_init(void)
{
......
/* Register the socket-side information for inet_create. */
for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)
INIT_LIST_HEAD(r);
for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)
inet_register_protosw(q);
.....
}
static const struct net_proto_family inet_family_ops = {
.family = PF_INET,
.create = inet_create,
.owner = THIS_MODULE,
};
static int inet_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
......
list_for_each_entry_rcu(answer, &inetsw[sock->type], list){......}
......
sock->ops = answer->ops;
answer_prot = answer->prot;
......
sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
......
if (sk->sk_prot->init)
err = sk->sk_prot->init(sk);
......
}
---------------------------------------------------------------------------
sys_socket():
#define AF_INET 2 /* Internet IP Protocol */
#define PF_INET AF_INET //include.h/linux/socket.h
1.sys_socket()
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
int retval;
struct socket *sock;
int flags;
......
retval = sock_create(family, type, protocol, &sock);
if (retval < 0)
goto out;
retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));
......
}
2.sock_create()
int sock_create(int family, int type, int protocol, struct socket **res)
{
return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
}
EXPORT_SYMBOL(sock_create);
int __sock_create(struct net *net, int family, int type, int protocol,
struct socket **res, int kern)
{
......
/*
* Allocate the socket and allow the family to set things up. if
* the protocol is 0, the family is instructed to select an appropriate
* default.
*/
sock = sock_alloc();
sock->type = type;
......
pf = rcu_dereference(net_families[family]);
err = pf->create(net, sock, protocol, kern);
......
}
Note:三组操作数组:
1.struct proto_ops //socket
2.struct proto //sock
3.struct inet_connection_sock_af_ops //inet_connection_sock
阅读(5562) | 评论(0) | 转发(0) |