NetBSD Problem Report #47749

From genadmin@idlefortress.accessaxis.com  Fri Apr 19 23:52:19 2013
Return-Path: <genadmin@idlefortress.accessaxis.com>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id 1803263E5A8
	for <gnats-bugs@gnats.NetBSD.org>; Fri, 19 Apr 2013 23:52:19 +0000 (UTC)
Message-Id: <20130419223512.3DEDA2402BD@idlefortress.accessaxis.com>
Date: Fri, 19 Apr 2013 16:35:12 -0600 (MDT)
From: genadmin@idlefortress.accessaxis.com
Reply-To: inittab@unixdev.net
To: gnats-bugs@gnats.NetBSD.org
Subject: NetBSD 6.0 Only Replies to First ICMP Echo (ping)
X-Send-Pr-Version: 3.95

>Number:         47749
>Category:       kern
>Synopsis:       IPF: NetBSD 6.0 Only Replies to First ICMP Echo (ping)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 19 23:55:00 +0000 2013
>Last-Modified:  Wed May 16 20:26:21 +0000 2018
>Originator:     Greg Schenzel
>Release:        NetBSD 6.0
>Organization:
unixdev.net
>Environment:


System: NetBSD idlefortress.accessaxis.com 6.0 NetBSD 6.0 (GENERIC.UP) sparc64
Architecture: sparc64
Machine: sparc64
>Description:
	NetBSD 6.0 only sends a reply for the first ICMP Echo received. Verified
	on NetBSD/sparc64. In the past I believe I've noticed this on NetBSD/i386
        and NetBSD/amd64 as well. IPFilter is enabled to allow all traffic on the
        internal interface (tlp0). tcpdump shows the requests coming in but only
        one reply going out. I dug through sysctl and didn't see any ICMP settings
        that might affect it. I've tried with Debian 6 and Solaris 9 ping
        utilities, but this is not an issue when pinging from the NetBSD system
        itself.
>How-To-Repeat:

>Fix:


>Release-Note:

>Audit-Trail:
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/47749: NetBSD 6.0 Only Replies to First ICMP Echo (ping)
Date: Sat, 20 Apr 2013 16:58:52 +0200

 Can you try with IPF disabled?

 Martin

From: Greg Schenzel <inittab@unixdev.net>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: kern/47749: NetBSD 6.0 Only Replies to First ICMP Echo (ping)
Date: Sat, 20 Apr 2013 14:45:44 -0600

 --tKW2IUtsqtDRztdT
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable

 Works as expected after running "ipf -D". Here are my first 12 rules.
 The remaining rules are specific tcp/udp ports on the external
 interface (tlp1). This issue occurs on both tlp0 and tlp1 with IPF
 enabled.=20

 ### - completely kill
 #   too short to be real
 block in log quick all with short
 #   source routing is set
 block in log quick all with opt lsrr
 block in log quick all with opt ssrr
 #   reserved address space
 block in log quick on tlp1 from 10.0.0.0/8 to any
 block in log quick on tlp1 from 172.16.0.0/12 to any
 block in log quick on tlp1 from 192.168.0.0/16 to any

 ### - set default interface rules
 pass out log quick proto icmp from any to any keep state
 pass out log quick proto tcp/udp from any to any keep state keep frags
 pass in log on tlp0 from any to any
 pass in log on lo0 from any to any
 block in log on tlp1 from any to any

 ### - icmp
 #   allow ping and traceroute
 #pass in log quick on tlp1 proto icmp from any to any icmp-type 0
 #pass in log quick on tlp1 proto icmp from any to any icmp-type 8
 #pass in log quick on tlp1 proto icmp from any to any icmp-type 11
 pass in log quick proto icmp from any to any


 --tKW2IUtsqtDRztdT
 Content-Type: application/pgp-signature; name="signature.asc"
 Content-Description: Digital signature
 Content-Disposition: inline

 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.10 (GNU/Linux)

 iEYEARECAAYFAlFy/ngACgkQ2ua/BJvbazccCwCdFEX8VUCXCsv75dC/3w9BKxeB
 tNoAn26rEJcfkGVoSxVjjTk825VrIsPU
 =ANwV
 -----END PGP SIGNATURE-----

 --tKW2IUtsqtDRztdT--

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: Darren Reed <darrenr@NetBSD.org>
Subject: Re: kern/47749: NetBSD 6.0 Only Replies to First ICMP Echo (ping)
Date: Sun, 21 Apr 2013 10:04:19 +0200

 On Sat, Apr 20, 2013 at 10:10:05PM +0000, Greg Schenzel wrote:
 >  Works as expected after running "ipf -D". Here are my first 12 rules.

 I don't think it is your rules, but a generic bug in IPF.

 Darren?

 Martin

