From owner-freebsd-net@FreeBSD.ORG Thu Apr 26 14:17:12 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id A1AE7106566B for ; Thu, 26 Apr 2012 14:17:12 +0000 (UTC) (envelope-from qing.li@bluecoat.com) Received: from plsvl-mailgw-02.bluecoat.com (plsvl-mailgw-02.bluecoat.com [199.91.133.12]) by mx1.freebsd.org (Postfix) with ESMTP id 75E818FC14 for ; Thu, 26 Apr 2012 14:17:12 +0000 (UTC) Received: from PWSVL-EXCHTS-02.internal.cacheflow.com (unknown [10.2.2.126]) by plsvl-mailgw-02.bluecoat.com (Postfix) with ESMTP id AA7C3200F3; Thu, 26 Apr 2012 07:10:28 -0700 (PDT) Received: from pwsvl-excmbx-05.internal.cacheflow.com ([fe80::f848:d461:9aa9:59a8]) by PWSVL-EXCHTS-02.internal.cacheflow.com ([fe80::4910:317f:407:6ecc%14]) with mapi id 14.01.0289.001; Thu, 26 Apr 2012 07:08:41 -0700 From: "Li, Qing" To: Ryan Stone Thread-Topic: Removing an IPv6 address does not remove NDP entries on that subnet Thread-Index: AQHNI7VX+mMM66qaLkCuQ2Pu1sztrJatJJVQ Date: Thu, 26 Apr 2012 14:08:41 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [199.91.133.85] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Cc: freebsd-net Subject: RE: Removing an IPv6 address does not remove NDP entries on that subnet X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Apr 2012 14:17:12 -0000 Okay, this is good information. I will look into it now. Thanks, --Qing > -----Original Message----- > From: Ryan Stone [mailto:rysto32@gmail.com] > Sent: Thursday, April 26, 2012 7:03 AM > To: Li, Qing > Cc: freebsd-net > Subject: Re: Removing an IPv6 address does not remove NDP entries on > that subnet >=20 > On Wed, Apr 25, 2012 at 3:59 AM, Li, Qing wrote: > > The patch is located at > > > > =A0 http://people.freebsd.org/~qingli/nd6_prefix.diff > > > > Please give it a try. I did only basic testing as of now and > > will do more tomorrow. > > > > --Qing >=20 > I tested this last night. Unfortunately this seems to be vulnerable > to the same races as our current ARP implementation. First, there is > a race between in6_lltable_lookup and in6_lltable_prefix_free. Here > is a crash that I reproduced last night: >=20 > Fatal trap 12: page fault while in kernel mode > cpuid =3D 0; apic id =3D 00 > fault virtual address =3D 0x360 > fault code =3D supervisor read data, page not present > instruction pointer =3D 0x20:0xffffffff808731a2 > stack pointer =3D 0x28:0xffffff80003ea280 > frame pointer =3D 0x28:0xffffff80003ea320 > code segment =3D base 0x0, limit 0xfffff, type 0x1b > =3D DPL 0, pres 1, long 1, def32 0, gran 1 > processor eflags =3D interrupt enabled, resume, IOPL =3D 0 > current process =3D 22170 (nc) > trap number =3D 12 > panic: page fault > cpuid =3D 0 > Uptime: 1h10m28s > Dumping 108 out of 489 MB:..15%..30%..45%..60%..74%..89% >=20 > #0 doadump (textdump=3D1) > at /usr/home/rstone/freebsd/head/sys/kern/kern_shutdown.c:268 > 268 if (textdump && textdump_pending) { > (kgdb) #0 doadump (textdump=3D1) > at /usr/home/rstone/freebsd/head/sys/kern/kern_shutdown.c:268 > #1 0xffffffff808753b9 in kern_reboot (howto=3D260) > at /usr/home/rstone/freebsd/head/sys/kern/kern_shutdown.c:454 > #2 0xffffffff80874dea in panic (fmt=3D0x0) > at /usr/home/rstone/freebsd/head/sys/kern/kern_shutdown.c:642 > #3 0xffffffff80b72860 in trap_fatal (frame=3D0xc, eva=3DVariable "eva" i= s > not avail > able. > ) > at /usr/home/rstone/freebsd/head/sys/amd64/amd64/trap.c:852 > #4 0xffffffff80b72a2a in trap_pfault (frame=3D0xffffff80003ea1d0, > usermode=3D0) > at /usr/home/rstone/freebsd/head/sys/amd64/amd64/trap.c:769 > #5 0xffffffff80b731ea in trap (frame=3D0xffffff80003ea1d0) > at /usr/home/rstone/freebsd/head/sys/amd64/amd64/trap.c:456 > #6 0xffffffff80b5d7c3 in calltrap () > at /usr/home/rstone/freebsd/head/sys/amd64/amd64/exception.S:228 > #7 0xffffffff808731a2 in _rw_rlock (rw=3D0xfffffe00058f3410, > file=3D0xffffffff80df7e40 > "/usr/home/rstone/freebsd/head/sys/netinet6/in6.c", > line=3D2615) at /usr/home/rstone/freebsd/head/sys/kern/kern_rwlock.c:388 > #8 0xffffffff80a27bd9 in in6_lltable_lookup (llt=3D0xfffffe0002422600, > flags=3D0, l3addr=3D0xffffff80003ea6ec) > at /usr/home/rstone/freebsd/head/sys/netinet6/in6.c:2615 > #9 0xffffffff80a409c6 in nd6_storelladdr (ifp=3D0xfffffe000241f000, > m=3D0xfffffe000503d500, dst=3D0xffffff80003ea6ec, > desten=3D0xffffff80003ea430 "\xc0\230\b\005", lle=3D0xffffff80003ea42= 8) > #10 0xffffffff80936f24 in ether_output (ifp=3D0xfffffe000241f000, > m=3D0xfffffe000503d500, dst=3D0xffffff80003ea6ec, ro=3DVariable "ro" = is > not availa > ble. > ) > at /usr/home/rstone/freebsd/head/sys/net/if_ethersubr.c:235 > #11 0xffffffff80a417df in nd6_output_lle (ifp=3D0xfffffe000241f000, > origifp=3D0xfffffe000241f000, m0=3D0xfffffe000503d500, > dst=3D0xffffff80003ea6ec, rt0=3DVariable "rt0" is not available. > ) > at /usr/home/rstone/freebsd/head/sys/netinet6/nd6.c:2081 > #12 0xffffffff80a41a18 in nd6_output (ifp=3DVariable "ifp" is not > available. > ) > at /usr/home/rstone/freebsd/head/sys/netinet6/nd6.c:1828 > #13 0xffffffff80a3c400 in ip6_output (m0=3D0x0, opt=3DVariable "opt" is > not available.) > at /usr/home/rstone/freebsd/head/sys/netinet6/ip6_output.c:1123 > #14 0xffffffff80a4debe in udp6_send (so=3DVariable "so" is not available. > ) > at /usr/home/rstone/freebsd/head/sys/netinet6/udp6_usrreq.c:782 > #15 0xffffffff808e97de in sosend_dgram (so=3D0xfffffe00058d3d48, > addr=3D0x0, uio=3DVariable "uio" is not available. > at /usr/home/rstone/freebsd/head/sys/kern/uipc_socket.c:1118 > #16 0xffffffff808cddad in soo_write (fp=3DVariable "fp" is not available. > ) > at /usr/home/rstone/freebsd/head/sys/kern/sys_socket.c:102 > #17 0xffffffff808c5f25 in dofilewrite (td=3D0xfffffe00050898c0, fd=3D3, > fp=3D0xfffffe0005134000, auio=3D0xffffff80003eaad0, offset=3DVariable > "offset" is > not available. > ) at file.h:271 > #18 0xffffffff808c65ac in kern_writev (td=3D0xfffffe00050898c0, fd=3D3, > auio=3D0xffffff80003eaad0) > at /usr/home/rstone/freebsd/head/sys/kern/sys_generic.c:459 > #19 0xffffffff808c66c4 in sys_write (td=3DVariable "td" is not available. > ) > at /usr/home/rstone/freebsd/head/sys/kern/sys_generic.c:375 > #20 0xffffffff80b71f79 in amd64_syscall (td=3D0xfffffe00050898c0, > traced=3D0) > at subr_syscall.c:135 > #21 0xffffffff80b5daa7 in Xfast_syscall () > at /usr/home/rstone/freebsd/head/sys/amd64/amd64/exception.S:387 >=20 > The line in in6_lltable_lookup that it crashes at (in6.c:2615) is the > LLE_RLOCK at the end of the function. From the vmcore I can see that > the lle was destroyed: >=20 > (kgdb) print *lle > $1 =3D {lle_next =3D {le_next =3D 0xdeadc0dedeadc0de, le_prev =3D > 0xdeadc0dedeadc0de}, > lle_lock =3D {lock_object =3D { > lo_name =3D 0xdeadc0dedeadc0de
bounds>, > lo_flags =3D 3735929054, lo_data =3D 3735929054, > lo_witness =3D 0xdeadc0dedeadc0de}, rw_lock =3D 1604569311084214703= 8}, > lle_tbl =3D 0xdeadc0dedeadc0de, lle_head =3D 0xdeadc0dedeadc0de, > lle_free =3D 0xdeadc0dedeadc0de, la_hold =3D 0xdeadc0dedeadc0de, > la_numheld =3D -559038242, la_expire =3D -2401050962867404578, la_flags= =3D > 49374, > la_asked =3D 57005, la_preempt =3D 49374, ln_byhint =3D 57005, ln_state= =3D - > 16162, > ln_router =3D 57005, ln_ntick =3D -2401050962867404578, lle_refcnt =3D = - > 559038242, > ll_addr =3D {mac_aligned =3D 16045693110842147038, mac16 =3D {49374, 57= 005, > 49374}}, lle_timer =3D {ln_timer_ch =3D {c_links =3D {sle =3D { > sle_next =3D 0xdeadc0dedeadc0de}, tqe =3D { > tqe_next =3D 0xdeadc0dedeadc0de, tqe_prev =3D > 0xdeadc0dedeadc0de}}, > c_time =3D -559038242, c_arg =3D 0xdeadc0dedeadc0de, > c_func =3D 0xdeadc0dedeadc0de, c_lock =3D 0xdeadc0dedeadc0de, > c_flags =3D -559038242, c_cpu =3D -559038242}, la_timer =3D {c_link= s =3D > {sle =3D { > sle_next =3D 0xdeadc0dedeadc0de}, tqe =3D { > tqe_next =3D 0xdeadc0dedeadc0de, tqe_prev =3D > 0xdeadc0dedeadc0de}}, > c_time =3D -559038242, c_arg =3D 0xdeadc0dedeadc0de, > c_func =3D 0xdeadc0dedeadc0de, c_lock =3D 0xdeadc0dedeadc0de, > c_flags =3D -559038242, c_cpu =3D -559038242}}} >=20 >=20 > The test that I was running was I had one ping6 -f going to an IPv6 > address as well as a loop of nc -u. In another terminal I had a > script constantly removing and adding the ipv6 address from which I > was pinging/ncing. >=20 > I haven't looked at the netinet6 code too closely yet but if it > follows the netinet implementation in6_lltable_prefix_free should > acquire the afdata_lock on the ifp before touching the lltable. >=20 >=20 > I haven't tried a test for this yet, but I also believe that > in6_lltable_prefix_free also doesn't drain the callout in the llentry > correctly. I try testing this to confirm this now.