inet——proto基本数据结构图

结构体 inet_protosw ,代表了socket的类型(套接字类型和相应的协议):

/* This is used to register socket interfaces for IP protocols.  */
struct inet_protosw {
	struct list_head list;

        /* These two fields form the lookup key.  */
	unsigned short	 type;	   /* This is the 2nd argument to socket(2). */
	unsigned short	 protocol; /* This is the L4 protocol number.  */

	struct proto	 *prot;
	const struct proto_ops *ops;
  
	unsigned char	 flags;      /* See INET_PROTOSW_* below.  */
};

初始化结构体inet_protosw 的静态数组,总共有4个元素:


/* 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,
		.flags =      INET_PROTOSW_PERMANENT |
			      INET_PROTOSW_ICSK,
	},

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

       {
		.type =       SOCK_DGRAM,
		.protocol =   IPPROTO_ICMP,
		.prot =       &ping_prot,
		.ops =        &inet_sockraw_ops,
		.flags =      INET_PROTOSW_REUSE,
       },

       {
	       .type =       SOCK_RAW,
	       .protocol =   IPPROTO_IP,	/* wild card */
	       .prot =       &raw_prot,
	       .ops =        &inet_sockraw_ops,
	       .flags =      INET_PROTOSW_REUSE,
       }
};

把这个数组中的静态变量注册进数组inetsw,这是一个通过list组织起来的数据结构。虽然代码有点多,但是功能很简单。

static struct list_head inetsw[SOCK_MAX];

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);
}

函数inet_register_protosw的作用是向inetsw里面添加元素。

1.	void inet_register_protosw(struct inet_protosw *p)  
2.	{  
3.	    struct list_head *lh;  
4.	    struct inet_protosw *answer;  
5.	    int protocol = p->protocol;  
6.	    struct list_head *last_perm;  
7.	  
8.	    printk("[%s %d] p->type: %d. protocol: %d .\n",   
9.	            __func__, __LINE__, p->type, protocol);  
10.	    dump_stack();  
11.	  
12.	    spin_lock_bh(&inetsw_lock);  
13.	  
14.	    if (p->type >= SOCK_MAX)  
15.	        goto out_illegal;  
16.	  
17.	    /* If we are trying to override a permanent protocol, bail. */  
18.	    last_perm = &inetsw[p->type];  
19.	    list_for_each(lh, &inetsw[p->type]) {  
20.	        answer = list_entry(lh, struct inet_protosw, list);  //container of
21.	        /* Check only the non-wild match. */  
22.	        if ((INET_PROTOSW_PERMANENT & answer->flags) == 0)  
23.	            break;  
24.	        if (protocol == answer->protocol)  
25.	            goto out_permanent;  
26.	        last_perm = lh;  
27.	    }  
28.	  
29.	    /* Add the new entry after the last permanent entry if any, so that 
30.	     * the new entry does not override a permanent entry when matched with 
31.	     * a wild-card protocol. But it is allowed to override any existing 
32.	     * non-permanent entry.  This means that when we remove this entry, the 
33.	     * system automatically returns to the old behavior. 
34.	     */  
35.	    list_add_rcu(&p->list, last_perm);  
36.	out:  
37.	    spin_unlock_bh(&inetsw_lock);  
38.	  
39.	    return;  
40.	  
41.	out_permanent:  
42.	    pr_err("Attempt to override permanent protocol %d\n", protocol);  
43.	    goto out;  
44.	  
45.	out_illegal:  
46.	    pr_err("Ignoring attempt to register invalid socket type %d\n",  
47.	           p->type);  
48.	    goto out;  
49.	}  
50.	EXPORT_SYMBOL(inet_register_protosw);  

 

 

猜你喜欢

转载自blog.csdn.net/yinming4u/article/details/84189211