From: =?ISO-8859-1?Q?Sergio_L=F3pez?= <slp@sinrega.org>
To: gnats-bugs@NetBSD.org
Cc: martin@duskware.de, darrenr@NetBSD.org
Subject: Re: kern/47749
Date: Sat, 24 Aug 2013 11:03:31 +0200

 Apparently, IPF gets confused when trying to keep track of an
 ICMP_ECHOREPLY packet.

 The first time such a packet is found, fr_addstate from fr_scanlist
 (fil.c:2146) fails, and if no other rule matches, it returns the
 default "pass" value (without FR_KEEPSTATE flag), but leaves
 fin->fin_fr pointing to the rule (with FR_KEEPSTATE), and this
 structure is saved into frcache. So this first packet is considered to
 haven't match any rule, and unless IPF is in block by default, it
 passes the filter.

 But, when a second packet arrives, its "pass" value is taken from
 frcache, which contains the flags from the rule, including
 FR_KEEPSTATE. In consequence, fr_addstate fails again when called from
 fr_check (fil.c:2586), and this time the packet is marked as blocked.

 From an user's perspective, this can be avoided by not using "keep
 state" for icmp rules, or by doing so in both the input and output
 filters, as this will make all ICMP_ECHOREPLY packets to be matched by
 a previous ICMP_ECHO.

 But, as Martin said, I don't think IPF should behave this way. I think
 a sensible solution, without altering much of IPF behavior, could be
 something like this:

 --- fil.c.orig 2013-08-24 08:55:50.000000000 +0000
 +++ fil.c 2013-08-24 08:56:20.000000000 +0000
 @@ -2147,6 +2147,7 @@
   ATOMIC_INCL(frstats[out].fr_ads);
   } else {
   ATOMIC_INCL(frstats[out].fr_bads);
 + fin->fin_fr = NULL;
   pass = passo;
   continue;
   }

 This makes that both first and subsequent ICMP_ECHOREPLY packets
 without a related ICMP_ECHO, will not match against a rule with "keep
 state", much in the same way as (AFAIK) IPF from "-current" does.

From: Darren Reed <darrenr@netbsd.org>
To: =?ISO-8859-1?Q?Sergio_L=F3pez?= <slp@sinrega.org>
Cc: gnats-bugs@NetBSD.org, martin@duskware.de
Subject: Re: kern/47749
Date: Thu, 29 Aug 2013 23:06:18 +1000

 Sergio López wrote:
 > Apparently, IPF gets confused when trying to keep track of an
 > ICMP_ECHOREPLY packet.
 >
 > The first time such a packet is found, fr_addstate from fr_scanlist
 > (fil.c:2146) fails, and if no other rule matches, it returns the
 > default "pass" value (without FR_KEEPSTATE flag), but leaves
 > fin->fin_fr pointing to the rule (with FR_KEEPSTATE), and this
 > structure is saved into frcache. So this first packet is considered to
 > haven't match any rule, and unless IPF is in block by default, it
 > passes the filter.
 >
 > But, when a second packet arrives, its "pass" value is taken from
 > frcache, which contains the flags from the rule, including
 > FR_KEEPSTATE. In consequence, fr_addstate fails again when called from
 > fr_check (fil.c:2586), and this time the packet is marked as blocked.
 >
 > From an user's perspective, this can be avoided by not using "keep
 > state" for icmp rules, or by doing so in both the input and output
 > filters, as this will make all ICMP_ECHOREPLY packets to be matched by
 > a previous ICMP_ECHO.
 >   

 Can you give me an example that uses ipftest to show this behaviour?

 Darren

