summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGautam Kachroo <gk@aristanetworks.com>2009-02-06 00:52:04 -0800
committerDavid S. Miller <davem@davemloft.net>2009-02-06 00:52:04 -0800
commitefc683fc2a692735029067b4f939af2a3625e31d (patch)
treed1961466cef6bae0cfa44f656a909ef8349b56c6
parent684de409acff8b1fe8bf188d75ff2f99c624387d (diff)
neigh: some entries can be skipped during dumping
neightbl_dump_info and neigh_dump_table can skip entries if the *fill*info functions return an error. This results in an incomplete dump ((invoked by netlink requests for RTM_GETNEIGHTBL or RTM_GETNEIGH) nidx and idx should not be incremented if the current entry was not placed in the output buffer Signed-off-by: Gautam Kachroo <gk@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/neighbour.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index f66c58df895..278a142d104 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1994,8 +1994,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
if (!net_eq(neigh_parms_net(p), net))
continue;
- if (nidx++ < neigh_skip)
- continue;
+ if (nidx < neigh_skip)
+ goto next;
if (neightbl_fill_param_info(skb, tbl, p,
NETLINK_CB(cb->skb).pid,
@@ -2003,6 +2003,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
RTM_NEWNEIGHTBL,
NLM_F_MULTI) <= 0)
goto out;
+ next:
+ nidx++;
}
neigh_skip = 0;
@@ -2082,12 +2084,10 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
if (h > s_h)
s_idx = 0;
for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
- int lidx;
if (dev_net(n->dev) != net)
continue;
- lidx = idx++;
- if (lidx < s_idx)
- continue;
+ if (idx < s_idx)
+ goto next;
if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
@@ -2096,6 +2096,8 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
rc = -1;
goto out;
}
+ next:
+ idx++;
}
}
read_unlock_bh(&tbl->lock);