Bug 17909

Summary: Panic when removing a pccard which has a seen an IPv6 router advertisement
Product: Base System Reporter: root <sam>
Component: kernAssignee: itojun
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description root 2000-04-10 20:30:01 UTC
	If a PCMCIA card (3C589D, ep0 device) is present in the laptop and
	is removed after a router advertisement has been seen on the wire,
	the kernel will panic in the next call to nd6_timer. This is due
	to the fact that the prefix/router pair is still present with a
	reference to the now-unexisting interface.

	The panic occurs in in6ifa_ifpwithaddr, called from line 479 of
	nd6.c. The prefix structure clearly shows that the prefix/router
	pair has not been removed (prefix was 3ffe:403:104:a0::/64):

(gdb) where
#0  in6ifa_ifpwithaddr (ifp=0xc0936a00, addr=0xc09024b8)
    at ../../netinet6/in6.c:1339
#1  0xc01db173 in nd6_timer (ignored_arg=0x0) at ../../netinet6/nd6.c:479
#2  0xc0159c65 in softclock () at ../../kern/kern_timeout.c:131
(gdb) fr 1
#1  0xc01db173 in nd6_timer (ignored_arg=0x0) at ../../netinet6/nd6.c:479
(gdb) p *pr
$4 = {ndpr_ifp = 0xc0936a00, ndpr_entry = {le_next = 0x0, 
    le_prev = 0xc02a697c}, ndpr_prefix = {sin6_len = 28 '\034', 
    sin6_family = 28 '\034', sin6_port = 0, sin6_flowinfo = 0, sin6_addr = {
      __u6_addr = {
        __u6_addr8 = "?þ\003\004\001\003\000 \000\000\000\000\000\000\000", 
        __u6_addr16 = {65087, 1027, 769, 40960, 0, 0, 0, 0}, __u6_addr32 = {
          67370559, 2684355329, 0, 0}}}, sin6_scope_id = 0}, ndpr_mask = {
    __u6_addr = {__u6_addr8 = "ÿÿÿÿÿÿÿÿ\000\000\000\000\000\000\000", 
      __u6_addr16 = {65535, 65535, 65535, 65535, 0, 0, 0, 0}, __u6_addr32 = {
        4294967295, 4294967295, 0, 0}}}, ndpr_addr = {__u6_addr = {
      __u6_addr8 = "?þ\003\004\001\003\000 \002`\bÿþC\177Ô", __u6_addr16 = {
        65087, 1027, 769, 40960, 24578, 65288, 17406, 54399}, __u6_addr32 = {
        67370559, 2684355329, 4278738946, 3565110270}}}, 
  ndpr_vltime = 4294967295, ndpr_pltime = 4294967295, ndpr_expire = 0, 
  ndpr_preferred = 0, ndpr_flags = {onlink = 1 '\001', autonomous = 1 '\001', 
    reserved = 0 '\000'}, ndpr_advrtrs = {lh_first = 0xc09a9e70}, 
  ndpr_plen = 64 '@', ndpr_stateflags = {onlink = 1 '\001'}}

	However, the interface is not valid anymore:

(gdb) p *pr->ndpr_ifp
$6 = {if_softc = 0xdeadc0de, if_name = 0xc029e200 "`ä)À°S", if_link = {
    tqe_next = 0xdeadc0de, tqe_prev = 0xc09c5000}, if_addrhead = {
    tqh_first = 0xdeadc0de, tqh_last = 0xdeadc0de}, if_pcount = -559038242, 
  if_bpf = 0xdeadc0de, if_index = 49374, if_unit = -8531, if_timer = -16162, 
  if_flags = -8531, if_ipending = -559038242, if_linkmib = 0xdeadc0de, 
  if_linkmiblen = 3735929054, if_data = {ifi_type = 222 'Þ', 
    ifi_physical = 192 'À', ifi_addrlen = 173 '­', ifi_hdrlen = 222 'Þ', 
    ifi_recvquota = 222 'Þ', ifi_xmitquota = 192 'À', ifi_mtu = 3735929054, 
    ifi_metric = 0, ifi_baudrate = 10000000, ifi_ipackets = 1739, 
    ifi_ierrors = 0, ifi_opackets = 26, ifi_oerrors = 0, ifi_collisions = 0, 
    ifi_ibytes = 310488, ifi_obytes = 2035, ifi_imcasts = 1698, 
    ifi_omcasts = 3, ifi_iqdrops = 0, ifi_noproto = 0, ifi_hwassist = 0, 
    ifi_unused = 0, ifi_lastchange = {tv_sec = 955392108, tv_usec = 92647}}, 
  if_multiaddrs = {lh_first = 0xc092fb80}, if_amcount = 0, 
  if_output = 0xc0193d64 <ether_output>, if_start = 0xc0132fd4 <ep_if_start>, 
  if_done = 0, if_ioctl = 0xc0133c28 <ep_if_ioctl>, 
  if_watchdog = 0xc0133d28 <ep_if_watchdog>, if_poll_recv = 0, 
  if_poll_xmit = 0, if_poll_intren = 0, if_poll_slowinput = 0, 
  if_init = 0xc0132d94 <ep_if_init>, 
  if_resolvemulti = 0xc0194900 <ether_resolvemulti>, if_snd = {ifq_head = 0x0, 
    ifq_tail = 0x0, ifq_len = 0, ifq_maxlen = 50, ifq_drops = 0}, 
  if_poll_slowq = 0x0, if_prefixhead = {tqh_first = 0x0, 
    tqh_last = 0xc0936ad0}}

Fix: 

It looks to me that removing the prefix/router associations bound
	to an interface when the interface is brought down is the right thing
	to do. Those pairs are useless when the interface is down, even
	if present.
How-To-Repeat: 
	Put an Ethernet card in a laptop on an IPv6 enabled network with
	router advertisements, wait for a global address to be assigned,
	then remove the card (or suspend the laptop, this should has the same
	effect when it resumes as the interface has been brought down when
	suspending).

	In fact, if you have a way to completely remove an interface, you
	should be able to reproduce this without a laptop.
Comment 1 Sheldon Hearn 2000-04-11 14:27:41 UTC
On Mon, 10 Apr 2000 20:58:54 +0200, Samuel Tardieu wrote:

> >Number:         17909
> >Category:       kern
> >Synopsis:       Panic when removing a pccard which has a seen an IPv6 router advertisement

Hi gents,

I'm contacting you because you are Mr Laptop (Warner) and Mr IPv6
(Inoue-san) respectively and I'm not sure where this one falls. :-)

Thanks,
Sheldon.
Comment 2 Warner Losh 2000-04-11 16:53:18 UTC
In message <7991.955459661@axl.ops.uunet.co.za> Sheldon Hearn writes:
: 
: 
: On Mon, 10 Apr 2000 20:58:54 +0200, Samuel Tardieu wrote:
: 
: > >Number:         17909
: > >Category:       kern
: > >Synopsis:       Panic when removing a pccard which has a seen an IPv6 router advertisement
: 
: Hi gents,
: 
: I'm contacting you because you are Mr Laptop (Warner) and Mr IPv6
: (Inoue-san) respectively and I'm not sure where this one falls. :-)

I'd say it is a if_detach issue, which inoue-san likely is more
qualified to look at.

Warner
Comment 3 shin freebsd_committer freebsd_triage 2000-04-12 01:17:11 UTC
Responsible Changed
From-To: freebsd-bugs->shin

I'll look at it. 

Comment 4 Yoshinobu Inoue 2000-04-12 01:17:56 UTC
> : I'm contacting you because you are Mr Laptop (Warner) and Mr IPv6
> : (Inoue-san) respectively and I'm not sure where this one falls. :-)
> 
> I'd say it is a if_detach issue, which inoue-san likely is more
> qualified to look at.

Sorry for my late response.
I'll check it, and create fix.

Yoshinobu Inoue
Comment 5 itojun freebsd_committer freebsd_triage 2000-07-18 10:30:01 UTC
State Changed
From-To: open->feedback

improvement in the tree (sys/net/if.c 1.90 -> 1.91)
Comment 6 Sheldon Hearn freebsd_committer freebsd_triage 2000-07-18 15:18:25 UTC
Responsible Changed
From-To: shin->itojun

Itoh-san's reminder.
Comment 7 Hajimu UMEMOTO freebsd_committer freebsd_triage 2000-07-26 10:30:12 UTC
State Changed
From-To: feedback->closed

This problem was gone by sys/net/if.c 1.90 -> 1.91.