From: Darren Reed <darrenr@netbsd.org>
To: =?ISO-8859-1?Q?Sergio_L=F3pez?= <slp@sinrega.org>
Cc: gnats-bugs@NetBSD.org, martin@duskware.de
Subject: Re: kern/47749
Date: Thu, 29 Aug 2013 23:14:08 +1000

 Sergio,

 I think that the change should look more like below.

 The reason is that when "pass" is restored with "pass = passo",
 the old rule from which "passo" belongs to should belong in
 fin_fr.

 Let me know how you go with testing it.

 Cheers,
 Darren

 Index: fil.c
 ===================================================================
 RCS file: /devel/CVS/IP-Filter/fil.c,v
 retrieving revision 2.243.2.164
 diff -u -r2.243.2.164 fil.c
 --- fil.c       26 Jan 2012 06:03:42 -0000      2.243.2.164
 +++ fil.c       29 Aug 2013 12:07:33 -0000
 @@ -1952,7 +1952,7 @@
  u_32_t pass;
  {
         int rulen, portcmp, off, skip;
 -       struct frentry *fr, *fnext;
 +       struct frentry *fr, *fnext, *fro;
         u_32_t passt, passo;

         /*
 @@ -2088,6 +2088,7 @@
                         }
                         passt = fr->fr_flags;
                 }
 +               fro = fin->fin_fr;
                 fin->fin_fr = fr;

  #ifdef  IPFILTER_LOG
 @@ -2148,6 +2149,7 @@
                                         ATOMIC_INCL(frstats[out].fr_ads);
                                 } else {
                                         ATOMIC_INCL(frstats[out].fr_bads);
 +                                       fin->fin_fr = fro;
                                         pass = passo;
                                         continue;
                                 }

From: Sergio Lopez <slp@sinrega.org>
To: Darren Reed <darrenr@netbsd.org>
Cc: gnats-bugs@NetBSD.org, martin@duskware.de
Subject: Re: kern/47749
Date: Fri, 30 Aug 2013 08:39:51 +0000

 > Can you give me an example that uses ipftest to show this behaviour?

 Sure:

 stable61164# cat /root/pr44749/rules.out
 pass out log quick proto icmp from any to any keep state

 stable61164# cat /root/pr44749/rules.out.nostate 
 pass out log quick proto icmp from any to any

 stable61164# cat /root/pr44749/test.out 
 in on re0 icmp 192.168.0.4 192.168.0.21
 out on re0 icmp 192.168.0.21 192.168.0.4
 in on re0 icmp 192.168.0.4 192.168.0.21
 out on re0 icmp 192.168.0.21 192.168.0.4
 in on re0 icmp 192.168.0.4 192.168.0.21
 out on re0 icmp 192.168.0.21 192.168.0.4

 stable61164# ./ipftest -r /root/pr44749/rules.out -i /root/pr44749/test.out
 nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------nomatch ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------block ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------block ip #0 48(20) 1 192.168.0.21 > 192.168.0.4

 stable61164# ./ipftest -r /root/pr44749/rules.out.nostate  -i /root/pr44749/test.out
 nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------pass ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------pass ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------pass ip #0 48(20) 1 192.168.0.21 > 192.168.0.4

 Sergio.

From: Sergio Lopez <slp@sinrega.org>
To: Darren Reed <darrenr@netbsd.org>
Cc: gnats-bugs@NetBSD.org, martin@duskware.de
Subject: Re: kern/47749
Date: Fri, 30 Aug 2013 08:48:22 +0000

 On Thu, Aug 29, 2013 at 11:14:08PM +1000, Darren Reed wrote:
 > Sergio,
 > 
 > I think that the change should look more like below.
 > 
 > The reason is that when "pass" is restored with "pass = passo",
 > the old rule from which "passo" belongs to should belong in
 > fin_fr.
 > 
 > Let me know how you go with testing it.

 You're right. I've tested your patch with ipftest and as kernel's IPF,
 and it works nicely in both cases:

 stable61164# ./ipftest -r /root/pr44749/rules.out  -i /root/pr44749/test.out
 nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------nomatch ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------nomatch ip #0 48(20) 1 192.168.0.21 > 192.168.0.4
 --------------nomatch ip #0 48(20) 1 192.168.0.4 > 192.168.0.21
 --------------nomatch ip #0 48(20) 1 192.168.0.21 > 192.168.0.4

 Thanks!
 Sergio.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.