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

📄 neighbour.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 4 页
字号:
				void *v = state->neigh_sub_iter(state, n, pos);				if (v)					return n;				goto next;			}			if (!(state->flags & NEIGH_SEQ_SKIP_NOARP))				break;			if (n->nud_state & ~NUD_NOARP)				break;		next:			n = n->next;		}		if (n)			break;		if (++state->bucket > tbl->hash_mask)			break;		n = tbl->hash_buckets[state->bucket];	}	if (n && pos)		--(*pos);	return n;}static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos){	struct neighbour *n = neigh_get_first(seq);	if (n) {		while (*pos) {			n = neigh_get_next(seq, n, pos);			if (!n)				break;		}	}	return *pos ? NULL : n;}static struct pneigh_entry *pneigh_get_first(struct seq_file *seq){	struct neigh_seq_state *state = seq->private;	struct neigh_table *tbl = state->tbl;	struct pneigh_entry *pn = NULL;	int bucket = state->bucket;	state->flags |= NEIGH_SEQ_IS_PNEIGH;	for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {		pn = tbl->phash_buckets[bucket];		if (pn)			break;	}	state->bucket = bucket;	return pn;}static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,					    struct pneigh_entry *pn,					    loff_t *pos){	struct neigh_seq_state *state = seq->private;	struct neigh_table *tbl = state->tbl;	pn = pn->next;	while (!pn) {		if (++state->bucket > PNEIGH_HASHMASK)			break;		pn = tbl->phash_buckets[state->bucket];		if (pn)			break;	}	if (pn && pos)		--(*pos);	return pn;}static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos){	struct pneigh_entry *pn = pneigh_get_first(seq);	if (pn) {		while (*pos) {			pn = pneigh_get_next(seq, pn, pos);			if (!pn)				break;		}	}	return *pos ? NULL : pn;}static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos){	struct neigh_seq_state *state = seq->private;	void *rc;	rc = neigh_get_idx(seq, pos);	if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY))		rc = pneigh_get_idx(seq, pos);	return rc;}void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags){	struct neigh_seq_state *state = seq->private;	loff_t pos_minus_one;	state->tbl = tbl;	state->bucket = 0;	state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH);	read_lock_bh(&tbl->lock);	pos_minus_one = *pos - 1;	return *pos ? neigh_get_idx_any(seq, &pos_minus_one) : SEQ_START_TOKEN;}EXPORT_SYMBOL(neigh_seq_start);void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos){	struct neigh_seq_state *state;	void *rc;	if (v == SEQ_START_TOKEN) {		rc = neigh_get_idx(seq, pos);		goto out;	}	state = seq->private;	if (!(state->flags & NEIGH_SEQ_IS_PNEIGH)) {		rc = neigh_get_next(seq, v, NULL);		if (rc)			goto out;		if (!(state->flags & NEIGH_SEQ_NEIGH_ONLY))			rc = pneigh_get_first(seq);	} else {		BUG_ON(state->flags & NEIGH_SEQ_NEIGH_ONLY);		rc = pneigh_get_next(seq, v, NULL);	}out:	++(*pos);	return rc;}EXPORT_SYMBOL(neigh_seq_next);void neigh_seq_stop(struct seq_file *seq, void *v){	struct neigh_seq_state *state = seq->private;	struct neigh_table *tbl = state->tbl;	read_unlock_bh(&tbl->lock);}EXPORT_SYMBOL(neigh_seq_stop);/* statistics via seq_file */static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos){	struct proc_dir_entry *pde = seq->private;	struct neigh_table *tbl = pde->data;	int cpu;	if (*pos == 0)		return SEQ_START_TOKEN;		for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {		if (!cpu_possible(cpu))			continue;		*pos = cpu+1;		return per_cpu_ptr(tbl->stats, cpu);	}	return NULL;}static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos){	struct proc_dir_entry *pde = seq->private;	struct neigh_table *tbl = pde->data;	int cpu;	for (cpu = *pos; cpu < NR_CPUS; ++cpu) {		if (!cpu_possible(cpu))			continue;		*pos = cpu+1;		return per_cpu_ptr(tbl->stats, cpu);	}	return NULL;}static void neigh_stat_seq_stop(struct seq_file *seq, void *v){}static int neigh_stat_seq_show(struct seq_file *seq, void *v){	struct proc_dir_entry *pde = seq->private;	struct neigh_table *tbl = pde->data;	struct neigh_statistics *st = v;	if (v == SEQ_START_TOKEN) {		seq_printf(seq, "entries  allocs destroys hash_grows  lookups hits  res_failed  rcv_probes_mcast rcv_probes_ucast  periodic_gc_runs forced_gc_runs forced_gc_goal_miss\n");		return 0;	}	seq_printf(seq, "%08x  %08lx %08lx %08lx  %08lx %08lx  %08lx  "			"%08lx %08lx  %08lx %08lx\n",		   tbl->entries,		   st->allocs,		   st->destroys,		   st->hash_grows,		   st->lookups,		   st->hits,		   st->res_failed,		   st->rcv_probes_mcast,		   st->rcv_probes_ucast,		   st->periodic_gc_runs,		   st->forced_gc_runs		   );	return 0;}static struct seq_operations neigh_stat_seq_ops = {	.start	= neigh_stat_seq_start,	.next	= neigh_stat_seq_next,	.stop	= neigh_stat_seq_stop,	.show	= neigh_stat_seq_show,};static int neigh_stat_seq_open(struct inode *inode, struct file *file){	int ret = seq_open(file, &neigh_stat_seq_ops);	if (!ret) {		struct seq_file *sf = file->private_data;		sf->private = PDE(inode);	}	return ret;};static struct file_operations neigh_stat_seq_fops = {	.owner	 = THIS_MODULE,	.open 	 = neigh_stat_seq_open,	.read	 = seq_read,	.llseek	 = seq_lseek,	.release = seq_release,};#endif /* CONFIG_PROC_FS */#ifdef CONFIG_ARPDvoid neigh_app_ns(struct neighbour *n){	struct nlmsghdr  *nlh;	int size = NLMSG_SPACE(sizeof(struct ndmsg) + 256);	struct sk_buff *skb = alloc_skb(size, GFP_ATOMIC);	if (!skb)		return;	if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH) < 0) {		kfree_skb(skb);		return;	}	nlh			   = (struct nlmsghdr *)skb->data;	nlh->nlmsg_flags	   = NLM_F_REQUEST;	NETLINK_CB(skb).dst_groups = RTMGRP_NEIGH;	netlink_broadcast(rtnl, skb, 0, RTMGRP_NEIGH, GFP_ATOMIC);}static void neigh_app_notify(struct neighbour *n){	struct nlmsghdr *nlh;	int size = NLMSG_SPACE(sizeof(struct ndmsg) + 256);	struct sk_buff *skb = alloc_skb(size, GFP_ATOMIC);	if (!skb)		return;	if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH) < 0) {		kfree_skb(skb);		return;	}	nlh			   = (struct nlmsghdr *)skb->data;	NETLINK_CB(skb).dst_groups = RTMGRP_NEIGH;	netlink_broadcast(rtnl, skb, 0, RTMGRP_NEIGH, GFP_ATOMIC);}#endif /* CONFIG_ARPD */#ifdef CONFIG_SYSCTLstatic struct neigh_sysctl_table {	struct ctl_table_header *sysctl_header;	ctl_table		neigh_vars[17];	ctl_table		neigh_dev[2];	ctl_table		neigh_neigh_dir[2];	ctl_table		neigh_proto_dir[2];	ctl_table		neigh_root_dir[2];} neigh_sysctl_template = {	.neigh_vars = {		{			.ctl_name	= NET_NEIGH_MCAST_SOLICIT,			.procname	= "mcast_solicit",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_UCAST_SOLICIT,			.procname	= "ucast_solicit",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_APP_SOLICIT,			.procname	= "app_solicit",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_RETRANS_TIME,			.procname	= "retrans_time",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_userhz_jiffies,		},		{			.ctl_name	= NET_NEIGH_REACHABLE_TIME,			.procname	= "base_reachable_time",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_jiffies,			.strategy	= &sysctl_jiffies,		},		{			.ctl_name	= NET_NEIGH_DELAY_PROBE_TIME,			.procname	= "delay_first_probe_time",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_jiffies,			.strategy	= &sysctl_jiffies,		},		{			.ctl_name	= NET_NEIGH_GC_STALE_TIME,			.procname	= "gc_stale_time",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_jiffies,			.strategy	= &sysctl_jiffies,		},		{			.ctl_name	= NET_NEIGH_UNRES_QLEN,			.procname	= "unres_qlen",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_PROXY_QLEN,			.procname	= "proxy_qlen",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_ANYCAST_DELAY,			.procname	= "anycast_delay",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_userhz_jiffies,		},		{			.ctl_name	= NET_NEIGH_PROXY_DELAY,			.procname	= "proxy_delay",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_userhz_jiffies,		},		{			.ctl_name	= NET_NEIGH_LOCKTIME,			.procname	= "locktime",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_userhz_jiffies,		},		{			.ctl_name	= NET_NEIGH_GC_INTERVAL,			.procname	= "gc_interval",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec_jiffies,			.strategy	= &sysctl_jiffies,		},		{			.ctl_name	= NET_NEIGH_GC_THRESH1,			.procname	= "gc_thresh1",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_GC_THRESH2,			.procname	= "gc_thresh2",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},		{			.ctl_name	= NET_NEIGH_GC_THRESH3,			.procname	= "gc_thresh3",			.maxlen		= sizeof(int),			.mode		= 0644,			.proc_handler	= &proc_dointvec,		},	},	.neigh_dev = {		{			.ctl_name	= NET_PROTO_CONF_DEFAULT,			.procname	= "default",			.mode		= 0555,		},	},	.neigh_neigh_dir = {		{			.procname	= "neigh",			.mode		= 0555,		},	},	.neigh_proto_dir = {		{			.mode		= 0555,		},	},	.neigh_root_dir = {		{			.ctl_name	= CTL_NET,			.procname	= "net",			.mode		= 0555,		},	},};int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,			  int p_id, int pdev_id, char *p_name, 			  proc_handler *handler){	struct neigh_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL);	const char *dev_name_source = NULL;	char *dev_name = NULL;	int err = 0;	if (!t)		return -ENOBUFS;	memcpy(t, &neigh_sysctl_template, sizeof(*t));	t->neigh_vars[0].data  = &p->mcast_probes;	t->neigh_vars[1].data  = &p->ucast_probes;	t->neigh_vars[2].data  = &p->app_probes;	t->neigh_vars[3].data  = &p->retrans_time;	if (handler) {		t->neigh_vars[3].proc_handler = handler;		t->neigh_vars[3].extra1 = dev;	}	t->neigh_vars[4].data  = &p->base_reachable_time;	t->neigh_vars[5].data  = &p->delay_probe_time;	t->neigh_vars[6].data  = &p->gc_staletime;	t->neigh_vars[7].data  = &p->queue_len;	t->neigh_vars[8].data  = &p->proxy_qlen;	t->neigh_vars[9].data  = &p->anycast_delay;	t->neigh_vars[10].data = &p->proxy_delay;	t->neigh_vars[11].data = &p->locktime; 	dev_name_source = t->neigh_dev[0].procname;	if (dev) {		dev_name_source = dev->name;		t->neigh_dev[0].ctl_name = dev->ifindex;		memset(&t->neigh_vars[12], 0, sizeof(ctl_table));	} else {		t->neigh_vars[12].data = (int *)(p + 1);		t->neigh_vars[13].data = (int *)(p + 1) + 1;		t->neigh_vars[14].data = (int *)(p + 1) + 2;		t->neigh_vars[15].data = (int *)(p + 1) + 3;	}	dev_name = net_sysctl_strdup(dev_name_source);	if (!dev_name) {		err = -ENOBUFS;		goto free;	} 	t->neigh_dev[0].procname = dev_name;	t->neigh_neigh_dir[0].ctl_name = pdev_id;	t->neigh_proto_dir[0].procname = p_name;	t->neigh_proto_dir[0].ctl_name = p_id;	t->neigh_dev[0].child	       = t->neigh_vars;	t->neigh_neigh_dir[0].child    = t->neigh_dev;	t->neigh_proto_dir[0].child    = t->neigh_neigh_dir;	t->neigh_root_dir[0].child     = t->neigh_proto_dir;	t->sysctl_header = register_sysctl_table(t->neigh_root_dir, 0);	if (!t->sysctl_header) {		err = -ENOBUFS;		goto free_procname;	}	p->sysctl_table = t;	return 0;	/* error path */ free_procname:	kfree(dev_name); free:	kfree(t);	return err;}void neigh_sysctl_unregister(struct neigh_parms *p){	if (p->sysctl_table) {		struct neigh_sysctl_table *t = p->sysctl_table;		p->sysctl_table = NULL;		unregister_sysctl_table(t->sysctl_header);		kfree(t->neigh_dev[0].procname);		kfree(t);	}}#endif	/* CONFIG_SYSCTL */EXPORT_SYMBOL(__neigh_event_send);EXPORT_SYMBOL(neigh_add);EXPORT_SYMBOL(neigh_changeaddr);EXPORT_SYMBOL(neigh_compat_output);EXPORT_SYMBOL(neigh_connected_output);EXPORT_SYMBOL(neigh_create);EXPORT_SYMBOL(neigh_delete);EXPORT_SYMBOL(neigh_destroy);EXPORT_SYMBOL(neigh_dump_info);EXPORT_SYMBOL(neigh_event_ns);EXPORT_SYMBOL(neigh_ifdown);EXPORT_SYMBOL(neigh_lookup);EXPORT_SYMBOL(neigh_lookup_nodev);EXPORT_SYMBOL(neigh_parms_alloc);EXPORT_SYMBOL(neigh_parms_release);EXPORT_SYMBOL(neigh_rand_reach_time);EXPORT_SYMBOL(neigh_resolve_output);EXPORT_SYMBOL(neigh_table_clear);EXPORT_SYMBOL(neigh_table_init);EXPORT_SYMBOL(neigh_update);EXPORT_SYMBOL(neigh_update_hhs);EXPORT_SYMBOL(pneigh_enqueue);EXPORT_SYMBOL(pneigh_lookup);#ifdef CONFIG_ARPDEXPORT_SYMBOL(neigh_app_ns);#endif#ifdef CONFIG_SYSCTLEXPORT_SYMBOL(neigh_sysctl_register);EXPORT_SYMBOL(neigh_sysctl_unregister);#endif

⌨️ 快捷键说明

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