* [PATCH] fix IP-over-ATM and ARP interaction.
@ 2006-05-06 16:13 Simon Kelley
2006-05-06 16:31 ` YOSHIFUJI Hideaki / 吉藤英明
0 siblings, 1 reply; 2+ messages in thread
From: Simon Kelley @ 2006-05-06 16:13 UTC (permalink / raw)
To: davem, netdev
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.
Signed-off-by: Simon Kelley <simon@thekelleys.org.uk>
--
diff -Naur linux-2.6.16.11.orig/include/net/neighbour.h linux-2.6.16.11/include/net/neighbour.h
--- linux-2.6.16.11.orig/include/net/neighbour.h 2006-04-24 21:20:24.000000000 +0100
+++ linux-2.6.16.11/include/net/neighbour.h 2006-05-04 20:09:17.000000000 +0100
@@ -211,6 +211,7 @@
#define NEIGH_UPDATE_F_ADMIN 0x80000000
extern void neigh_table_init(struct neigh_table *tbl);
+extern void neigh_table_init_no_netlink(struct neigh_table *tbl);
extern int neigh_table_clear(struct neigh_table *tbl);
extern struct neighbour * neigh_lookup(struct neigh_table *tbl,
const void *pkey,
diff -Naur linux-2.6.16.11.orig/net/atm/clip.c linux-2.6.16.11/net/atm/clip.c
--- linux-2.6.16.11.orig/net/atm/clip.c 2006-04-24 21:20:24.000000000 +0100
+++ linux-2.6.16.11/net/atm/clip.c 2006-05-04 20:10:00.000000000 +0100
@@ -995,7 +995,7 @@
static int __init atm_clip_init(void)
{
- neigh_table_init(&clip_tbl);
+ neigh_table_init_no_netlink(&clip_tbl);
clip_tbl_hook = &clip_tbl;
register_atm_ioctl(&clip_ioctl_ops);
diff -Naur linux-2.6.16.11.orig/net/core/neighbour.c linux-2.6.16.11/net/core/neighbour.c
--- linux-2.6.16.11.orig/net/core/neighbour.c 2006-04-24 21:20:24.000000000 +0100
+++ linux-2.6.16.11/net/core/neighbour.c 2006-05-04 20:07:55.000000000 +0100
@@ -1322,8 +1322,7 @@
kfree(parms);
}
-
-void neigh_table_init(struct neigh_table *tbl)
+void neigh_table_init_no_netlink(struct neigh_table *tbl)
{
unsigned long now = jiffies;
unsigned long phsize;
@@ -1381,10 +1380,19 @@
tbl->last_flush = now;
tbl->last_rand = now + tbl->parms.reachable_time * 20;
- write_lock(&neigh_tbl_lock);
- tbl->next = neigh_tables;
- neigh_tables = tbl;
- write_unlock(&neigh_tbl_lock);
+}
+
+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)
+ BUG_ON(tmp->family == tbl->family);
+ tbl->next = neigh_tables;
+ neigh_tables = tbl;
+ write_unlock(&neigh_tbl_lock);
}
int neigh_table_clear(struct neigh_table *tbl)
@@ -2655,6 +2663,7 @@
EXPORT_SYMBOL(neigh_resolve_output);
EXPORT_SYMBOL(neigh_table_clear);
EXPORT_SYMBOL(neigh_table_init);
+EXPORT_SYMBOL(neigh_table_init_no_netlink);
EXPORT_SYMBOL(neigh_update);
EXPORT_SYMBOL(neigh_update_hhs);
EXPORT_SYMBOL(pneigh_enqueue);
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] fix IP-over-ATM and ARP interaction.
2006-05-06 16:13 [PATCH] fix IP-over-ATM and ARP interaction Simon Kelley
@ 2006-05-06 16:31 ` YOSHIFUJI Hideaki / 吉藤英明
0 siblings, 0 replies; 2+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2006-05-06 16:31 UTC (permalink / raw)
To: simon; +Cc: davem, netdev, yoshfuji
In article <E1FcPPN-0004xi-00@thekelleys.org.uk> (at Sat, 06 May 2006 17:13:29 +0100), Simon Kelley <simon@thekelleys.org.uk> says:
> +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)
> + BUG_ON(tmp->family == tbl->family);
> + tbl->next = neigh_tables;
> + neigh_tables = tbl;
> + write_unlock(&neigh_tbl_lock);
> }
>
> int neigh_table_clear(struct neigh_table *tbl)
Please fix the coding style; use tab for indent, please.
--yoshfuji
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-05-06 16:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-06 16:13 [PATCH] fix IP-over-ATM and ARP interaction Simon Kelley
2006-05-06 16:31 ` YOSHIFUJI Hideaki / 吉藤英明
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).