From owner-freebsd-i386@FreeBSD.ORG Sat Jul 2 02:40:14 2005 Return-Path: X-Original-To: freebsd-i386@hub.freebsd.org Delivered-To: freebsd-i386@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E22DB16A41C for ; Sat, 2 Jul 2005 02:40:14 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id B14B043D48 for ; Sat, 2 Jul 2005 02:40:14 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id j622eEXC025754 for ; Sat, 2 Jul 2005 02:40:14 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id j622eE1d025717; Sat, 2 Jul 2005 02:40:14 GMT (envelope-from gnats) Resent-Date: Sat, 2 Jul 2005 02:40:14 GMT Resent-Message-Id: <200507020240.j622eE1d025717@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-i386@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Dan Lukes Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B8A7016A41C for ; Sat, 2 Jul 2005 02:39:05 +0000 (GMT) (envelope-from dan@kulesh.obluda.cz) Received: from kulesh.obluda.cz (kulesh.obluda.cz [193.179.22.243]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8698343D49 for ; Sat, 2 Jul 2005 02:39:04 +0000 (GMT) (envelope-from dan@kulesh.obluda.cz) Received: from kulesh.obluda.cz (localhost.eunet.cz [127.0.0.1]) by kulesh.obluda.cz (8.13.3/8.13.3) with ESMTP id j622d1Rh000810 for ; Sat, 2 Jul 2005 04:39:02 +0200 (CEST) (envelope-from dan@kulesh.obluda.cz) Received: (from root@localhost) by kulesh.obluda.cz (8.13.3/8.13.1/Submit) id j622d1f9000809; Sat, 2 Jul 2005 04:39:01 +0200 (CEST) (envelope-from dan) Message-Id: <200507020239.j622d1f9000809@kulesh.obluda.cz> Date: Sat, 2 Jul 2005 04:39:01 +0200 (CEST) From: Dan Lukes To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: i386/82882: [ PATCH ] ip_mroute abends kernel when interface detached X-BeenThere: freebsd-i386@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Dan Lukes List-Id: I386-specific issues for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Jul 2005 02:40:15 -0000 >Number: 82882 >Category: i386 >Synopsis: [ PATCH ] ip_mroute abends kernel when interface detached >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-i386 >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jul 02 02:40:14 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Dan Lukes >Release: FreeBSD 5.4-STABLE i386 >Organization: Obludarium >Environment: System: FreeBSD 5.4-STABLE i386 src/sys/netinet/ip_mroute.c,v 1.106.2.3 2004/10/09 15:12:04 rwatson >Description: MROUTE code didn't care about interface deletion. It's maintain it's own copy of ifp within it's table. Using it copy after interface detached may cause kernel abend or other malfunction. >How-To-Repeat: ifconfig vlan666 create ifconfig vlan666 127.0.0.5/32 vlan 666 vlandev run a mroute daemon which add vlan666 as vif to kernel ifconfig vlan666 destroy now shutdown the mrouted - kernel abend during MRT_DEL_VIF (or MRT_DONE) >Fix: ip_mroute should monitor if_detach interface event invoked by if.c:if_detach() It should delete delte destryed interface from it's tables --- ip_mroute.patch begins here --- --- sys/netinet/ip_mroute.c.ORIG Tue Nov 30 14:58:31 2004 +++ sys/netinet/ip_mroute.c Sat Jul 2 04:11:13 2005 @@ -124,6 +124,8 @@ static u_char nexpire[MFCTBLSIZ]; +static eventhandler_tag if_detach_event_tag = NULL; + static struct callout expire_upcalls_ch; #define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */ @@ -268,8 +270,10 @@ static int get_sg_cnt(struct sioc_sg_req *); static int get_vif_cnt(struct sioc_vif_req *); +static void if_detached_event(void *arg __unused, struct ifnet *); static int ip_mrouter_init(struct socket *, int); static int add_vif(struct vifctl *); +static int del_vif_locked(vifi_t); static int del_vif(vifi_t); static int add_mfc(struct mfcctl2 *); static int del_mfc(struct mfcctl2 *); @@ -619,6 +623,29 @@ static struct mtx mrouter_mtx; /* used to synch init/done work */ +static void +if_detached_event(void *arg __unused, struct ifnet *ifp) +{ + vifi_t vifi; + + mtx_lock(&mrouter_mtx); + + if (ip_mrouter == NULL) { + mtx_unlock(&mrouter_mtx); + } + + VIF_LOCK(); + /* + * For each phyint in use, disable promiscuous reception of all IP + * multicasts. + */ + for (vifi = 0; vifi < numvifs; vifi++) + if (viftable[vifi].v_ifp == ifp) + del_vif_locked(vifi); + VIF_UNLOCK(); + mtx_unlock(&mrouter_mtx); +} + /* * Enable multicast routing */ @@ -642,6 +669,11 @@ return EADDRINUSE; } + if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, + if_detached_event, NULL, EVENTHANDLER_PRI_ANY); + if (if_detach_event_tag == NULL) + return (ENOMEM); + callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls, NULL); callout_reset(&bw_upcalls_ch, BW_UPCALLS_PERIOD, @@ -716,6 +748,7 @@ numvifs = 0; pim_assert = 0; VIF_UNLOCK(); + EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_detach_event_tag); /* * Free all multicast forwarding cache entries. @@ -1050,19 +1083,17 @@ * Delete a vif from the vif table */ static int -del_vif(vifi_t vifi) +del_vif_locked(vifi_t vifi) { struct vif *vifp; - VIF_LOCK(); + VIF_LOCK_ASSERT(); if (vifi >= numvifs) { - VIF_UNLOCK(); return EINVAL; } vifp = &viftable[vifi]; if (vifp->v_lcl_addr.s_addr == INADDR_ANY) { - VIF_UNLOCK(); return EADDRNOTAVAIL; } @@ -1101,9 +1132,19 @@ break; numvifs = vifi; + return 0; +} + +static int +del_vif(vifi_t vifi) +{ + int cc; + + VIF_LOCK(); + cc = del_vif_locked(vifi); VIF_UNLOCK(); - return 0; + return cc; } /* --- ip_mroute.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: