mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	neigh: remove dynamic neigh table registration support
Currently there are only three neigh tables in the whole kernel: arp table, ndisc table and decnet neigh table. What's more, we don't support registering multiple tables per family. Therefore we can just make these tables statically built-in. Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									b2e2f0c779
								
							
						
					
					
						commit
						d7480fd3b1
					
				
					 5 changed files with 133 additions and 149 deletions
				
			
		| 
						 | 
				
			
			@ -220,6 +220,13 @@ struct neigh_table {
 | 
			
		|||
	struct pneigh_entry	**phash_buckets;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	NEIGH_ARP_TABLE = 0,
 | 
			
		||||
	NEIGH_ND_TABLE = 1,
 | 
			
		||||
	NEIGH_DN_TABLE = 2,
 | 
			
		||||
	NEIGH_NR_TABLES,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int neigh_parms_family(struct neigh_parms *p)
 | 
			
		||||
{
 | 
			
		||||
	return p->tbl->family;
 | 
			
		||||
| 
						 | 
				
			
			@ -240,8 +247,8 @@ static inline void *neighbour_priv(const struct neighbour *n)
 | 
			
		|||
#define NEIGH_UPDATE_F_ISROUTER			0x40000000
 | 
			
		||||
#define NEIGH_UPDATE_F_ADMIN			0x80000000
 | 
			
		||||
 | 
			
		||||
void neigh_table_init(struct neigh_table *tbl);
 | 
			
		||||
int neigh_table_clear(struct neigh_table *tbl);
 | 
			
		||||
void neigh_table_init(int index, struct neigh_table *tbl);
 | 
			
		||||
int neigh_table_clear(int index, struct neigh_table *tbl);
 | 
			
		||||
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
 | 
			
		||||
			       struct net_device *dev);
 | 
			
		||||
struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,6 @@ static void __neigh_notify(struct neighbour *n, int type, int flags);
 | 
			
		|||
static void neigh_update_notify(struct neighbour *neigh);
 | 
			
		||||
static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 | 
			
		||||
 | 
			
		||||
static struct neigh_table *neigh_tables;
 | 
			
		||||
#ifdef CONFIG_PROC_FS
 | 
			
		||||
static const struct file_operations neigh_stat_seq_fops;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -87,13 +86,8 @@ static const struct file_operations neigh_stat_seq_fops;
 | 
			
		|||
   the most complicated procedure, which we allow is dev->hard_header.
 | 
			
		||||
   It is supposed, that dev->hard_header is simplistic and does
 | 
			
		||||
   not make callbacks to neighbour tables.
 | 
			
		||||
 | 
			
		||||
   The last lock is neigh_tbl_lock. It is pure SMP lock, protecting
 | 
			
		||||
   list of neighbour tables. This list is used only in process context,
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static DEFINE_RWLOCK(neigh_tbl_lock);
 | 
			
		||||
 | 
			
		||||
static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb)
 | 
			
		||||
{
 | 
			
		||||
	kfree_skb(skb);
 | 
			
		||||
| 
						 | 
				
			
			@ -1520,7 +1514,9 @@ static void neigh_parms_destroy(struct neigh_parms *parms)
 | 
			
		|||
 | 
			
		||||
static struct lock_class_key neigh_table_proxy_queue_class;
 | 
			
		||||
 | 
			
		||||
static void neigh_table_init_no_netlink(struct neigh_table *tbl)
 | 
			
		||||
static struct neigh_table *neigh_tables[NEIGH_NR_TABLES] __read_mostly;
 | 
			
		||||
 | 
			
		||||
void neigh_table_init(int index, struct neigh_table *tbl)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long now = jiffies;
 | 
			
		||||
	unsigned long phsize;
 | 
			
		||||
| 
						 | 
				
			
			@ -1566,34 +1562,14 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl)
 | 
			
		|||
 | 
			
		||||
	tbl->last_flush = now;
 | 
			
		||||
	tbl->last_rand	= now + tbl->parms.reachable_time * 20;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void neigh_table_init(struct neigh_table *tbl)
 | 
			
		||||
{
 | 
			
		||||
	struct neigh_table *tmp;
 | 
			
		||||
 | 
			
		||||
	neigh_table_init_no_netlink(tbl);
 | 
			
		||||
	write_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tmp = neigh_tables; tmp; tmp = tmp->next) {
 | 
			
		||||
		if (tmp->family == tbl->family)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	tbl->next	= neigh_tables;
 | 
			
		||||
	neigh_tables	= tbl;
 | 
			
		||||
	write_unlock(&neigh_tbl_lock);
 | 
			
		||||
 | 
			
		||||
	if (unlikely(tmp)) {
 | 
			
		||||
		pr_err("Registering multiple tables for family %d\n",
 | 
			
		||||
		       tbl->family);
 | 
			
		||||
		dump_stack();
 | 
			
		||||
	}
 | 
			
		||||
	neigh_tables[index] = tbl;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(neigh_table_init);
 | 
			
		||||
 | 
			
		||||
int neigh_table_clear(struct neigh_table *tbl)
 | 
			
		||||
int neigh_table_clear(int index, struct neigh_table *tbl)
 | 
			
		||||
{
 | 
			
		||||
	struct neigh_table **tp;
 | 
			
		||||
 | 
			
		||||
	neigh_tables[index] = NULL;
 | 
			
		||||
	/* It is not clean... Fix it to unload IPv6 module safely */
 | 
			
		||||
	cancel_delayed_work_sync(&tbl->gc_work);
 | 
			
		||||
	del_timer_sync(&tbl->proxy_timer);
 | 
			
		||||
| 
						 | 
				
			
			@ -1601,14 +1577,6 @@ int neigh_table_clear(struct neigh_table *tbl)
 | 
			
		|||
	neigh_ifdown(tbl, NULL);
 | 
			
		||||
	if (atomic_read(&tbl->entries))
 | 
			
		||||
		pr_crit("neighbour leakage\n");
 | 
			
		||||
	write_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tp = &neigh_tables; *tp; tp = &(*tp)->next) {
 | 
			
		||||
		if (*tp == tbl) {
 | 
			
		||||
			*tp = tbl->next;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	write_unlock(&neigh_tbl_lock);
 | 
			
		||||
 | 
			
		||||
	call_rcu(&rcu_dereference_protected(tbl->nht, 1)->rcu,
 | 
			
		||||
		 neigh_hash_free_rcu);
 | 
			
		||||
| 
						 | 
				
			
			@ -1626,12 +1594,32 @@ int neigh_table_clear(struct neigh_table *tbl)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(neigh_table_clear);
 | 
			
		||||
 | 
			
		||||
static struct neigh_table *neigh_find_table(int family)
 | 
			
		||||
{
 | 
			
		||||
	struct neigh_table *tbl = NULL;
 | 
			
		||||
 | 
			
		||||
	switch (family) {
 | 
			
		||||
	case AF_INET:
 | 
			
		||||
		tbl = neigh_tables[NEIGH_ARP_TABLE];
 | 
			
		||||
		break;
 | 
			
		||||
	case AF_INET6:
 | 
			
		||||
		tbl = neigh_tables[NEIGH_ND_TABLE];
 | 
			
		||||
		break;
 | 
			
		||||
	case AF_DECnet:
 | 
			
		||||
		tbl = neigh_tables[NEIGH_DN_TABLE];
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return tbl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		||||
{
 | 
			
		||||
	struct net *net = sock_net(skb->sk);
 | 
			
		||||
	struct ndmsg *ndm;
 | 
			
		||||
	struct nlattr *dst_attr;
 | 
			
		||||
	struct neigh_table *tbl;
 | 
			
		||||
	struct neighbour *neigh;
 | 
			
		||||
	struct net_device *dev = NULL;
 | 
			
		||||
	int err = -EINVAL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1652,39 +1640,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	read_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tbl = neigh_tables; tbl; tbl = tbl->next) {
 | 
			
		||||
		struct neighbour *neigh;
 | 
			
		||||
	tbl = neigh_find_table(ndm->ndm_family);
 | 
			
		||||
	if (tbl == NULL)
 | 
			
		||||
		return -EAFNOSUPPORT;
 | 
			
		||||
 | 
			
		||||
		if (tbl->family != ndm->ndm_family)
 | 
			
		||||
			continue;
 | 
			
		||||
		read_unlock(&neigh_tbl_lock);
 | 
			
		||||
	if (nla_len(dst_attr) < tbl->key_len)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
		if (nla_len(dst_attr) < tbl->key_len)
 | 
			
		||||
			goto out;
 | 
			
		||||
 | 
			
		||||
		if (ndm->ndm_flags & NTF_PROXY) {
 | 
			
		||||
			err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (dev == NULL)
 | 
			
		||||
			goto out;
 | 
			
		||||
 | 
			
		||||
		neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
 | 
			
		||||
		if (neigh == NULL) {
 | 
			
		||||
			err = -ENOENT;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		err = neigh_update(neigh, NULL, NUD_FAILED,
 | 
			
		||||
				   NEIGH_UPDATE_F_OVERRIDE |
 | 
			
		||||
				   NEIGH_UPDATE_F_ADMIN);
 | 
			
		||||
		neigh_release(neigh);
 | 
			
		||||
	if (ndm->ndm_flags & NTF_PROXY) {
 | 
			
		||||
		err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
	read_unlock(&neigh_tbl_lock);
 | 
			
		||||
	err = -EAFNOSUPPORT;
 | 
			
		||||
 | 
			
		||||
	if (dev == NULL)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	neigh = neigh_lookup(tbl, nla_data(dst_attr), dev);
 | 
			
		||||
	if (neigh == NULL) {
 | 
			
		||||
		err = -ENOENT;
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = neigh_update(neigh, NULL, NUD_FAILED,
 | 
			
		||||
			   NEIGH_UPDATE_F_OVERRIDE |
 | 
			
		||||
			   NEIGH_UPDATE_F_ADMIN);
 | 
			
		||||
	neigh_release(neigh);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return err;
 | 
			
		||||
| 
						 | 
				
			
			@ -1692,11 +1672,14 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
 | 
			
		||||
static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		||||
{
 | 
			
		||||
	int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE;
 | 
			
		||||
	struct net *net = sock_net(skb->sk);
 | 
			
		||||
	struct ndmsg *ndm;
 | 
			
		||||
	struct nlattr *tb[NDA_MAX+1];
 | 
			
		||||
	struct neigh_table *tbl;
 | 
			
		||||
	struct net_device *dev = NULL;
 | 
			
		||||
	struct neighbour *neigh;
 | 
			
		||||
	void *dst, *lladdr;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	ASSERT_RTNL();
 | 
			
		||||
| 
						 | 
				
			
			@ -1720,70 +1703,60 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
			goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	read_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tbl = neigh_tables; tbl; tbl = tbl->next) {
 | 
			
		||||
		int flags = NEIGH_UPDATE_F_ADMIN | NEIGH_UPDATE_F_OVERRIDE;
 | 
			
		||||
		struct neighbour *neigh;
 | 
			
		||||
		void *dst, *lladdr;
 | 
			
		||||
	tbl = neigh_find_table(ndm->ndm_family);
 | 
			
		||||
	if (tbl == NULL)
 | 
			
		||||
		return -EAFNOSUPPORT;
 | 
			
		||||
 | 
			
		||||
		if (tbl->family != ndm->ndm_family)
 | 
			
		||||
			continue;
 | 
			
		||||
		read_unlock(&neigh_tbl_lock);
 | 
			
		||||
	if (nla_len(tb[NDA_DST]) < tbl->key_len)
 | 
			
		||||
		goto out;
 | 
			
		||||
	dst = nla_data(tb[NDA_DST]);
 | 
			
		||||
	lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
 | 
			
		||||
 | 
			
		||||
		if (nla_len(tb[NDA_DST]) < tbl->key_len)
 | 
			
		||||
			goto out;
 | 
			
		||||
		dst = nla_data(tb[NDA_DST]);
 | 
			
		||||
		lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL;
 | 
			
		||||
	if (ndm->ndm_flags & NTF_PROXY) {
 | 
			
		||||
		struct pneigh_entry *pn;
 | 
			
		||||
 | 
			
		||||
		if (ndm->ndm_flags & NTF_PROXY) {
 | 
			
		||||
			struct pneigh_entry *pn;
 | 
			
		||||
 | 
			
		||||
			err = -ENOBUFS;
 | 
			
		||||
			pn = pneigh_lookup(tbl, net, dst, dev, 1);
 | 
			
		||||
			if (pn) {
 | 
			
		||||
				pn->flags = ndm->ndm_flags;
 | 
			
		||||
				err = 0;
 | 
			
		||||
			}
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (dev == NULL)
 | 
			
		||||
			goto out;
 | 
			
		||||
 | 
			
		||||
		neigh = neigh_lookup(tbl, dst, dev);
 | 
			
		||||
		if (neigh == NULL) {
 | 
			
		||||
			if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
 | 
			
		||||
				err = -ENOENT;
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			neigh = __neigh_lookup_errno(tbl, dst, dev);
 | 
			
		||||
			if (IS_ERR(neigh)) {
 | 
			
		||||
				err = PTR_ERR(neigh);
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (nlh->nlmsg_flags & NLM_F_EXCL) {
 | 
			
		||||
				err = -EEXIST;
 | 
			
		||||
				neigh_release(neigh);
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
 | 
			
		||||
				flags &= ~NEIGH_UPDATE_F_OVERRIDE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ndm->ndm_flags & NTF_USE) {
 | 
			
		||||
			neigh_event_send(neigh, NULL);
 | 
			
		||||
		err = -ENOBUFS;
 | 
			
		||||
		pn = pneigh_lookup(tbl, net, dst, dev, 1);
 | 
			
		||||
		if (pn) {
 | 
			
		||||
			pn->flags = ndm->ndm_flags;
 | 
			
		||||
			err = 0;
 | 
			
		||||
		} else
 | 
			
		||||
			err = neigh_update(neigh, lladdr, ndm->ndm_state, flags);
 | 
			
		||||
		neigh_release(neigh);
 | 
			
		||||
		}
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	read_unlock(&neigh_tbl_lock);
 | 
			
		||||
	err = -EAFNOSUPPORT;
 | 
			
		||||
	if (dev == NULL)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	neigh = neigh_lookup(tbl, dst, dev);
 | 
			
		||||
	if (neigh == NULL) {
 | 
			
		||||
		if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
 | 
			
		||||
			err = -ENOENT;
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		neigh = __neigh_lookup_errno(tbl, dst, dev);
 | 
			
		||||
		if (IS_ERR(neigh)) {
 | 
			
		||||
			err = PTR_ERR(neigh);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if (nlh->nlmsg_flags & NLM_F_EXCL) {
 | 
			
		||||
			err = -EEXIST;
 | 
			
		||||
			neigh_release(neigh);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(nlh->nlmsg_flags & NLM_F_REPLACE))
 | 
			
		||||
			flags &= ~NEIGH_UPDATE_F_OVERRIDE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ndm->ndm_flags & NTF_USE) {
 | 
			
		||||
		neigh_event_send(neigh, NULL);
 | 
			
		||||
		err = 0;
 | 
			
		||||
	} else
 | 
			
		||||
		err = neigh_update(neigh, lladdr, ndm->ndm_state, flags);
 | 
			
		||||
	neigh_release(neigh);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1982,7 +1955,8 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
	struct neigh_table *tbl;
 | 
			
		||||
	struct ndtmsg *ndtmsg;
 | 
			
		||||
	struct nlattr *tb[NDTA_MAX+1];
 | 
			
		||||
	int err;
 | 
			
		||||
	bool found = false;
 | 
			
		||||
	int err, tidx;
 | 
			
		||||
 | 
			
		||||
	err = nlmsg_parse(nlh, sizeof(*ndtmsg), tb, NDTA_MAX,
 | 
			
		||||
			  nl_neightbl_policy);
 | 
			
		||||
| 
						 | 
				
			
			@ -1995,19 +1969,21 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	ndtmsg = nlmsg_data(nlh);
 | 
			
		||||
	read_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tbl = neigh_tables; tbl; tbl = tbl->next) {
 | 
			
		||||
 | 
			
		||||
	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
 | 
			
		||||
		tbl = neigh_tables[tidx];
 | 
			
		||||
		if (!tbl)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0)
 | 
			
		||||
		if (nla_strcmp(tb[NDTA_NAME], tbl->id) == 0) {
 | 
			
		||||
			found = true;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tbl == NULL) {
 | 
			
		||||
		err = -ENOENT;
 | 
			
		||||
		goto errout_locked;
 | 
			
		||||
	}
 | 
			
		||||
	if (!found)
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We acquire tbl->lock to be nice to the periodic timers and
 | 
			
		||||
| 
						 | 
				
			
			@ -2118,8 +2094,6 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh)
 | 
			
		|||
 | 
			
		||||
errout_tbl_lock:
 | 
			
		||||
	write_unlock_bh(&tbl->lock);
 | 
			
		||||
errout_locked:
 | 
			
		||||
	read_unlock(&neigh_tbl_lock);
 | 
			
		||||
errout:
 | 
			
		||||
	return err;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2134,10 +2108,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 | 
			
		|||
 | 
			
		||||
	family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
 | 
			
		||||
 | 
			
		||||
	read_lock(&neigh_tbl_lock);
 | 
			
		||||
	for (tbl = neigh_tables, tidx = 0; tbl; tbl = tbl->next, tidx++) {
 | 
			
		||||
	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
 | 
			
		||||
		struct neigh_parms *p;
 | 
			
		||||
 | 
			
		||||
		tbl = neigh_tables[tidx];
 | 
			
		||||
		if (!tbl)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (tidx < tbl_skip || (family && tbl->family != family))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2168,7 +2145,6 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 | 
			
		|||
		neigh_skip = 0;
 | 
			
		||||
	}
 | 
			
		||||
out:
 | 
			
		||||
	read_unlock(&neigh_tbl_lock);
 | 
			
		||||
	cb->args[0] = tidx;
 | 
			
		||||
	cb->args[1] = nidx;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2351,7 +2327,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 | 
			
		|||
	int proxy = 0;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	read_lock(&neigh_tbl_lock);
 | 
			
		||||
	family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
 | 
			
		||||
 | 
			
		||||
	/* check for full ndmsg structure presence, family member is
 | 
			
		||||
| 
						 | 
				
			
			@ -2363,8 +2338,11 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 | 
			
		|||
 | 
			
		||||
	s_t = cb->args[0];
 | 
			
		||||
 | 
			
		||||
	for (tbl = neigh_tables, t = 0; tbl;
 | 
			
		||||
	     tbl = tbl->next, t++) {
 | 
			
		||||
	for (t = 0; t < NEIGH_NR_TABLES; t++) {
 | 
			
		||||
		tbl = neigh_tables[t];
 | 
			
		||||
 | 
			
		||||
		if (!tbl)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (t < s_t || (family && tbl->family != family))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (t > s_t)
 | 
			
		||||
| 
						 | 
				
			
			@ -2377,7 +2355,6 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 | 
			
		|||
		if (err < 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	read_unlock(&neigh_tbl_lock);
 | 
			
		||||
 | 
			
		||||
	cb->args[0] = t;
 | 
			
		||||
	return skb->len;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -591,7 +591,7 @@ static const struct file_operations dn_neigh_seq_fops = {
 | 
			
		|||
 | 
			
		||||
void __init dn_neigh_init(void)
 | 
			
		||||
{
 | 
			
		||||
	neigh_table_init(&dn_neigh_table);
 | 
			
		||||
	neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table);
 | 
			
		||||
	proc_create("decnet_neigh", S_IRUGO, init_net.proc_net,
 | 
			
		||||
		    &dn_neigh_seq_fops);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -599,5 +599,5 @@ void __init dn_neigh_init(void)
 | 
			
		|||
void __exit dn_neigh_cleanup(void)
 | 
			
		||||
{
 | 
			
		||||
	remove_proc_entry("decnet_neigh", init_net.proc_net);
 | 
			
		||||
	neigh_table_clear(&dn_neigh_table);
 | 
			
		||||
	neigh_table_clear(NEIGH_DN_TABLE, &dn_neigh_table);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1292,7 +1292,7 @@ static int arp_proc_init(void);
 | 
			
		|||
 | 
			
		||||
void __init arp_init(void)
 | 
			
		||||
{
 | 
			
		||||
	neigh_table_init(&arp_tbl);
 | 
			
		||||
	neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl);
 | 
			
		||||
 | 
			
		||||
	dev_add_pack(&arp_packet_type);
 | 
			
		||||
	arp_proc_init();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1763,7 +1763,7 @@ int __init ndisc_init(void)
 | 
			
		|||
	/*
 | 
			
		||||
	 * Initialize the neighbour table
 | 
			
		||||
	 */
 | 
			
		||||
	neigh_table_init(&nd_tbl);
 | 
			
		||||
	neigh_table_init(NEIGH_ND_TABLE, &nd_tbl);
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SYSCTL
 | 
			
		||||
	err = neigh_sysctl_register(NULL, &nd_tbl.parms,
 | 
			
		||||
| 
						 | 
				
			
			@ -1796,6 +1796,6 @@ void ndisc_cleanup(void)
 | 
			
		|||
#ifdef CONFIG_SYSCTL
 | 
			
		||||
	neigh_sysctl_unregister(&nd_tbl.parms);
 | 
			
		||||
#endif
 | 
			
		||||
	neigh_table_clear(&nd_tbl);
 | 
			
		||||
	neigh_table_clear(NEIGH_ND_TABLE, &nd_tbl);
 | 
			
		||||
	unregister_pernet_subsys(&ndisc_net_ops);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue