diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2006-05-12 17:56:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-05-12 17:56:08 -0400 |
commit | bd89efc532fe41f867f848144cc8b42054ddf6f9 (patch) | |
tree | fcf90049cb5a15bf6689cdbc6038c3fe22079009 /include/net | |
parent | ef34814426862c41c061520d4ac833be5914b5ba (diff) |
[NEIGH]: Fix IP-over-ATM and ARP interaction.
The classical IP over ATM code maintains its own IPv4 <-> <ATM stuff>
ARP table, using the standard neighbour-table code. The
neigh_table_init function adds this neighbour table to a linked list
of all neighbor tables which is used by the functions neigh_delete()
neigh_add() and neightbl_set(), all called by the netlink code.
Once the ATM neighbour table is added to the list, there are two
tables with family == AF_INET there, and ARP entries sent via netlink
go into the first table with matching family. This is indeterminate
and often wrong.
To see the bug, on a kernel with CLIP enabled, create a standard IPv4
ARP entry by pinging an unused address on a local subnet. Then attempt
to complete that entry by doing
ip neigh replace <ip address> lladdr <some mac address> nud reachable
Looking at the ARP tables by using
ip neigh show
will reveal two ARP entries for the same address. One of these can be
found in /proc/net/arp, and the other in /proc/net/atm/arp.
This patch adds a new function, neigh_table_init_no_netlink() which
does everything the neigh_table_init() does, except add the table to
the netlink all-arp-tables chain. In addition neigh_table_init() has a
check that all tables on the chain have a distinct address family.
The init call in clip.c is changed to call
neigh_table_init_no_netlink().
Since ATM ARP tables are rather more complicated than can currently be
handled by the available rtattrs in the netlink protocol, no
functionality is lost by this patch, and non-ATM ARP manipulation via
netlink is rescued. A more complete solution would involve a rtattr
for ATM ARP entries and some way for the netlink code to give
neigh_add and friends more information than just address family with
which to find the correct ARP table.
[ I've changed the assertion checking in neigh_table_init() to not
use BUG_ON() while holding neigh_tbl_lock. Instead we remember that
we found an existing tbl with the same family, and after dropping
the lock we'll give a diagnostic kernel log message and a stack dump.
-DaveM ]
Signed-off-by: Simon Kelley <simon@thekelleys.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/neighbour.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index b0666d66293..4901ee44687 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -211,6 +211,7 @@ struct neigh_table | |||
211 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 | 211 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 |
212 | 212 | ||
213 | extern void neigh_table_init(struct neigh_table *tbl); | 213 | extern void neigh_table_init(struct neigh_table *tbl); |
214 | extern void neigh_table_init_no_netlink(struct neigh_table *tbl); | ||
214 | extern int neigh_table_clear(struct neigh_table *tbl); | 215 | extern int neigh_table_clear(struct neigh_table *tbl); |
215 | extern struct neighbour * neigh_lookup(struct neigh_table *tbl, | 216 | extern struct neighbour * neigh_lookup(struct neigh_table *tbl, |
216 | const void *pkey, | 217 | const void *pkey, |