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

📄 af_inet.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}}/* *      Shall we try to damage output packets if routing dev changes? */int sysctl_ip_dynaddr __read_mostly;static int inet_sk_reselect_saddr(struct sock *sk){	struct inet_sock *inet = inet_sk(sk);	int err;	struct rtable *rt;	__be32 old_saddr = inet->saddr;	__be32 new_saddr;	__be32 daddr = inet->daddr;	if (inet->opt && inet->opt->srr)		daddr = inet->opt->faddr;	/* Query new route. */	err = ip_route_connect(&rt, daddr, 0,			       RT_CONN_FLAGS(sk),			       sk->sk_bound_dev_if,			       sk->sk_protocol,			       inet->sport, inet->dport, sk, 0);	if (err)		return err;	sk_setup_caps(sk, &rt->u.dst);	new_saddr = rt->rt_src;	if (new_saddr == old_saddr)		return 0;	if (sysctl_ip_dynaddr > 1) {		printk(KERN_INFO "%s(): shifting inet->"				 "saddr from %d.%d.%d.%d to %d.%d.%d.%d\n",		       __FUNCTION__,		       NIPQUAD(old_saddr),		       NIPQUAD(new_saddr));	}	inet->saddr = inet->rcv_saddr = new_saddr;	/*	 * XXX The only one ugly spot where we need to	 * XXX really change the sockets identity after	 * XXX it has entered the hashes. -DaveM	 *	 * Besides that, it does not check for connection	 * uniqueness. Wait for troubles.	 */	__sk_prot_rehash(sk);	return 0;}int inet_sk_rebuild_header(struct sock *sk){	struct inet_sock *inet = inet_sk(sk);	struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);	__be32 daddr;	int err;	/* Route is OK, nothing to do. */	if (rt)		return 0;	/* Reroute. */	daddr = inet->daddr;	if (inet->opt && inet->opt->srr)		daddr = inet->opt->faddr;{	struct flowi fl = {		.oif = sk->sk_bound_dev_if,		.nl_u = {			.ip4_u = {				.daddr	= daddr,				.saddr	= inet->saddr,				.tos	= RT_CONN_FLAGS(sk),			},		},		.proto = sk->sk_protocol,		.uli_u = {			.ports = {				.sport = inet->sport,				.dport = inet->dport,			},		},	};	security_sk_classify_flow(sk, &fl);	err = ip_route_output_flow(&rt, &fl, sk, 0);}	if (!err)		sk_setup_caps(sk, &rt->u.dst);	else {		/* Routing failed... */		sk->sk_route_caps = 0;		/*		 * Other protocols have to map its equivalent state to TCP_SYN_SENT.		 * DCCP maps its DCCP_REQUESTING state to TCP_SYN_SENT. -acme		 */		if (!sysctl_ip_dynaddr ||		    sk->sk_state != TCP_SYN_SENT ||		    (sk->sk_userlocks & SOCK_BINDADDR_LOCK) ||		    (err = inet_sk_reselect_saddr(sk)) != 0)			sk->sk_err_soft = -err;	}	return err;}EXPORT_SYMBOL(inet_sk_rebuild_header);static int inet_gso_send_check(struct sk_buff *skb){	struct iphdr *iph;	struct net_protocol *ops;	int proto;	int ihl;	int err = -EINVAL;	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))		goto out;	iph = ip_hdr(skb);	ihl = iph->ihl * 4;	if (ihl < sizeof(*iph))		goto out;	if (unlikely(!pskb_may_pull(skb, ihl)))		goto out;	__skb_pull(skb, ihl);	skb_reset_transport_header(skb);	iph = ip_hdr(skb);	proto = iph->protocol & (MAX_INET_PROTOS - 1);	err = -EPROTONOSUPPORT;	rcu_read_lock();	ops = rcu_dereference(inet_protos[proto]);	if (likely(ops && ops->gso_send_check))		err = ops->gso_send_check(skb);	rcu_read_unlock();out:	return err;}static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features){	struct sk_buff *segs = ERR_PTR(-EINVAL);	struct iphdr *iph;	struct net_protocol *ops;	int proto;	int ihl;	int id;	if (!(features & NETIF_F_V4_CSUM))		features &= ~NETIF_F_SG;	if (unlikely(skb_shinfo(skb)->gso_type &		     ~(SKB_GSO_TCPV4 |		       SKB_GSO_UDP |		       SKB_GSO_DODGY |		       SKB_GSO_TCP_ECN |		       0)))		goto out;	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))		goto out;	iph = ip_hdr(skb);	ihl = iph->ihl * 4;	if (ihl < sizeof(*iph))		goto out;	if (unlikely(!pskb_may_pull(skb, ihl)))		goto out;	__skb_pull(skb, ihl);	skb_reset_transport_header(skb);	iph = ip_hdr(skb);	id = ntohs(iph->id);	proto = iph->protocol & (MAX_INET_PROTOS - 1);	segs = ERR_PTR(-EPROTONOSUPPORT);	rcu_read_lock();	ops = rcu_dereference(inet_protos[proto]);	if (likely(ops && ops->gso_segment))		segs = ops->gso_segment(skb, features);	rcu_read_unlock();	if (!segs || unlikely(IS_ERR(segs)))		goto out;	skb = segs;	do {		iph = ip_hdr(skb);		iph->id = htons(id++);		iph->tot_len = htons(skb->len - skb->mac_len);		iph->check = 0;		iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);	} while ((skb = skb->next));out:	return segs;}unsigned long snmp_fold_field(void *mib[], int offt){	unsigned long res = 0;	int i;	for_each_possible_cpu(i) {		res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);		res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);	}	return res;}EXPORT_SYMBOL_GPL(snmp_fold_field);int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign){	BUG_ON(ptr == NULL);	ptr[0] = __alloc_percpu(mibsize);	if (!ptr[0])		goto err0;	ptr[1] = __alloc_percpu(mibsize);	if (!ptr[1])		goto err1;	return 0;err1:	free_percpu(ptr[0]);	ptr[0] = NULL;err0:	return -ENOMEM;}EXPORT_SYMBOL_GPL(snmp_mib_init);void snmp_mib_free(void *ptr[2]){	BUG_ON(ptr == NULL);	free_percpu(ptr[0]);	free_percpu(ptr[1]);	ptr[0] = ptr[1] = NULL;}EXPORT_SYMBOL_GPL(snmp_mib_free);#ifdef CONFIG_IP_MULTICASTstatic struct net_protocol igmp_protocol = {	.handler =	igmp_rcv,};#endifstatic struct net_protocol tcp_protocol = {	.handler =	tcp_v4_rcv,	.err_handler =	tcp_v4_err,	.gso_send_check = tcp_v4_gso_send_check,	.gso_segment =	tcp_tso_segment,	.no_policy =	1,};static struct net_protocol udp_protocol = {	.handler =	udp_rcv,	.err_handler =	udp_err,	.no_policy =	1,};static struct net_protocol icmp_protocol = {	.handler =	icmp_rcv,};static int __init init_ipv4_mibs(void){	if (snmp_mib_init((void **)net_statistics,			  sizeof(struct linux_mib),			  __alignof__(struct linux_mib)) < 0)		goto err_net_mib;	if (snmp_mib_init((void **)ip_statistics,			  sizeof(struct ipstats_mib),			  __alignof__(struct ipstats_mib)) < 0)		goto err_ip_mib;	if (snmp_mib_init((void **)icmp_statistics,			  sizeof(struct icmp_mib),			  __alignof__(struct icmp_mib)) < 0)		goto err_icmp_mib;	if (snmp_mib_init((void **)icmpmsg_statistics,			  sizeof(struct icmpmsg_mib),			  __alignof__(struct icmpmsg_mib)) < 0)		goto err_icmpmsg_mib;	if (snmp_mib_init((void **)tcp_statistics,			  sizeof(struct tcp_mib),			  __alignof__(struct tcp_mib)) < 0)		goto err_tcp_mib;	if (snmp_mib_init((void **)udp_statistics,			  sizeof(struct udp_mib),			  __alignof__(struct udp_mib)) < 0)		goto err_udp_mib;	if (snmp_mib_init((void **)udplite_statistics,			  sizeof(struct udp_mib),			  __alignof__(struct udp_mib)) < 0)		goto err_udplite_mib;	tcp_mib_init();	return 0;err_udplite_mib:	snmp_mib_free((void **)udp_statistics);err_udp_mib:	snmp_mib_free((void **)tcp_statistics);err_tcp_mib:	snmp_mib_free((void **)icmpmsg_statistics);err_icmpmsg_mib:	snmp_mib_free((void **)icmp_statistics);err_icmp_mib:	snmp_mib_free((void **)ip_statistics);err_ip_mib:	snmp_mib_free((void **)net_statistics);err_net_mib:	return -ENOMEM;}static int ipv4_proc_init(void);/* *	IP protocol layer initialiser */static struct packet_type ip_packet_type = {	.type = __constant_htons(ETH_P_IP),	.func = ip_rcv,	.gso_send_check = inet_gso_send_check,	.gso_segment = inet_gso_segment,};static int __init inet_init(void){	struct sk_buff *dummy_skb;	struct inet_protosw *q;	struct list_head *r;	int rc = -EINVAL;	BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));	rc = proto_register(&tcp_prot, 1);	if (rc)		goto out;	rc = proto_register(&udp_prot, 1);	if (rc)		goto out_unregister_tcp_proto;	rc = proto_register(&raw_prot, 1);	if (rc)		goto out_unregister_udp_proto;	/*	 *	Tell SOCKET that we are alive...	 */	(void)sock_register(&inet_family_ops);	/*	 *	Add all the base protocols.	 */	if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)		printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");	if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)		printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");	if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)		printk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");#ifdef CONFIG_IP_MULTICAST	if (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)		printk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");#endif	/* 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);	/*	 *	Set the ARP module up	 */	arp_init();	/*	 *	Set the IP module up	 */	ip_init();	tcp_v4_init(&inet_family_ops);	/* Setup TCP slab cache for open requests. */	tcp_init();	/* Add UDP-Lite (RFC 3828) */	udplite4_register();	/*	 *	Set the ICMP layer up	 */	icmp_init(&inet_family_ops);	/*	 *	Initialise the multicast router	 */#if defined(CONFIG_IP_MROUTE)	ip_mr_init();#endif	/*	 *	Initialise per-cpu ipv4 mibs	 */	if (init_ipv4_mibs())		printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n"); ;	ipv4_proc_init();	ipfrag_init();	dev_add_pack(&ip_packet_type);	rc = 0;out:	return rc;out_unregister_udp_proto:	proto_unregister(&udp_prot);out_unregister_tcp_proto:	proto_unregister(&tcp_prot);	goto out;}fs_initcall(inet_init);/* ------------------------------------------------------------------------ */#ifdef CONFIG_PROC_FSstatic int __init ipv4_proc_init(void){	int rc = 0;	if (raw_proc_init())		goto out_raw;	if (tcp4_proc_init())		goto out_tcp;	if (udp4_proc_init())		goto out_udp;	if (fib_proc_init())		goto out_fib;	if (ip_misc_proc_init())		goto out_misc;out:	return rc;out_misc:	fib_proc_exit();out_fib:	udp4_proc_exit();out_udp:	tcp4_proc_exit();out_tcp:	raw_proc_exit();out_raw:	rc = -ENOMEM;	goto out;}#else /* CONFIG_PROC_FS */static int __init ipv4_proc_init(void){	return 0;}#endif /* CONFIG_PROC_FS */MODULE_ALIAS_NETPROTO(PF_INET);EXPORT_SYMBOL(inet_accept);EXPORT_SYMBOL(inet_bind);EXPORT_SYMBOL(inet_dgram_connect);EXPORT_SYMBOL(inet_dgram_ops);EXPORT_SYMBOL(inet_getname);EXPORT_SYMBOL(inet_ioctl);EXPORT_SYMBOL(inet_listen);EXPORT_SYMBOL(inet_register_protosw);EXPORT_SYMBOL(inet_release);EXPORT_SYMBOL(inet_sendmsg);EXPORT_SYMBOL(inet_shutdown);EXPORT_SYMBOL(inet_sock_destruct);EXPORT_SYMBOL(inet_stream_connect);EXPORT_SYMBOL(inet_stream_ops);EXPORT_SYMBOL(inet_unregister_protosw);EXPORT_SYMBOL(net_statistics);EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);

⌨️ 快捷键说明

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