Subject: Re: kern/29126: tcpdump leads to packet loss
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Kimmo Suominen <kim@tac.nyc.ny.us>
List: netbsd-bugs
Date: 02/06/2005 00:18:01
The following reply was made to PR kern/29126; it has been noted by GNATS.

From: Kimmo Suominen <kim@tac.nyc.ny.us>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/29126: tcpdump leads to packet loss
Date: Sat, 5 Feb 2005 19:17:31 -0500

 [Resending...]
 
 The patch below would appear to fix this for gsip (I don't have a sip
 card to test with).  I'm basically copying the idea from the hme driver,
 as pointed out by John: ignore changes in internal-only flags.
 
 I've tested downing and re-upping the interface as well as adding and
 removing an inet alias.  Seems to work for me...  :-)
 
 I'll look at ex next, then tlp.
 
 Regards,
 + Kim
 -- 
 Kimmo Suominen
 
 
 Index: if_sip.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v
 retrieving revision 1.97
 diff -u -r1.97 if_sip.c
 --- if_sip.c	30 Jan 2005 18:56:34 -0000	1.97
 +++ if_sip.c	5 Feb 2005 23:23:06 -0000
 @@ -309,6 +309,8 @@
  	struct sip_txsq sc_txfreeq;	/* free Tx descsofts */
  	struct sip_txsq sc_txdirtyq;	/* dirty Tx descsofts */
  
 +	short	sc_if_flags;
 +
  	int	sc_rxptr;		/* next ready Rx descriptor/descsoft */
  #if defined(DP83820)
  	int	sc_rxdiscard;
 @@ -979,6 +981,7 @@
  	strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  	ifp->if_softc = sc;
  	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 +	sc->sc_if_flags = ifp->if_flags;
  	ifp->if_ioctl = SIP_DECL(ioctl);
  	ifp->if_start = SIP_DECL(start);
  	ifp->if_watchdog = SIP_DECL(watchdog);
 @@ -1551,7 +1554,22 @@
  	case SIOCGIFMEDIA:
  		error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
  		break;
 -
 +	case SIOCSIFFLAGS:
 +		/* If the interface is up and running, only modify the receive
 +		 * filter when setting promiscuous or debug mode.  Otherwise
 +		 * fall through to ether_ioctl, which will reset the chip.
 +		 */
 +#define RESETIGN (IFF_CANTCHANGE|IFF_DEBUG)
 +		if (((ifp->if_flags & (IFF_UP|IFF_RUNNING))
 +		    == (IFF_UP|IFF_RUNNING))
 +		    && ((ifp->if_flags & (~RESETIGN))
 +		    == (sc->sc_if_flags & (~RESETIGN)))) {
 +			/* Set up the receive filter. */
 +			(*sc->sc_model->sip_variant->sipv_set_filter)(sc);
 +			error = 0;
 +#undef RESETIGN
 +		} else
 +		/* FALLTHROUGH */
  	default:
  		error = ether_ioctl(ifp, cmd, data);
  		if (error == ENETRESET) { 
 @@ -1569,6 +1587,7 @@
  	/* Try to get more packets going. */
  	SIP_DECL(start)(ifp);
  
 +	sc->sc_if_flags = ifp->if_flags;
  	splx(s);
  	return (error);
  }
 @@ -2542,6 +2561,7 @@
  	 */
  	ifp->if_flags |= IFF_RUNNING;
  	ifp->if_flags &= ~IFF_OACTIVE;
 +	sc->sc_if_flags = ifp->if_flags;
  
   out:
  	if (error)