mirror of https://github.com/torvalds/linux.git
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> |
||
|---|---|---|
| .. | ||
| bluetooth | ||
| irda | ||
| netfilter | ||
| sctp | ||
| tc_act | ||
| tipc | ||
| act_api.h | ||
| act_generic.h | ||
| addrconf.h | ||
| af_unix.h | ||
| ah.h | ||
| arp.h | ||
| atmclip.h | ||
| ax25.h | ||
| checksum.h | ||
| compat.h | ||
| datalink.h | ||
| dn.h | ||
| dn_dev.h | ||
| dn_fib.h | ||
| dn_neigh.h | ||
| dn_nsp.h | ||
| dn_route.h | ||
| dsfield.h | ||
| dst.h | ||
| esp.h | ||
| flow.h | ||
| gen_stats.h | ||
| genetlink.h | ||
| icmp.h | ||
| ieee80211.h | ||
| ieee80211_crypt.h | ||
| ieee80211_radiotap.h | ||
| ieee80211softmac.h | ||
| ieee80211softmac_wx.h | ||
| if_inet6.h | ||
| inet6_connection_sock.h | ||
| inet6_hashtables.h | ||
| inet_common.h | ||
| inet_connection_sock.h | ||
| inet_ecn.h | ||
| inet_hashtables.h | ||
| inet_sock.h | ||
| inet_timewait_sock.h | ||
| inetpeer.h | ||
| ip.h | ||
| ip6_checksum.h | ||
| ip6_fib.h | ||
| ip6_route.h | ||
| ip6_tunnel.h | ||
| ip_fib.h | ||
| ip_mp_alg.h | ||
| ip_vs.h | ||
| ipcomp.h | ||
| ipconfig.h | ||
| ipip.h | ||
| ipv6.h | ||
| ipx.h | ||
| iw_handler.h | ||
| lapb.h | ||
| llc.h | ||
| llc_c_ac.h | ||
| llc_c_ev.h | ||
| llc_c_st.h | ||
| llc_conn.h | ||
| llc_if.h | ||
| llc_pdu.h | ||
| llc_s_ac.h | ||
| llc_s_ev.h | ||
| llc_s_st.h | ||
| llc_sap.h | ||
| ndisc.h | ||
| neighbour.h | ||
| netlink.h | ||
| netrom.h | ||
| p8022.h | ||
| pkt_act.h | ||
| pkt_cls.h | ||
| pkt_sched.h | ||
| protocol.h | ||
| psnap.h | ||
| raw.h | ||
| rawv6.h | ||
| red.h | ||
| request_sock.h | ||
| rose.h | ||
| route.h | ||
| sch_generic.h | ||
| scm.h | ||
| slhc_vj.h | ||
| snmp.h | ||
| sock.h | ||
| syncppp.h | ||
| tcp.h | ||
| tcp_ecn.h | ||
| tcp_states.h | ||
| timewait_sock.h | ||
| transp_v6.h | ||
| udp.h | ||
| x25.h | ||
| x25device.h | ||
| xfrm.h | ||