From owner-freebsd-pf@FreeBSD.ORG Mon Aug 15 15:40:41 2005 Return-Path: X-Original-To: freebsd-pf@freebsd.org Delivered-To: freebsd-pf@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7C50716A41F for ; Mon, 15 Aug 2005 15:40:41 +0000 (GMT) (envelope-from slapinid@gmail.com) Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.194]) by mx1.FreeBSD.org (Postfix) with ESMTP id 09F7E43D49 for ; Mon, 15 Aug 2005 15:40:40 +0000 (GMT) (envelope-from slapinid@gmail.com) Received: by zproxy.gmail.com with SMTP id z6so681603nzd for ; Mon, 15 Aug 2005 08:40:40 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=emzpjejtsOp3A1fn2PKk5j3Xzfmq4JOjrs07OzKbcL7ejHdclfUyMPdDQnBYEBKMjNnqpemGdxrIBBnY2G3Kj7NjiQLYrxPMxZ/jDFs93+uqkUoyF9BaHSOV9Ev2LMh6vEvPA+uGtfN+ZxrNYCRATyB7NKq88aezmu711J0x2Q4= Received: by 10.37.14.76 with SMTP id r76mr3506287nzi; Mon, 15 Aug 2005 08:40:40 -0700 (PDT) Received: by 10.36.33.4 with HTTP; Mon, 15 Aug 2005 08:40:40 -0700 (PDT) Message-ID: <48239d390508150840481420ec@mail.gmail.com> Date: Mon, 15 Aug 2005 19:40:40 +0400 From: Sergey Lapin To: freebsd-pf@freebsd.org In-Reply-To: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: Subject: Fwd: Fwd: Dual-feed: PF setup troubles X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Aug 2005 15:40:41 -0000 ---------- Forwarded message ---------- From: Dmitry Andrianov Date: Aug 15, 2005 7:31 PM Subject: RE: Fwd: Dual-feed: PF setup troubles To: Sergey Lapin , Max Laier , Daniel Hartmeier Hi. > You can try turning of the IFF_SIMPLEX flag on the interface > (unsure about the entire effects of that), or simply exclude those > broadcast packets from getting routed by pf (which isn't really intentional, is it?), like > > - ... from ... to any ... > + ... from ... to !255.255.255.255 ... Well, these are not packets to 255.255.255.255 which cause dead box. As we previously note, ANY packet with broadcast destination MAC and destination IP outside of directly connected networks does that. Which means we can not just block it at Layer 3 level - we need some sort of MAC (Layer 2) filtering which pf does not have (I suppose). After all, I do not see how this ruleset pass in quick on $dmz_if route-to ($ext_if1 $ext_gw1) tagged DMZ_TO_EXT1 keep state pass in quick on $dmz_if route-to ($ext_if2 $ext_gw2) tagged DMZ_TO_EXT2 keep state pass out quick on $ext_if1 route-to ($ext_if2 $ext_gw2) tagged DMZ_TO_EXT2 keep state pass out quick on $ext_if2 route-to ($ext_if1 $ext_gw1) tagged DMZ_TO_EXT1 keep state Causes loop. Even if packet re-enters ext_if1 input queue, it should not be affected by these rules because 1. first two applies only to packets coming to DMZ interfact 2. second two applies only when packet with wrong source is on the interface output queue... Regards, Dmitry Andrianov -----Original Message----- From: Sergey Lapin [mailto:slapinid@gmail.com] Sent: Monday, August 15, 2005 6:51 PM To: Dmitry Andrianov; Max Laier Subject: Fwd: Fwd: Dual-feed: PF setup troubles ---------- Forwarded message ---------- From: Daniel Hartmeier Date: Aug 15, 2005 6:34 PM Subject: Re: Fwd: Dual-feed: PF setup troubles To: Sergey Lapin Cc: freebsd-pf@freebsd.org I suspect the loop occurs through sys/net/if_ethersubr.c ether_output() /* * If a simplex interface, and the packet is being sent to our * Ethernet address or a broadcast address, loopback a copy. * XXX To make a simplex device behave exactly like a duplex * device, we should copy in the case of sending to our own * ethernet address (thus letting the original actually appear * on the wire). However, we don't do that here for security * reasons and compatibility with the original behavior. */ if ((ifp->if_flags & IFF_SIMPLEX) && (loop_copy !=3D -1)) { int csum_flags =3D 0; if (m->m_pkthdr.csum_flags & CSUM_IP) csum_flags |=3D (CSUM_IP_CHECKED|CSUM_IP_VALID); if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) csum_flags |=3D (CSUM_DATA_VALID|CSUM_PSEUDO_HDR); if ((m->m_flags & M_BCAST) || (loop_copy > 0)) { struct mbuf *n; if ((n =3D m_copy(m, 0, (int)M_COPYALL)) !=3D NULL) { n->m_pkthdr.csum_flags |=3D csum_flags; if (csum_flags & CSUM_DATA_VALID) n->m_pkthdr.csum_data =3D 0xffff; (void)if_simloop(ifp, n, dst->sa_family, hlen); } else ifp->if_iqdrops++; } else if (bcmp(eh->ether_dhost, eh->ether_shost, ETHER_ADDR_LEN) =3D=3D 0) { m->m_pkthdr.csum_flags |=3D csum_flags; if (csum_flags & CSUM_DATA_VALID) m->m_pkthdr.csum_data =3D 0xffff; (void) if_simloop(ifp, m, dst->sa_family, hlen); return (0); /* XXX */ } } You route-to the broadcast packet, pf will call ether_output() to send it out through the new interface, and this piece of code in there will send it right back in through that interface again. If your ruleset then routes that resent packet again, you get a tight endless loop, locking up the kernel, like you describe. OpenBSD doesn't have this piece in ether_output(), I'm not sure in what cases people want outgoing broadcasts on an interface reflected back at them by the stack. You can try turning of the IFF_SIMPLEX flag on the interface (unsure about the entire effects of that), or simply exclude those broadcast packets from getting routed by pf (which isn't really intentional, is it?), like - ... from ... to any ... + ... from ... to !255.255.255.255 ... Or find the person familiar/responsible for this loop_copy code, and ask whether we can bypass it, for instance when the PF_ROUTED mbuf tag is present, or such. I'm not entirely sure this is the loop, but you can confirm by adding simple printf()s along that code path, you'll see them printed endlessly when the lockup occurs. Daniel