[Fwd: Panic: if_freemulti: protospec not NULL]

From: Bruce M. Simpson <bms_at_FreeBSD.org>
Date: Tue, 27 Mar 2007 17:19:33 +0100
Patch for this condition is attached.

This particular bug is irritating: the IPv4 stack joins 224.0.0.1 once 
for every IPv4 unicast address configured in the stack. This is 
incorrect behaviour. The implementation of refcounting has exposed this 
bug. The fix is not particularly elegant.

It is most likely a left-over from the FreeBSD 2.x/3.x era when IPv4 
'aliases' were first introduced. At that point in time the IGMP code in 
FreeBSD would allow groups to be joined on a per-IPv4-address basis, 
which is inconsistent with the IGMPv2/v3 specified behaviour (and indeed 
that addressed in future multicast RFCs).

It seems that there are other situations where the stack is not 
adequately equipped to deal with interfaces going away unexpectedly. We 
can't afford to be complacent about multicast code on the basis of 'it's 
not the critical path', because it is an integral component of IPv6, and 
many ideas which people are trying to implement in IPv4 also require 
that the multicast code is fit for purpose.

We would do well to have more people available to help on reviewing and 
possibly rewriting parts of the network stack from a perspective of 
correctness, not just performance. If this interests you please consider 
signing up to the Wiki and updating the page at 
http://wiki.freebsd.org/NetworkRFCCompliance.

Regards,
BMS

attached mail follows:



fxp0: 62.48.0.50/24

sysctl net.link.

ifconfig lo1 create
ifconfig lo1 inet 62.48.0.39/32
ifconfig lo1 inet 62.48.0.38/32 alias
# ping tests etc.
ifconfig lo1 delete 62.48.0.39
ifconfig lo1 delete 62.48.0.38
ifconfig lo1 destroy
# panic

Unread portion of the kernel message buffer:
panic: if_freemulti: protospec not NULL
cpuid = 1
KDB: enter: panic
Physical memory: 2035 MB
Dumping 103 MB: 88 72 56 40 24 8

#0  doadump () at pcpu.h:172
172     pcpu.h: No such file or directory.
         in pcpu.h
(kgdb) bt
#0  doadump () at pcpu.h:172
#1  0xc0477a3f in db_fncall (dummy1=-406202100, dummy2=0, dummy3=-1062950496, 
dummy4=0xe7c9d8e8 "\200DŽĀ")
     at ../../../ddb/db_command.c:486
#2  0xc047784b in db_command (last_cmdp=0xc0a23244, cmd_table=0x0) at 
../../../ddb/db_command.c:401
#3  0xc0477906 in db_command_loop () at ../../../ddb/db_command.c:453
#4  0xc0479551 in db_trap (type=3, code=0) at ../../../ddb/db_main.c:222
#5  0xc06e1f0c in kdb_trap (type=3, code=0, tf=0xe7c9da80) at ../../../kern/subr_kdb.c:502
#6  0xc08c0529 in trap (frame=0xe7c9da80) at ../../../i386/i386/trap.c:621
#7  0xc08aa47b in calltrap () at ../../../i386/i386/exception.s:139
#8  0xc06e1c33 in kdb_enter (msg=0x12 <Address 0x12 out of bounds>) at cpufunc.h:60
#9  0xc06c2fc0 in panic (fmt=0xc0956e98 "if_freemulti: protospec not NULL") at 
../../../kern/kern_shutdown.c:547
#10 0xc073aa18 in if_freemulti (ifma=0xc548f360) at ../../../net/if.c:2251
#11 0xc073b036 in if_delmulti_locked (ifp=0xc50fd000, ifma=0xc548f360, detaching=1) at 
../../../net/if.c:2552
#12 0xc0737dd7 in if_purgemaddrs (ifp=0xc50fd000) at ../../../net/if.c:636
#13 0xc0737f0b in if_detach (ifp=0xc50fd000) at ../../../net/if.c:701
#14 0xc073e939 in lo_clone_destroy (ifp=0xc50fd000) at ../../../net/if_loop.c:131
#15 0xc073c1aa in ifc_simple_destroy (ifc=0xc0a015e0, ifp=0xc1433000) at 
../../../net/if_clone.c:560
#16 0xc073b753 in if_clone_destroyif (ifc=0xc0a015e0, ifp=0xc50fd000) at 
../../../net/if_clone.c:218
#17 0xc073b685 in if_clone_destroy (name=0xc548f9e0 "lo1") at ../../../net/if_clone.c:196
#18 0xc073a370 in ifioctl (so=0xc558ec3c, cmd=2149607801, data=0xc548f9e0 "lo1", 
td=0xc5529a20)
     at ../../../net/if.c:1849
#19 0xc06f4b2f in soo_ioctl (fp=0x12, cmd=2149607801, data=0xc548f9e0, 
active_cred=0xc5899880, td=0xc5529a20)
     at ../../../kern/sys_socket.c:202
#20 0xc06ef872 in kern_ioctl (td=0xc5529a20, fd=3, com=2149607801, data=0xc548f9e0 "lo1") 
at file.h:266
#21 0xc06ef595 in ioctl (td=0xc5529a20, uap=0xe7c9dd00) at ../../../kern/sys_generic.c:544
#22 0xc08c0d72 in syscall (frame=0xe7c9dd38) at ../../../i386/i386/trap.c:1010
#23 0xc08aa4e0 in Xint0x80_syscall () at ../../../i386/i386/exception.s:196
#24 0x00000033 in ?? ()
Previous frame inner to this frame (corrupt stack?)
(kgdb) frame 10
#10 0xc073aa18 in if_freemulti (ifma=0xc548f360) at ../../../net/if.c:2251
2251            KASSERT(ifma->ifma_protospec == NULL,
(kgdb) list
2246    if_freemulti(struct ifmultiaddr *ifma)
2247    {
2248
2249            KASSERT(ifma->ifma_refcount == 0, ("if_freemulti: refcount %d",
2250                ifma->ifma_refcount));
2251            KASSERT(ifma->ifma_protospec == NULL,
2252                ("if_freemulti: protospec not NULL"));
2253
2254            if (ifma->ifma_lladdr != NULL)
2255                    FREE(ifma->ifma_lladdr, M_IFMADDR);
(kgdb) inspect *ifma
$2 = {ifma_link = {tqe_next = 0x0, tqe_prev = 0xc50fd0bc}, ifma_addr = 0xc53210d0, 
ifma_lladdr = 0x0, ifma_ifp = 0x0,
   ifma_refcount = 0, ifma_protospec = 0xc5716180, ifma_llifma = 0x0}
(kgdb) up
#11 0xc073b036 in if_delmulti_locked (ifp=0xc50fd000, ifma=0xc548f360, detaching=1) at 
../../../net/if.c:2552
2552            if_freemulti(ifma);
(kgdb) inspect *ifp
$3 = {if_softc = 0xc548c990, if_l2com = 0x0, if_link = {tqe_next = 0x0, tqe_prev = 
0xc530b808},
   if_xname = "lo1", '\0' <repeats 12 times>, if_dname = 0xc0909303 "lo", if_dunit = 1, 
if_addrhead = {
     tqh_first = 0xc59b7600, tqh_last = 0xc59b7660}, if_klist = {kl_list = {slh_first = 0x0},
     kl_lock = 0xc06a8d78 <knlist_mtx_lock>, kl_unlock = 0xc06a8d94 <knlist_mtx_unlock>,
     kl_locked = 0xc06a8db0 <knlist_mtx_locked>, kl_lockarg = 0xc0a4d7f8}, if_pcount = 0, 
if_carp = 0x0,
   if_bpf = 0xc5716b80, if_index = 8, if_timer = 0, if_vlantrunk = 0x0, if_flags = 32776, 
if_capabilities = 0,
   if_capenable = 0, if_linkmib = 0x0, if_linkmiblen = 0, if_data = {ifi_type = 24 '\030', 
ifi_physical = 0 '\0',
     ifi_addrlen = 0 '\0', ifi_hdrlen = 0 '\0', ifi_link_state = 0 '\0', ifi_recvquota = 0 
'\0',
     ifi_xmitquota = 0 '\0', ifi_datalen = 80 'P', ifi_mtu = 16384, ifi_metric = 0, 
ifi_baudrate = 0,
     ifi_ipackets = 0, ifi_ierrors = 0, ifi_opackets = 0, ifi_oerrors = 0, ifi_collisions 
= 0, ifi_ibytes = 0,
     ifi_obytes = 0, ifi_imcasts = 0, ifi_omcasts = 0, ifi_iqdrops = 0, ifi_noproto = 0, 
ifi_hwassist = 0,
     ifi_epoch = 7771, ifi_lastchange = {tv_sec = 1174954038, tv_usec = 187825}}, 
if_multiaddrs = {tqh_first = 0x0,
     tqh_last = 0xc50fd0bc}, if_amcount = 0, if_output = 0xc073eadc <looutput>, if_input = 
0, if_start = 0,
   if_ioctl = 0xc073ed14 <loioctl>, if_watchdog = 0, if_init = 0, if_resolvemulti = 0, 
if_addr = 0xc59b7600,
   if_spare2 = 0x0, if_spare3 = 0x0, if_drv_flags = 64, if_spare_flags2 = 0, if_snd = 
{ifq_head = 0x0, ifq_tail = 0x0,
     ifq_len = 0, ifq_maxlen = 50, ifq_drops = 0, ifq_mtx = {lock_object = {lo_name = 
0xc50fd010 "lo1",
         lo_type = 0xc0956c03 "if send queue", lo_flags = 16973824, lo_witness_data = 
{lod_list = {
             stqe_next = 0xc0a5de98}, lod_witness = 0xc0a5de98}}, mtx_lock = 4, 
mtx_recurse = 0}, ifq_drv_head = 0x0,
     ifq_drv_tail = 0x0, ifq_drv_len = 0, ifq_drv_maxlen = 0, altq_type = 0, altq_flags = 
0, altq_disc = 0x0,
     altq_ifp = 0xc50fd000, altq_enqueue = 0, altq_dequeue = 0, altq_request = 0, 
altq_clfier = 0x0,
     altq_classify = 0, altq_tbr = 0x0, altq_cdnr = 0x0}, if_broadcastaddr = 0x0, 
if_bridge = 0x0, lltables = 0x0,
   if_label = 0x0, if_prefixhead = {tqh_first = 0x0, tqh_last = 0xc50fd170}, if_afdata = 
{0x0 <repeats 28 times>,
     0xc548c720, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, if_afdata_initialized = 2, 
if_afdata_mtx = {
     lock_object = {lo_name = 0xc0956bf9 "if_afdata", lo_type = 0xc0956bf9 "if_afdata", 
lo_flags = 16973824,
       lo_witness_data = {lod_list = {stqe_next = 0xc0a5dec0}, lod_witness = 0xc0a5dec0}}, 
mtx_lock = 4,
     mtx_recurse = 0}, if_starttask = {ta_link = {stqe_next = 0x0}, ta_pending = 0, 
ta_priority = 0,
     ta_func = 0xc073b2b0 <if_start_deferred>, ta_context = 0xc50fd000}, if_linktask = 
{ta_link = {stqe_next = 0x0},
     ta_pending = 0, ta_priority = 0, ta_func = 0xc07393f8 <do_link_state_change>, 
ta_context = 0xc50fd000},
   if_addr_mtx = {lock_object = {lo_name = 0xc094f3db "if_addr_mtx", lo_type = 0xc094f3db 
"if_addr_mtx",
       lo_flags = 16973824, lo_witness_data = {lod_list = {stqe_next = 0xc0a5f388}, 
lod_witness = 0xc0a5f388}},
     mtx_lock = 3310524960, mtx_recurse = 0}, if_clones = {le_next = 0xc530b800, le_prev = 
0xc0a01628}, if_groups = {
     tqh_first = 0xc548c6f0, tqh_last = 0xc548c6f4}, if_pf_kif = 0x0}
kgdb) inspect *ifma
$4 = {ifma_link = {tqe_next = 0x0, tqe_prev = 0xc50fd0bc}, ifma_addr = 0xc53210d0, 
ifma_lladdr = 0x0, ifma_ifp = 0x0,
   ifma_refcount = 0, ifma_protospec = 0xc5716180, ifma_llifma = 0x0}
(kgdb) up
#12 0xc0737dd7 in if_purgemaddrs (ifp=0xc50fd000) at ../../../net/if.c:636
636                     if_delmulti_locked(ifp, ifma, 1);
(kgdb) up
#13 0xc0737f0b in if_detach (ifp=0xc50fd000) at ../../../net/if.c:701
701             if_purgemaddrs(ifp);
(kgdb) up
#14 0xc073e939 in lo_clone_destroy (ifp=0xc50fd000) at ../../../net/if_loop.c:131
131             if_detach(ifp);
(kgdb) up
#15 0xc073c1aa in ifc_simple_destroy (ifc=0xc0a015e0, ifp=0xc1433000) at 
../../../net/if_clone.c:560
560             ifcs->ifcs_destroy(ifp);
(kgdb) inspect *ifc
$5 = {ifc_list = {le_next = 0xc0a01400, le_prev = 0xc0a9d034}, ifc_name = 0xc0909303 "lo", 
ifc_maxunit = 32767,
   ifc_units = 0xc5316000 "\003", ifc_bmlen = 4096, ifc_data = 0xc0a015c4,
   ifc_attach = 0xc073bfe4 <ifc_simple_attach>, ifc_match = 0xc073c070 <ifc_simple_match>,
   ifc_create = 0xc073c0d4 <ifc_simple_create>, ifc_destroy = 0xc073c18c 
<ifc_simple_destroy>, ifc_refcnt = 3,
   ifc_mtx = {lock_object = {lo_name = 0xc0957019 "if_clone lock", lo_type = 0xc0957019 
"if_clone lock",
       lo_flags = 16973824, lo_witness_data = {lod_list = {stqe_next = 0xc0a5dbc8}, 
lod_witness = 0xc0a5dbc8}},
     mtx_lock = 4, mtx_recurse = 0}, ifc_iflist = {lh_first = 0xc530b800}}
(kgdb) up
#16 0xc073b753 in if_clone_destroyif (ifc=0xc0a015e0, ifp=0xc50fd000) at 
../../../net/if_clone.c:218
218             err =  (*ifc->ifc_destroy)(ifc, ifp);
(kgdb) up
#17 0xc073b685 in if_clone_destroy (name=0xc548f9e0 "lo1") at ../../../net/if_clone.c:196
196             return (if_clone_destroyif(ifc, ifp));
(kgdb) up
#18 0xc073a370 in ifioctl (so=0xc558ec3c, cmd=2149607801, data=0xc548f9e0 "lo1", 
td=0xc5529a20)
     at ../../../net/if.c:1849
1849                    return if_clone_destroy(ifr->ifr_name);


Received on Tue Mar 27 2007 - 14:19:36 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:07 UTC