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);
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:07 UTC