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)