⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Socket operations.  */struct proto_ops inet_seqpacket_ops = {	.family      = PF_INET,	.owner       = THIS_MODULE,	.release     = inet_release,       /* Needs to be wrapped... */	.bind        = inet_bind,	.connect     = inet_dgram_connect,	.socketpair  = sock_no_socketpair,	.accept      = inet_accept,	.getname     = inet_getname,      /* Semantics are different.  */	.poll        = sctp_poll,	.ioctl       = inet_ioctl,	.listen      = sctp_inet_listen,	.shutdown    = inet_shutdown,     /* Looks harmless.  */	.setsockopt  = sock_common_setsockopt,   /* IP_SOL IP_OPTION is a problem. */	.getsockopt  = sock_common_getsockopt,	.sendmsg     = inet_sendmsg,	.recvmsg     = sock_common_recvmsg,	.mmap        = sock_no_mmap,	.sendpage    = sock_no_sendpage,};/* Registration with AF_INET family.  */static struct inet_protosw sctp_seqpacket_protosw = {	.type       = SOCK_SEQPACKET,	.protocol   = IPPROTO_SCTP,	.prot       = &sctp_prot,	.ops        = &inet_seqpacket_ops,	.capability = -1,	.no_check   = 0,	.flags      = SCTP_PROTOSW_FLAG};static struct inet_protosw sctp_stream_protosw = {	.type       = SOCK_STREAM,	.protocol   = IPPROTO_SCTP,	.prot       = &sctp_prot,	.ops        = &inet_seqpacket_ops,	.capability = -1,	.no_check   = 0,	.flags      = SCTP_PROTOSW_FLAG};/* Register with IP layer.  */static struct net_protocol sctp_protocol = {	.handler     = sctp_rcv,	.err_handler = sctp_v4_err,	.no_policy   = 1,};/* IPv4 address related functions.  */struct sctp_af sctp_ipv4_specific = {	.sctp_xmit      = sctp_v4_xmit,	.setsockopt     = ip_setsockopt,	.getsockopt     = ip_getsockopt,	.get_dst	= sctp_v4_get_dst,	.get_saddr	= sctp_v4_get_saddr,	.copy_addrlist  = sctp_v4_copy_addrlist,	.from_skb       = sctp_v4_from_skb,	.from_sk        = sctp_v4_from_sk,	.to_sk_saddr    = sctp_v4_to_sk_saddr,	.to_sk_daddr    = sctp_v4_to_sk_daddr,	.from_addr_param= sctp_v4_from_addr_param,	.to_addr_param  = sctp_v4_to_addr_param,		.dst_saddr      = sctp_v4_dst_saddr,	.cmp_addr       = sctp_v4_cmp_addr,	.addr_valid     = sctp_v4_addr_valid,	.inaddr_any     = sctp_v4_inaddr_any,	.is_any         = sctp_v4_is_any,	.available      = sctp_v4_available,	.scope          = sctp_v4_scope,	.skb_iif        = sctp_v4_skb_iif,	.is_ce          = sctp_v4_is_ce,	.seq_dump_addr  = sctp_v4_seq_dump_addr,	.net_header_len = sizeof(struct iphdr),	.sockaddr_len   = sizeof(struct sockaddr_in),	.sa_family      = AF_INET,};struct sctp_pf *sctp_get_pf_specific(sa_family_t family) {	switch (family) {	case PF_INET:		return sctp_pf_inet_specific;	case PF_INET6:		return sctp_pf_inet6_specific;	default:		return NULL;	}}/* Register the PF specific function table.  */int sctp_register_pf(struct sctp_pf *pf, sa_family_t family){	switch (family) {	case PF_INET:		if (sctp_pf_inet_specific)			return 0;		sctp_pf_inet_specific = pf;		break;	case PF_INET6:		if (sctp_pf_inet6_specific)			return 0;		sctp_pf_inet6_specific = pf;		break;	default:		return 0;	}	return 1;}static int __init init_sctp_mibs(void){	sctp_statistics[0] = alloc_percpu(struct sctp_mib);	if (!sctp_statistics[0])		return -ENOMEM;	sctp_statistics[1] = alloc_percpu(struct sctp_mib);	if (!sctp_statistics[1]) {		free_percpu(sctp_statistics[0]);		return -ENOMEM;	}	return 0;}static void cleanup_sctp_mibs(void){	free_percpu(sctp_statistics[0]);	free_percpu(sctp_statistics[1]);}/* Initialize the universe into something sensible.  */__init int sctp_init(void){	int i;	int status = -EINVAL;	unsigned long goal;	int order;	/* SCTP_DEBUG sanity check. */	if (!sctp_sanity_check())		goto out;	status = sk_alloc_slab(&sctp_prot, "sctp_sock");	if (status)		goto out;	/* Add SCTP to inet_protos hash table.  */	status = -EAGAIN;	if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)		goto err_add_protocol;	/* Add SCTP(TCP and UDP style) to inetsw linked list.  */	inet_register_protosw(&sctp_seqpacket_protosw);	inet_register_protosw(&sctp_stream_protosw);	/* Allocate a cache pools. */	status = -ENOBUFS;	sctp_bucket_cachep = kmem_cache_create("sctp_bind_bucket",					       sizeof(struct sctp_bind_bucket),					       0, SLAB_HWCACHE_ALIGN,					       NULL, NULL);	if (!sctp_bucket_cachep)		goto err_bucket_cachep;	sctp_chunk_cachep = kmem_cache_create("sctp_chunk",					       sizeof(struct sctp_chunk),					       0, SLAB_HWCACHE_ALIGN,					       NULL, NULL);	if (!sctp_chunk_cachep)		goto err_chunk_cachep;	/* Allocate and initialise sctp mibs.  */	status = init_sctp_mibs();	if (status)		goto err_init_mibs;	/* Initialize proc fs directory.  */	status = sctp_proc_init();	if (status)		goto err_init_proc;	/* Initialize object count debugging.  */	sctp_dbg_objcnt_init();	/* Initialize the SCTP specific PF functions. */	sctp_register_pf(&sctp_pf_inet, PF_INET);	/*	 * 14. Suggested SCTP Protocol Parameter Values	 */	/* The following protocol parameters are RECOMMENDED:  */	/* RTO.Initial              - 3  seconds */	sctp_rto_initial		= SCTP_RTO_INITIAL;	/* RTO.Min                  - 1  second */	sctp_rto_min	 		= SCTP_RTO_MIN;	/* RTO.Max                 -  60 seconds */	sctp_rto_max 			= SCTP_RTO_MAX;	/* RTO.Alpha                - 1/8 */	sctp_rto_alpha	        	= SCTP_RTO_ALPHA;	/* RTO.Beta                 - 1/4 */	sctp_rto_beta			= SCTP_RTO_BETA;	/* Valid.Cookie.Life        - 60  seconds */	sctp_valid_cookie_life		= 60 * HZ;	/* Whether Cookie Preservative is enabled(1) or not(0) */	sctp_cookie_preserve_enable 	= 1;	/* Max.Burst		    - 4 */	sctp_max_burst 			= SCTP_MAX_BURST;	/* Association.Max.Retrans  - 10 attempts	 * Path.Max.Retrans         - 5  attempts (per destination address)	 * Max.Init.Retransmits     - 8  attempts	 */	sctp_max_retrans_association 	= 10;	sctp_max_retrans_path		= 5;	sctp_max_retrans_init		= 8;	/* HB.interval              - 30 seconds */	sctp_hb_interval		= 30 * HZ;	/* Implementation specific variables. */	/* Initialize default stream count setup information. */	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;	/* Initialize handle used for association ids. */	idr_init(&sctp_assocs_id);	/* Size and allocate the association hash table.	 * The methodology is similar to that of the tcp hash tables.	 */	if (num_physpages >= (128 * 1024))		goal = num_physpages >> (22 - PAGE_SHIFT);	else		goal = num_physpages >> (24 - PAGE_SHIFT);	for (order = 0; (1UL << order) < goal; order++)		;	do {		sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /					sizeof(struct sctp_hashbucket);		if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)			continue;		sctp_assoc_hashtable = (struct sctp_hashbucket *)					__get_free_pages(GFP_ATOMIC, order);	} while (!sctp_assoc_hashtable && --order > 0);	if (!sctp_assoc_hashtable) {		printk(KERN_ERR "SCTP: Failed association hash alloc.\n");		status = -ENOMEM;		goto err_ahash_alloc;	}	for (i = 0; i < sctp_assoc_hashsize; i++) {		sctp_assoc_hashtable[i].lock = RW_LOCK_UNLOCKED;		sctp_assoc_hashtable[i].chain = NULL;	}	/* Allocate and initialize the endpoint hash table.  */	sctp_ep_hashsize = 64;	sctp_ep_hashtable = (struct sctp_hashbucket *)		kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL);	if (!sctp_ep_hashtable) {		printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n");		status = -ENOMEM;		goto err_ehash_alloc;	}	for (i = 0; i < sctp_ep_hashsize; i++) {		sctp_ep_hashtable[i].lock = RW_LOCK_UNLOCKED;		sctp_ep_hashtable[i].chain = NULL;	}	/* Allocate and initialize the SCTP port hash table.  */	do {		sctp_port_hashsize = (1UL << order) * PAGE_SIZE /					sizeof(struct sctp_bind_hashbucket);		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)			continue;		sctp_port_hashtable = (struct sctp_bind_hashbucket *)					__get_free_pages(GFP_ATOMIC, order);	} while (!sctp_port_hashtable && --order > 0);	if (!sctp_port_hashtable) {		printk(KERN_ERR "SCTP: Failed bind hash alloc.");		status = -ENOMEM;		goto err_bhash_alloc;	}	for (i = 0; i < sctp_port_hashsize; i++) {		sctp_port_hashtable[i].lock = SPIN_LOCK_UNLOCKED;		sctp_port_hashtable[i].chain = NULL;	}	sctp_port_alloc_lock = SPIN_LOCK_UNLOCKED;	sctp_port_rover = sysctl_local_port_range[0] - 1;	printk(KERN_INFO "SCTP: Hash tables configured "			 "(established %d bind %d)\n",		sctp_assoc_hashsize, sctp_port_hashsize);	/* Disable ADDIP by default. */	sctp_addip_enable = 0;	/* Enable PR-SCTP by default. */	sctp_prsctp_enable = 1;	sctp_sysctl_register();	INIT_LIST_HEAD(&sctp_address_families);	sctp_register_af(&sctp_ipv4_specific);	status = sctp_v6_init();	if (status)		goto err_v6_init;	/* Initialize the control inode/socket for handling OOTB packets.  */	if ((status = sctp_ctl_sock_init())) {		printk (KERN_ERR			"SCTP: Failed to initialize the SCTP control sock.\n");		goto err_ctl_sock_init;	}	/* Initialize the local address list. */	INIT_LIST_HEAD(&sctp_local_addr_list);	sctp_local_addr_lock = SPIN_LOCK_UNLOCKED;	/* Register notifier for inet address additions/deletions. */	register_inetaddr_notifier(&sctp_inetaddr_notifier);	sctp_get_local_addr_list();	__unsafe(THIS_MODULE);	status = 0;out:	return status;err_add_protocol:	sk_free_slab(&sctp_prot);err_ctl_sock_init:	sctp_v6_exit();err_v6_init:	sctp_sysctl_unregister();	list_del(&sctp_ipv4_specific.list);	free_pages((unsigned long)sctp_port_hashtable,		   get_order(sctp_port_hashsize *			     sizeof(struct sctp_bind_hashbucket)));err_bhash_alloc:	kfree(sctp_ep_hashtable);err_ehash_alloc:	free_pages((unsigned long)sctp_assoc_hashtable,		   get_order(sctp_assoc_hashsize *			     sizeof(struct sctp_hashbucket)));err_ahash_alloc:	sctp_dbg_objcnt_exit();err_init_proc:	sctp_proc_exit();	cleanup_sctp_mibs();err_init_mibs:	kmem_cache_destroy(sctp_chunk_cachep);err_chunk_cachep:	kmem_cache_destroy(sctp_bucket_cachep);err_bucket_cachep:	inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);	inet_unregister_protosw(&sctp_seqpacket_protosw);	inet_unregister_protosw(&sctp_stream_protosw);	goto out;}/* Exit handler for the SCTP protocol.  */__exit void sctp_exit(void){	/* BUG.  This should probably do something useful like clean	 * up all the remaining associations and all that memory.	 */	/* Unregister notifier for inet address additions/deletions. */	unregister_inetaddr_notifier(&sctp_inetaddr_notifier);	/* Free the local address list.  */	sctp_free_local_addr_list();	/* Free the control endpoint.  */	sock_release(sctp_ctl_socket);	sctp_v6_exit();	sctp_sysctl_unregister();	list_del(&sctp_ipv4_specific.list);	free_pages((unsigned long)sctp_assoc_hashtable,		   get_order(sctp_assoc_hashsize *			     sizeof(struct sctp_hashbucket)));	kfree(sctp_ep_hashtable);	free_pages((unsigned long)sctp_port_hashtable,		   get_order(sctp_port_hashsize *			     sizeof(struct sctp_bind_hashbucket)));	kmem_cache_destroy(sctp_chunk_cachep);	kmem_cache_destroy(sctp_bucket_cachep);	sctp_dbg_objcnt_exit();	sctp_proc_exit();	cleanup_sctp_mibs();	inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);	inet_unregister_protosw(&sctp_seqpacket_protosw);	inet_unregister_protosw(&sctp_stream_protosw);	sk_free_slab(&sctp_prot);}module_init(sctp_init);module_exit(sctp_exit);MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -