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

📄 af_inet6.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	.connect	   = inet_stream_connect,	/* ok		*/	.socketpair	   = sock_no_socketpair,	/* a do nothing	*/	.accept		   = inet_accept,		/* ok		*/	.getname	   = inet6_getname,	.poll		   = tcp_poll,			/* ok		*/	.ioctl		   = inet6_ioctl,		/* must change  */	.listen		   = inet_listen,		/* ok		*/	.shutdown	   = inet_shutdown,		/* ok		*/	.setsockopt	   = sock_common_setsockopt,	/* ok		*/	.getsockopt	   = sock_common_getsockopt,	/* ok		*/	.sendmsg	   = tcp_sendmsg,		/* ok		*/	.recvmsg	   = sock_common_recvmsg,	/* ok		*/	.mmap		   = sock_no_mmap,	.sendpage	   = tcp_sendpage,#ifdef CONFIG_COMPAT	.compat_setsockopt = compat_sock_common_setsockopt,	.compat_getsockopt = compat_sock_common_getsockopt,#endif};const struct proto_ops inet6_dgram_ops = {	.family		   = PF_INET6,	.owner		   = THIS_MODULE,	.release	   = inet6_release,	.bind		   = inet6_bind,	.connect	   = inet_dgram_connect,	/* ok		*/	.socketpair	   = sock_no_socketpair,	/* a do nothing	*/	.accept		   = sock_no_accept,		/* a do nothing	*/	.getname	   = inet6_getname,	.poll		   = udp_poll,			/* ok		*/	.ioctl		   = inet6_ioctl,		/* must change  */	.listen		   = sock_no_listen,		/* ok		*/	.shutdown	   = inet_shutdown,		/* ok		*/	.setsockopt	   = sock_common_setsockopt,	/* ok		*/	.getsockopt	   = sock_common_getsockopt,	/* ok		*/	.sendmsg	   = inet_sendmsg,		/* ok		*/	.recvmsg	   = sock_common_recvmsg,	/* ok		*/	.mmap		   = sock_no_mmap,	.sendpage	   = sock_no_sendpage,#ifdef CONFIG_COMPAT	.compat_setsockopt = compat_sock_common_setsockopt,	.compat_getsockopt = compat_sock_common_getsockopt,#endif};static struct net_proto_family inet6_family_ops = {	.family = PF_INET6,	.create = inet6_create,	.owner	= THIS_MODULE,};/* Same as inet6_dgram_ops, sans udp_poll.  */static const struct proto_ops inet6_sockraw_ops = {	.family		   = PF_INET6,	.owner		   = THIS_MODULE,	.release	   = inet6_release,	.bind		   = inet6_bind,	.connect	   = inet_dgram_connect,	/* ok		*/	.socketpair	   = sock_no_socketpair,	/* a do nothing	*/	.accept		   = sock_no_accept,		/* a do nothing	*/	.getname	   = inet6_getname,	.poll		   = datagram_poll,		/* ok		*/	.ioctl		   = inet6_ioctl,		/* must change  */	.listen		   = sock_no_listen,		/* ok		*/	.shutdown	   = inet_shutdown,		/* ok		*/	.setsockopt	   = sock_common_setsockopt,	/* ok		*/	.getsockopt	   = sock_common_getsockopt,	/* ok		*/	.sendmsg	   = inet_sendmsg,		/* ok		*/	.recvmsg	   = sock_common_recvmsg,	/* ok		*/	.mmap		   = sock_no_mmap,	.sendpage	   = sock_no_sendpage,#ifdef CONFIG_COMPAT	.compat_setsockopt = compat_sock_common_setsockopt,	.compat_getsockopt = compat_sock_common_getsockopt,#endif};static struct inet_protosw rawv6_protosw = {	.type		= SOCK_RAW,	.protocol	= IPPROTO_IP,	/* wild card */	.prot		= &rawv6_prot,	.ops		= &inet6_sockraw_ops,	.capability	= CAP_NET_RAW,	.no_check	= UDP_CSUM_DEFAULT,	.flags		= INET_PROTOSW_REUSE,};voidinet6_register_protosw(struct inet_protosw *p){	struct list_head *lh;	struct inet_protosw *answer;	int protocol = p->protocol;	struct list_head *last_perm;	spin_lock_bh(&inetsw6_lock);	if (p->type >= SOCK_MAX)		goto out_illegal;	/* If we are trying to override a permanent protocol, bail. */	answer = NULL;	last_perm = &inetsw6[p->type];	list_for_each(lh, &inetsw6[p->type]) {		answer = list_entry(lh, struct inet_protosw, list);		/* Check only the non-wild match. */		if (INET_PROTOSW_PERMANENT & answer->flags) {			if (protocol == answer->protocol)				break;			last_perm = lh;		}		answer = NULL;	}	if (answer)		goto out_permanent;	/* Add the new entry after the last permanent entry if any, so that	 * the new entry does not override a permanent entry when matched with	 * a wild-card protocol. But it is allowed to override any existing	 * non-permanent entry.  This means that when we remove this entry, the	 * system automatically returns to the old behavior.	 */	list_add_rcu(&p->list, last_perm);out:	spin_unlock_bh(&inetsw6_lock);	return;out_permanent:	printk(KERN_ERR "Attempt to override permanent protocol %d.\n",	       protocol);	goto out;out_illegal:	printk(KERN_ERR	       "Ignoring attempt to register invalid socket type %d.\n",	       p->type);	goto out;}EXPORT_SYMBOL(inet6_register_protosw);voidinet6_unregister_protosw(struct inet_protosw *p){	if (INET_PROTOSW_PERMANENT & p->flags) {		printk(KERN_ERR		       "Attempt to unregister permanent protocol %d.\n",		       p->protocol);	} else {		spin_lock_bh(&inetsw6_lock);		list_del_rcu(&p->list);		spin_unlock_bh(&inetsw6_lock);		synchronize_net();	}}EXPORT_SYMBOL(inet6_unregister_protosw);int inet6_sk_rebuild_header(struct sock *sk){	int err;	struct dst_entry *dst;	struct ipv6_pinfo *np = inet6_sk(sk);	dst = __sk_dst_check(sk, np->dst_cookie);	if (dst == NULL) {		struct inet_sock *inet = inet_sk(sk);		struct in6_addr *final_p = NULL, final;		struct flowi fl;		memset(&fl, 0, sizeof(fl));		fl.proto = sk->sk_protocol;		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);		ipv6_addr_copy(&fl.fl6_src, &np->saddr);		fl.fl6_flowlabel = np->flow_label;		fl.oif = sk->sk_bound_dev_if;		fl.fl_ip_dport = inet->dport;		fl.fl_ip_sport = inet->sport;		security_sk_classify_flow(sk, &fl);		if (np->opt && np->opt->srcrt) {			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;			ipv6_addr_copy(&final, &fl.fl6_dst);			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);			final_p = &final;		}		err = ip6_dst_lookup(sk, &dst, &fl);		if (err) {			sk->sk_route_caps = 0;			return err;		}		if (final_p)			ipv6_addr_copy(&fl.fl6_dst, final_p);		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {			sk->sk_err_soft = -err;			return err;		}		__ip6_dst_store(sk, dst, NULL, NULL);	}	return 0;}EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header);int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb){	struct ipv6_pinfo *np = inet6_sk(sk);	struct inet6_skb_parm *opt = IP6CB(skb);	if (np->rxopt.all) {		if ((opt->hop && (np->rxopt.bits.hopopts ||				  np->rxopt.bits.ohopopts)) ||		    ((IPV6_FLOWINFO_MASK &		      *(__be32 *)skb_network_header(skb)) &&		     np->rxopt.bits.rxflow) ||		    (opt->srcrt && (np->rxopt.bits.srcrt ||		     np->rxopt.bits.osrcrt)) ||		    ((opt->dst1 || opt->dst0) &&		     (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))			return 1;	}	return 0;}EXPORT_SYMBOL_GPL(ipv6_opt_accepted);static int __init init_ipv6_mibs(void){	if (snmp_mib_init((void **)ipv6_statistics, sizeof (struct ipstats_mib),			  __alignof__(struct ipstats_mib)) < 0)		goto err_ip_mib;	if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),			  __alignof__(struct icmpv6_mib)) < 0)		goto err_icmp_mib;	if (snmp_mib_init((void **)icmpv6msg_statistics,	    sizeof (struct icmpv6msg_mib), __alignof__(struct icmpv6_mib)) < 0)		goto err_icmpmsg_mib;	if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),			  __alignof__(struct udp_mib)) < 0)		goto err_udp_mib;	if (snmp_mib_init((void **)udplite_stats_in6, sizeof (struct udp_mib),			  __alignof__(struct udp_mib)) < 0)		goto err_udplite_mib;	return 0;err_udplite_mib:	snmp_mib_free((void **)udp_stats_in6);err_udp_mib:	snmp_mib_free((void **)icmpv6msg_statistics);err_icmpmsg_mib:	snmp_mib_free((void **)icmpv6_statistics);err_icmp_mib:	snmp_mib_free((void **)ipv6_statistics);err_ip_mib:	return -ENOMEM;}static void cleanup_ipv6_mibs(void){	snmp_mib_free((void **)ipv6_statistics);	snmp_mib_free((void **)icmpv6_statistics);	snmp_mib_free((void **)icmpv6msg_statistics);	snmp_mib_free((void **)udp_stats_in6);	snmp_mib_free((void **)udplite_stats_in6);}static int __init inet6_init(void){	struct sk_buff *dummy_skb;	struct list_head *r;	int err;	BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb));#ifdef MODULE#if 0 /* FIXME --RR */	if (!mod_member_present(&__this_module, can_unload))	  return -EINVAL;	__this_module.can_unload = &ipv6_unload;#endif#endif	err = proto_register(&tcpv6_prot, 1);	if (err)		goto out;	err = proto_register(&udpv6_prot, 1);	if (err)		goto out_unregister_tcp_proto;	err = proto_register(&udplitev6_prot, 1);	if (err)		goto out_unregister_udp_proto;	err = proto_register(&rawv6_prot, 1);	if (err)		goto out_unregister_udplite_proto;	/* Register the socket-side information for inet6_create.  */	for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)		INIT_LIST_HEAD(r);	/* We MUST register RAW sockets before we create the ICMP6,	 * IGMP6, or NDISC control sockets.	 */	inet6_register_protosw(&rawv6_protosw);	/* Register the family here so that the init calls below will	 * be able to create sockets. (?? is this dangerous ??)	 */	err = sock_register(&inet6_family_ops);	if (err)		goto out_unregister_raw_proto;	/* Initialise ipv6 mibs */	err = init_ipv6_mibs();	if (err)		goto out_unregister_sock;	/*	 *	ipngwg API draft makes clear that the correct semantics	 *	for TCP and UDP is to consider one TCP and UDP instance	 *	in a host availiable by both INET and INET6 APIs and	 *	able to communicate via both network protocols.	 */#ifdef CONFIG_SYSCTL	ipv6_sysctl_register();#endif	err = icmpv6_init(&inet6_family_ops);	if (err)		goto icmp_fail;	err = ndisc_init(&inet6_family_ops);	if (err)		goto ndisc_fail;	err = igmp6_init(&inet6_family_ops);	if (err)		goto igmp_fail;	err = ipv6_netfilter_init();	if (err)		goto netfilter_fail;	/* Create /proc/foo6 entries. */#ifdef CONFIG_PROC_FS	err = -ENOMEM;	if (raw6_proc_init())		goto proc_raw6_fail;	if (tcp6_proc_init())		goto proc_tcp6_fail;	if (udp6_proc_init())		goto proc_udp6_fail;	if (udplite6_proc_init())		goto proc_udplite6_fail;	if (ipv6_misc_proc_init())		goto proc_misc6_fail;	if (ac6_proc_init())		goto proc_anycast6_fail;	if (if6_proc_init())		goto proc_if6_fail;#endif	ip6_route_init();	ip6_flowlabel_init();	err = addrconf_init();	if (err)		goto addrconf_fail;	/* Init v6 extension headers. */	ipv6_rthdr_init();	ipv6_frag_init();	ipv6_nodata_init();	ipv6_destopt_init();	/* Init v6 transport protocols. */	udpv6_init();	udplitev6_init();	tcpv6_init();	ipv6_packet_init();	err = 0;out:	return err;addrconf_fail:	ip6_flowlabel_cleanup();	ip6_route_cleanup();#ifdef CONFIG_PROC_FS	if6_proc_exit();proc_if6_fail:	ac6_proc_exit();proc_anycast6_fail:	ipv6_misc_proc_exit();proc_misc6_fail:	udplite6_proc_exit();proc_udplite6_fail:	udp6_proc_exit();proc_udp6_fail:	tcp6_proc_exit();proc_tcp6_fail:	raw6_proc_exit();proc_raw6_fail:#endif	ipv6_netfilter_fini();netfilter_fail:	igmp6_cleanup();igmp_fail:	ndisc_cleanup();ndisc_fail:	icmpv6_cleanup();icmp_fail:#ifdef CONFIG_SYSCTL	ipv6_sysctl_unregister();#endif	cleanup_ipv6_mibs();out_unregister_sock:	sock_unregister(PF_INET6);out_unregister_raw_proto:	proto_unregister(&rawv6_prot);out_unregister_udplite_proto:	proto_unregister(&udplitev6_prot);out_unregister_udp_proto:	proto_unregister(&udpv6_prot);out_unregister_tcp_proto:	proto_unregister(&tcpv6_prot);	goto out;}module_init(inet6_init);static void __exit inet6_exit(void){	/* First of all disallow new sockets creation. */	sock_unregister(PF_INET6);	/* Disallow any further netlink messages */	rtnl_unregister_all(PF_INET6);	/* Cleanup code parts. */	ipv6_packet_cleanup();	addrconf_cleanup();	ip6_flowlabel_cleanup();	ip6_route_cleanup();#ifdef CONFIG_PROC_FS	/* Cleanup code parts. */	if6_proc_exit();	ac6_proc_exit();	ipv6_misc_proc_exit();	udplite6_proc_exit();	udp6_proc_exit();	tcp6_proc_exit();	raw6_proc_exit();#endif	ipv6_netfilter_fini();	igmp6_cleanup();	ndisc_cleanup();	icmpv6_cleanup();#ifdef CONFIG_SYSCTL	ipv6_sysctl_unregister();#endif	cleanup_ipv6_mibs();	proto_unregister(&rawv6_prot);	proto_unregister(&udplitev6_prot);	proto_unregister(&udpv6_prot);	proto_unregister(&tcpv6_prot);}module_exit(inet6_exit);MODULE_ALIAS_NETPROTO(PF_INET6);

⌨️ 快捷键说明

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