FW: [PATCH] SysKonnect Yukon driver promiscuous mode fix
Wilko Bulte
wkb at freebie.xs4all.nl
Mon Dec 15 15:10:27 PST 2003
----- Forwarded message from Jung-uk Kim <jkim at niksun.com> -----
Date: Wed, 15 Oct 2003 19:40:02 -0400
From: Jung-uk Kim <jkim at niksun.com> (by way of Jung-uk Kim <jkim at niksun.com>)
Subject: [PATCH] SysKonnect Yukon driver promiscuous mode fix
To: Wilko Bulte <wkb at freebie.xs4all.nl>
I am re-sending it to your private e-mail just in case you missed
@FreeBSD.Org e-mail. ;-)
--------------
(I am CC'ing Nathan L. Binkert because my patch was originally from
OpenBSD.)
Here is the first patch for the bug.
It is very simple to reproduce the bug. Run tcpdump on the
interface, e.g., 'tcpdump -i sk0'. You will see all packets on the
segment. While in promiscuous mode (i.e., don't quit tcpdump), try
'ifconfig <iface> down', e.g., 'ifconfig sk0 down', and bring it
back up, e.g., 'ifconfig sk0 up'. You will only see your packets or
broadcast packets. This bug also causes multicast filter to be
cleaned up.
This patch simplifies IFF_PROMISC checking from sk_ioctl() and
prevents the inteface from getting re-initialized when you change
other flags, e.g., arp.
Thanks,
JK
PS: Actually I found another bug, which was originally from Bill
Paul's code. I need more test but I will let you know.
On Tuesday 14 October 2003 07:38 pm, Jung-uk Kim wrote:
> I thought you were going to MFC it after 4.9-RELEASE but...
>
> Any way, I think you have to mention that miivar.h has partial MFC
> from the following:
>
> http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/mii/miivar.h.diff
>?r1=1.10&r2=1.11
>
> Actually I got it from NetBSD.
>
> BTW, there is a buglet in the driver with promiscuous mode. ;-)
> When the card is in promiscuous mode, trying changing any flags.
> Promiscuous mode WILL not work properly because of a bug in the
> original patch.
>
> Nathan also added checksum offloading feature recently. I am going
> to add the feature, too.
>
> So stay tuned for more patches. ;-)
>
> Thanks,
>
> JK
--
_______________________________________________________________
Jung-uk Kim NIKSUN, Inc.
jkim at niksun.com http://www.niksun.com
Tel: +1 732 821-5000 x3331 1100 Cornwall Road
Fax: +1 732 821-6000 Monmouth Junction, NJ 08852 USA
_______________________________________________________________
----- End forwarded message -----
--
| / o / /_ _
|/|/ / / /( (_) Bulte wilko at FreeBSD.org
-------------- next part --------------
--- src/sys/pci/if_sk.c.orig Tue Oct 14 19:22:55 2003
+++ src/sys/pci/if_sk.c Wed Oct 15 18:58:12 2003
@@ -217,6 +217,7 @@
static u_int32_t sk_calchash __P((caddr_t));
static void sk_setfilt __P((struct sk_if_softc *, caddr_t, int));
static void sk_setmulti __P((struct sk_if_softc *));
+static void sk_setpromisc __P((struct sk_if_softc *));
#ifdef SK_USEIOSPACE
#define SK_RES SYS_RES_IOPORT
@@ -787,6 +788,34 @@
return;
}
+static void sk_setpromisc(sc_if)
+ struct sk_if_softc *sc_if;
+{
+ struct sk_softc *sc = sc_if->sk_softc;
+ struct ifnet *ifp = &sc_if->arpcom.ac_if;
+
+ switch(sc->sk_type) {
+ case SK_GENESIS:
+ if (ifp->if_flags & IFF_PROMISC) {
+ SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
+ } else {
+ SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
+ }
+ break;
+ case SK_YUKON:
+ if (ifp->if_flags & IFF_PROMISC) {
+ SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
+ YU_RCR_UFLEN | YU_RCR_MUFLEN);
+ } else {
+ SK_YU_SETBIT_2(sc_if, YUKON_RCR,
+ YU_RCR_UFLEN | YU_RCR_MUFLEN);
+ }
+ break;
+ }
+
+ return;
+}
+
static int sk_init_rx_ring(sc_if)
struct sk_if_softc *sc_if;
{
@@ -1125,7 +1154,6 @@
caddr_t data;
{
struct sk_if_softc *sc_if = ifp->if_softc;
- struct sk_softc *sc = sc_if->sk_softc;
struct ifreq *ifr = (struct ifreq *) data;
int s, error = 0;
struct mii_data *mii;
@@ -1147,34 +1175,12 @@
break;
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc_if->sk_if_flags & IFF_PROMISC)) {
- switch(sc->sk_type) {
- case SK_GENESIS:
- SK_XM_SETBIT_4(sc_if, XM_MODE,
- XM_MODE_RX_PROMISC);
- break;
- case SK_YUKON:
- SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
- YU_RCR_UFLEN | YU_RCR_MUFLEN);
- break;
- }
- sk_setmulti(sc_if);
- } else if (ifp->if_flags & IFF_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc_if->sk_if_flags & IFF_PROMISC) {
- switch(sc->sk_type) {
- case SK_GENESIS:
- SK_XM_CLRBIT_4(sc_if, XM_MODE,
- XM_MODE_RX_PROMISC);
- break;
- case SK_YUKON:
- SK_YU_SETBIT_2(sc_if, YUKON_RCR,
- YU_RCR_UFLEN | YU_RCR_MUFLEN);
- break;
+ if (ifp->if_flags & IFF_RUNNING) {
+ if ((ifp->if_flags ^ sc_if->sk_if_flags)
+ & IFF_PROMISC) {
+ sk_setpromisc(sc_if);
+ sk_setmulti(sc_if);
}
- sk_setmulti(sc_if);
} else
sk_init(sc_if);
} else {
@@ -2258,12 +2264,6 @@
*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4]));
SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION);
- if (ifp->if_flags & IFF_PROMISC) {
- SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
- } else {
- SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
- }
-
if (ifp->if_flags & IFF_BROADCAST) {
SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
} else {
@@ -2305,6 +2305,9 @@
*/
SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH);
+ /* Set promiscuous mode */
+ sk_setpromisc(sc_if);
+
/* Set multicast filter */
sk_setmulti(sc_if);
@@ -2400,8 +2403,7 @@
SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
/* receive control reg */
- SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_UFLEN | YU_RCR_MUFLEN |
- YU_RCR_CRCR);
+ SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
/* transmit parameter register */
SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
@@ -2425,11 +2427,11 @@
SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
}
- /* clear all Multicast filter hash registers */
- SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
+ /* Set promiscuous mode */
+ sk_setpromisc(sc_if);
+
+ /* Set multicast filter */
+ sk_setmulti(sc_if);
/* enable interrupt mask for counter overflows */
SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
-------------- next part --------------
--- src/sys/pci/if_sk.c.orig Sat Sep 20 06:53:08 2003
+++ src/sys/pci/if_sk.c Wed Oct 15 19:10:32 2003
@@ -219,6 +219,7 @@
static u_int32_t sk_calchash (caddr_t);
static void sk_setfilt (struct sk_if_softc *, caddr_t, int);
static void sk_setmulti (struct sk_if_softc *);
+static void sk_setpromisc (struct sk_if_softc *);
#ifdef SK_USEIOSPACE
#define SK_RES SYS_RES_IOPORT
@@ -815,6 +816,35 @@
return;
}
+static void
+sk_setpromisc(sc_if)
+ struct sk_if_softc *sc_if;
+{
+ struct sk_softc *sc = sc_if->sk_softc;
+ struct ifnet *ifp = &sc_if->arpcom.ac_if;
+
+ switch(sc->sk_type) {
+ case SK_GENESIS:
+ if (ifp->if_flags & IFF_PROMISC) {
+ SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
+ } else {
+ SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
+ }
+ break;
+ case SK_YUKON:
+ if (ifp->if_flags & IFF_PROMISC) {
+ SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
+ YU_RCR_UFLEN | YU_RCR_MUFLEN);
+ } else {
+ SK_YU_SETBIT_2(sc_if, YUKON_RCR,
+ YU_RCR_UFLEN | YU_RCR_MUFLEN);
+ }
+ break;
+ }
+
+ return;
+}
+
static int
sk_init_rx_ring(sc_if)
struct sk_if_softc *sc_if;
@@ -1097,7 +1127,6 @@
caddr_t data;
{
struct sk_if_softc *sc_if = ifp->if_softc;
- struct sk_softc *sc = sc_if->sk_softc;
struct ifreq *ifr = (struct ifreq *) data;
int error = 0;
struct mii_data *mii;
@@ -1115,34 +1144,12 @@
break;
case SIOCSIFFLAGS:
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc_if->sk_if_flags & IFF_PROMISC)) {
- switch(sc->sk_type) {
- case SK_GENESIS:
- SK_XM_SETBIT_4(sc_if, XM_MODE,
- XM_MODE_RX_PROMISC);
- break;
- case SK_YUKON:
- SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
- YU_RCR_UFLEN | YU_RCR_MUFLEN);
- break;
- }
- sk_setmulti(sc_if);
- } else if (ifp->if_flags & IFF_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc_if->sk_if_flags & IFF_PROMISC) {
- switch(sc->sk_type) {
- case SK_GENESIS:
- SK_XM_CLRBIT_4(sc_if, XM_MODE,
- XM_MODE_RX_PROMISC);
- break;
- case SK_YUKON:
- SK_YU_SETBIT_2(sc_if, YUKON_RCR,
- YU_RCR_UFLEN | YU_RCR_MUFLEN);
- break;
+ if (ifp->if_flags & IFF_RUNNING) {
+ if ((ifp->if_flags ^ sc_if->sk_if_flags)
+ & IFF_PROMISC) {
+ sk_setpromisc(sc_if);
+ sk_setmulti(sc_if);
}
- sk_setmulti(sc_if);
} else
sk_init(sc_if);
} else {
@@ -2242,12 +2249,6 @@
*(u_int16_t *)(&sc_if->arpcom.ac_enaddr[4]));
SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_STATION);
- if (ifp->if_flags & IFF_PROMISC) {
- SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
- } else {
- SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_PROMISC);
- }
-
if (ifp->if_flags & IFF_BROADCAST) {
SK_XM_CLRBIT_4(sc_if, XM_MODE, XM_MODE_RX_NOBROAD);
} else {
@@ -2289,6 +2290,9 @@
*/
SK_XM_WRITE_2(sc_if, XM_TX_REQTHRESH, SK_XM_TX_FIFOTHRESH);
+ /* Set promiscuous mode */
+ sk_setpromisc(sc_if);
+
/* Set multicast filter */
sk_setmulti(sc_if);
@@ -2384,8 +2388,7 @@
SK_YU_WRITE_2(sc_if, YUKON_PAR, reg);
/* receive control reg */
- SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_UFLEN | YU_RCR_MUFLEN |
- YU_RCR_CRCR);
+ SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_CRCR);
/* transmit parameter register */
SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) |
@@ -2409,11 +2412,11 @@
SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg);
}
- /* clear all Multicast filter hash registers */
- SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
- SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0);
+ /* Set promiscuous mode */
+ sk_setpromisc(sc_if);
+
+ /* Set multicast filter */
+ sk_setmulti(sc_if);
/* enable interrupt mask for counter overflows */
SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0);
More information about the freebsd-current
mailing list