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

📄 ip_vs_ctl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	ip_vs_num_services--;	ip_vs_kill_estimator(&svc->stats);	/* Unbind scheduler */	old_sched = svc->scheduler;	ip_vs_unbind_scheduler(svc);	if (old_sched)		ip_vs_scheduler_put(old_sched);	/* Unbind app inc */	if (svc->inc) {		ip_vs_app_inc_put(svc->inc);		svc->inc = NULL;	}	/*	 *    Unlink the whole destination list	 */	list_for_each_entry_safe(dest, nxt, &svc->destinations, n_list) {		__ip_vs_unlink_dest(svc, dest, 0);		__ip_vs_del_dest(dest);	}	/*	 *    Update the virtual service counters	 */	if (svc->port == FTPPORT)		atomic_dec(&ip_vs_ftpsvc_counter);	else if (svc->port == 0)		atomic_dec(&ip_vs_nullsvc_counter);	/*	 *    Free the service if nobody refers to it	 */	if (atomic_read(&svc->refcnt) == 0)		kfree(svc);	/* decrease the module use count */	ip_vs_use_count_dec();}/* *	Delete a service from the service list */static int ip_vs_del_service(struct ip_vs_service *svc){	if (svc == NULL)		return -EEXIST;	/*	 * Unhash it from the service table	 */	write_lock_bh(&__ip_vs_svc_lock);	ip_vs_svc_unhash(svc);	/*	 * Wait until all the svc users go away.	 */	IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);	__ip_vs_del_service(svc);	write_unlock_bh(&__ip_vs_svc_lock);	return 0;}/* *	Flush all the virtual services */static int ip_vs_flush(void){	int idx;	struct ip_vs_service *svc, *nxt;	/*	 * Flush the service table hashed by <protocol,addr,port>	 */	for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) {			write_lock_bh(&__ip_vs_svc_lock);			ip_vs_svc_unhash(svc);			/*			 * Wait until all the svc users go away.			 */			IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);			__ip_vs_del_service(svc);			write_unlock_bh(&__ip_vs_svc_lock);		}	}	/*	 * Flush the service table hashed by fwmark	 */	for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry_safe(svc, nxt,					 &ip_vs_svc_fwm_table[idx], f_list) {			write_lock_bh(&__ip_vs_svc_lock);			ip_vs_svc_unhash(svc);			/*			 * Wait until all the svc users go away.			 */			IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0);			__ip_vs_del_service(svc);			write_unlock_bh(&__ip_vs_svc_lock);		}	}	return 0;}/* *	Zero counters in a service or all services */static int ip_vs_zero_service(struct ip_vs_service *svc){	struct ip_vs_dest *dest;	write_lock_bh(&__ip_vs_svc_lock);	list_for_each_entry(dest, &svc->destinations, n_list) {		ip_vs_zero_stats(&dest->stats);	}	ip_vs_zero_stats(&svc->stats);	write_unlock_bh(&__ip_vs_svc_lock);	return 0;}static int ip_vs_zero_all(void){	int idx;	struct ip_vs_service *svc;	for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {			ip_vs_zero_service(svc);		}	}	for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {			ip_vs_zero_service(svc);		}	}	ip_vs_zero_stats(&ip_vs_stats);	return 0;}static intproc_do_defense_mode(ctl_table *table, int write, struct file * filp,		     void __user *buffer, size_t *lenp, loff_t *ppos){	int *valp = table->data;	int val = *valp;	int rc;	rc = proc_dointvec(table, write, filp, buffer, lenp, ppos);	if (write && (*valp != val)) {		if ((*valp < 0) || (*valp > 3)) {			/* Restore the correct value */			*valp = val;		} else {			update_defense_level();		}	}	return rc;}static intproc_do_sync_threshold(ctl_table *table, int write, struct file *filp,		       void __user *buffer, size_t *lenp, loff_t *ppos){	int *valp = table->data;	int val[2];	int rc;	/* backup the value first */	memcpy(val, valp, sizeof(val));	rc = proc_dointvec(table, write, filp, buffer, lenp, ppos);	if (write && (valp[0] < 0 || valp[1] < 0 || valp[0] >= valp[1])) {		/* Restore the correct value */		memcpy(valp, val, sizeof(val));	}	return rc;}/* *	IPVS sysctl table (under the /proc/sys/net/ipv4/vs/) */static struct ctl_table vs_vars[] = {	{		.ctl_name	= NET_IPV4_VS_AMEMTHRESH,		.procname	= "amemthresh",		.data		= &sysctl_ip_vs_amemthresh,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},#ifdef CONFIG_IP_VS_DEBUG	{		.ctl_name	= NET_IPV4_VS_DEBUG_LEVEL,		.procname	= "debug_level",		.data		= &sysctl_ip_vs_debug_level,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},#endif	{		.ctl_name	= NET_IPV4_VS_AMDROPRATE,		.procname	= "am_droprate",		.data		= &sysctl_ip_vs_am_droprate,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_VS_DROP_ENTRY,		.procname	= "drop_entry",		.data		= &sysctl_ip_vs_drop_entry,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_do_defense_mode,	},	{		.ctl_name	= NET_IPV4_VS_DROP_PACKET,		.procname	= "drop_packet",		.data		= &sysctl_ip_vs_drop_packet,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_do_defense_mode,	},	{		.ctl_name	= NET_IPV4_VS_SECURE_TCP,		.procname	= "secure_tcp",		.data		= &sysctl_ip_vs_secure_tcp,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_do_defense_mode,	},#if 0	{		.ctl_name	= NET_IPV4_VS_TO_ES,		.procname	= "timeout_established",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_ESTABLISHED],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_SS,		.procname	= "timeout_synsent",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_SYN_SENT],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_SR,		.procname	= "timeout_synrecv",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_SYN_RECV],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_FW,		.procname	= "timeout_finwait",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_FIN_WAIT],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_TW,		.procname	= "timeout_timewait",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_TIME_WAIT],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_CL,		.procname	= "timeout_close",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_CW,		.procname	= "timeout_closewait",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE_WAIT],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_LA,		.procname	= "timeout_lastack",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_LAST_ACK],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_LI,		.procname	= "timeout_listen",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_LISTEN],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_SA,		.procname	= "timeout_synack",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_SYNACK],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_UDP,		.procname	= "timeout_udp",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_UDP],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},	{		.ctl_name	= NET_IPV4_VS_TO_ICMP,		.procname	= "timeout_icmp",		.data	= &vs_timeout_table_dos.timeout[IP_VS_S_ICMP],		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec_jiffies,	},#endif	{		.ctl_name	= NET_IPV4_VS_CACHE_BYPASS,		.procname	= "cache_bypass",		.data		= &sysctl_ip_vs_cache_bypass,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_VS_EXPIRE_NODEST_CONN,		.procname	= "expire_nodest_conn",		.data		= &sysctl_ip_vs_expire_nodest_conn,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE,		.procname	= "expire_quiescent_template",		.data		= &sysctl_ip_vs_expire_quiescent_template,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{		.ctl_name	= NET_IPV4_VS_SYNC_THRESHOLD,		.procname	= "sync_threshold",		.data		= &sysctl_ip_vs_sync_threshold,		.maxlen		= sizeof(sysctl_ip_vs_sync_threshold),		.mode		= 0644,		.proc_handler	= &proc_do_sync_threshold,	},	{		.ctl_name	= NET_IPV4_VS_NAT_ICMP_SEND,		.procname	= "nat_icmp_send",		.data		= &sysctl_ip_vs_nat_icmp_send,		.maxlen		= sizeof(int),		.mode		= 0644,		.proc_handler	= &proc_dointvec,	},	{ .ctl_name = 0 }};static ctl_table vs_table[] = {	{		.ctl_name	= NET_IPV4_VS,		.procname	= "vs",		.mode		= 0555,		.child		= vs_vars	},	{ .ctl_name = 0 }};static ctl_table ipvs_ipv4_table[] = {	{		.ctl_name	= NET_IPV4,		.procname	= "ipv4",		.mode		= 0555,		.child		= vs_table,	},	{ .ctl_name = 0 }};static ctl_table vs_root_table[] = {	{		.ctl_name	= CTL_NET,		.procname	= "net",		.mode		= 0555,		.child		= ipvs_ipv4_table,	},	{ .ctl_name = 0 }};static struct ctl_table_header * sysctl_header;#ifdef CONFIG_PROC_FSstruct ip_vs_iter {	struct list_head *table;	int bucket;};/* *	Write the contents of the VS rule table to a PROCfs file. *	(It is kept just for backward compatibility) */static inline const char *ip_vs_fwd_name(unsigned flags){	switch (flags & IP_VS_CONN_F_FWD_MASK) {	case IP_VS_CONN_F_LOCALNODE:		return "Local";	case IP_VS_CONN_F_TUNNEL:		return "Tunnel";	case IP_VS_CONN_F_DROUTE:		return "Route";	default:		return "Masq";	}}/* Get the Nth entry in the two lists */static struct ip_vs_service *ip_vs_info_array(struct seq_file *seq, loff_t pos){	struct ip_vs_iter *iter = seq->private;	int idx;	struct ip_vs_service *svc;	/* look in hash by protocol */	for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {			if (pos-- == 0){				iter->table = ip_vs_svc_table;				iter->bucket = idx;				return svc;			}		}	}	/* keep looking in fwmark */	for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {		list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {			if (pos-- == 0) {				iter->table = ip_vs_svc_fwm_table;				iter->bucket = idx;				return svc;			}		}	}	return NULL;}static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos){	read_lock_bh(&__ip_vs_svc_lock);	return *pos ? ip_vs_info_array(seq, *pos - 1) : SEQ_START_TOKEN;}static void *ip_vs_info_seq_next(struct seq_file *seq, void *v, loff_t *pos){	struct list_head *e;	struct ip_vs_iter *iter;	struct ip_vs_service *svc;	++*pos;	if (v == SEQ_START_TOKEN)		return ip_vs_info_array(seq,0);	svc = v;	iter = seq->private;	if (iter->table == ip_vs_svc_table) {		/* next service in table hashed by protocol */		if ((e = svc->s_list.next) != &ip_vs_svc_table[iter->bucket])			return list_entry(e, struct ip_vs_service, s_list);		while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {			list_for_each_entry(svc,&ip_vs_svc_table[iter->bucket],					    s_list) {				return svc;			}		}		iter->table = ip_vs_svc_fwm_table;		iter->bucket = -1;		goto scan_fwmark;	}	/* next service in hashed by fwmark */	if ((e = svc->f_list.next) != &ip_vs_svc_fwm_table[iter->bucket])		return list_entry(e, struct ip_vs_service, f_list); scan_fwmark:	while (++iter->bucket < IP_VS_SVC_TAB_SIZE) {		list_for_each_entry(svc, &ip_vs_svc_fwm_table[iter->bucket],				    f_list)			return svc;	}	return NULL;}static void ip_vs_info_seq_stop(struct seq_file *seq, void *v){	read_unlock_bh(&__ip_vs_svc_lock);}static int ip_vs_info_seq_show(struct seq_file *seq, void *v){	if (v == SEQ_START_TOKEN) {		seq_printf(seq,			"IP Virtual Server version %d.%d.%d (size=%d)\n",			NVERSION(IP_VS_VERSION_CODE), IP_VS_CONN_TAB_SIZE);		seq_puts(seq,			 "Prot LocalAddress:Port Scheduler Flags\n");		seq_puts(seq,			 "  -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n");	} else {		const struct ip_vs_service *svc = v;		const struct ip_vs_iter *iter = seq->private;		const struct ip_vs_dest *dest;		if (iter->table == ip_vs_svc_table)			seq_printf(seq, "%s  %08X:%04X %s ",				   ip_vs_proto_name(svc->protocol),				   ntohl(svc->addr),				   ntohs(svc->port),				   svc->scheduler->name);		else			seq_printf(seq, "FWM  %08X %s ",				   svc->fwmark, svc->scheduler->name);		if (svc->flags & IP_VS_SVC_F_PERSISTENT)			seq_printf(seq, "persistent %d %08X\n",				svc->timeout,				ntohl(svc->netmask));		else			seq_putc(seq, '\n');		list_for_each_entry(dest, &svc->destinations, n_list) {			seq_printf(seq,				   "  -> %08X:%04X      %-7s %-6d %-10d %-10d\n",				   ntohl(dest->addr), ntohs(dest->port),				   ip_vs_fwd_name(atomic_read(&dest->conn_flags)),				   atomic_read(&dest->weight),				   atomic_read(&dest->activeconns),				   atomic_read(&dest->inactconns));		}	}	return 0;}static struct seq_operations ip_vs_info_seq_ops = {	.start = ip_vs_info_seq_start,	.next  = ip_vs_info_seq_next,	.stop  = ip_vs_info_seq_stop,	.show  = ip_vs_info_seq_show,};static int ip_vs_info_open(struct inode *inode, struct file *file){	struct seq_file *seq;	int rc = -ENOMEM;	struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL);	if (!s)		goto out;

⌨️ 快捷键说明

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