netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).