From owner-freebsd-bugs@FreeBSD.ORG Sat Mar 3 21:20:05 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 3E36A16A401 for ; Sat, 3 Mar 2007 21:20:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 20F1B13C461 for ; Sat, 3 Mar 2007 21:20:05 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l23LK4fv082892 for ; Sat, 3 Mar 2007 21:20:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l23LK4v0082890; Sat, 3 Mar 2007 21:20:04 GMT (envelope-from gnats) Resent-Date: Sat, 3 Mar 2007 21:20:04 GMT Resent-Message-Id: <200703032120.l23LK4v0082890@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eygene Ryabinkin Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8566616A403; Sat, 3 Mar 2007 21:12:39 +0000 (UTC) (envelope-from rea-fbsd@codelabs.ru) Received: from pobox.codelabs.ru (pobox.codelabs.ru [144.206.177.45]) by mx1.freebsd.org (Postfix) with ESMTP id 3DE5D13C4AA; Sat, 3 Mar 2007 21:12:39 +0000 (UTC) (envelope-from rea-fbsd@codelabs.ru) Received: from localdomain by pobox.codelabs.ru with local id 1HNbWw-000LoF-Bo; Sun, 04 Mar 2007 00:12:38 +0300 Message-Id: Date: Sun, 04 Mar 2007 00:12:38 +0300 From: Eygene Ryabinkin Sender: rea-fbsd@codelabs.ru To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: rik@FreeBSD.org, glebius@FreeBSD.org, andre@FreeBSD.org, thompsa@FreeBSD.org Subject: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Eygene Ryabinkin List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Mar 2007 21:20:05 -0000 >Number: 109815 >Category: kern >Synopsis: wrong interface identifier at pfil_hooks for vlans + if_bridge >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Mar 03 21:20:04 GMT 2007 >Closed-Date: >Last-Modified: >Originator: Eygene Ryabinkin >Release: FreeBSD 6.2-STABLE i386 >Organization: Code Labs >Environment: System: FreeBSD XXX 6.2-STABLE FreeBSD 6.2-STABLE #13: Mon Feb 12 15:59:07 MSK 2007 root@XXX:/usr/obj/usr/src/sys/XXX i386 >Description: When if_bridge is used to gather multiple vlan interfaces that have the same physical parent (I will call such vlan interfaces the 'vlan group') the interface identifier that will be passed to the pfil_hooks will be sometimes wrong. For all packets coming from the 'vlan group' and destined to some local interface the incoming interface passed to the pfil_hooks will be the last interface in that group regardless of the actual incoming interface. The 'last interface' is the interface that was added to the if_bridge at the very last 'addm' command. The problem is lying in the fact that MAC addresses of the 'vlan group' are just the same and they are equal to the MAC address of the parent interface. And the check for the unicat packet that is destined for 'us' in the if_bridge.c:bridge_input() is walking by the list of the if_bridge-attached interfaces and compares the MAC addresses to the packet's one. Once match is found the interface in the packet header will be rewritten to the found list entry's one. Apparently such code flow will select the last added interface from the 'vlan group' because FreeBSD list macros are adding list members to the beginning of the linked list. BPF will receive the right interface, because it is tapped before bridge_input (in if_ethersubr.c). >How-To-Repeat: Set up three vlan interfaces on the same physical one, and add them to the same if_bridge. Give one VLAN interface IP address and send packets from the other VLAN segment to that IP. See that tcpdump is seeing the correct interface, but ipfw/pf are seeing the same packet having the last added interface as the rcvif, not the right one. For the last added interface the result will be correct, but for others -- not. >Fix: Since bridge_input always knows about the incoming interface as it is passed as the first argument my fix is just to set the right interface using the passed parameter and not the interface found by the list traversal. The patch is below. It should not break the ordinary situation without CARP and I see no troubles even with the CARP code. But I am not expirienced with CARP, so I am CCing Gleb, Andrew and Andre. We'd found this bug with rik@ so he gots the CC too. Shutting up ;)) --- if_bridge.c.orig Fri Mar 2 18:23:56 2007 +++ if_bridge.c Sat Mar 3 05:04:38 2007 @@ -2122,7 +2122,11 @@ LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) { if (bif2->bif_ifp->if_type == IFT_GIF) continue; - /* It is destined for us. */ + /* It is destined for us. We should not rely on the + * found interface's MAC as the interface identifier, + * because vlanX interfaces are sharing their MAC + * with the parent. Moreover, we do know the interface + * the packet is coming from. So we're using it. */ if (memcmp(IF_LLADDR(bif2->bif_ifp), eh->ether_dhost, ETHER_ADDR_LEN) == 0 #ifdef DEV_CARP @@ -2133,7 +2137,7 @@ if (bif->bif_flags & IFBIF_LEARNING) (void) bridge_rtupdate(sc, eh->ether_shost, bif, 0, IFBAF_DYNAMIC); - m->m_pkthdr.rcvif = bif2->bif_ifp; + m->m_pkthdr.rcvif = ifp; BRIDGE_UNLOCK(sc); return (m); } >Release-Note: >Audit-Trail: >Unformatted: