Date: Sat, 31 Jul 2004 15:11:32 +0900 From: Pyun YongHyeon <yongari@kt-is.co.kr> To: sparc64@freebsd.org Subject: ifconfig(8) mediaopt bug and temporary fix Message-ID: <20040731061132.GC19761@kt-is.co.kr>
next in thread | raw e-mail | index | archive | help
Hi, Normally, users with hme(4) + DP83840 PHY forcly set media type to full-duplex since that combination lacks auto-negotiation. However, this has side-effect of bind(2) problem. Typical phenomenon is binding error(EADDRNOTAVAIL) for locally assgined address.(INADDR_ANY works though). I guess this issue had been there for a long time and triggered by ifconfig mediaopt command in big-endian arch. The root cause of the problem seems to be in ifconfig(8) itself. When ifconfig(8) sets media with user-supplied one, it also sets its internal global variable(ifr_media) in 'struct ifreq ifr' to selected one. Since the member variable ifr_media in 'struct ifreq ifr' is shared with all other attributes, subsequent evaluation of 'ifr.ifr_addr.sa_family' is wrong. Under Ultra2, usually I see "atalk 0.0 range 0-0 phase 2" message when I try to set media with command "ifconfig hme0 media 100baseTX mediaopt full-duplex".(i.e. ifconfig(8) thinks I had set AF_APPLETALK.) I guess this affects little-endian machine too. But due to its endian-nature it's not triggered. Here is temporary fix for that issue. Since ifconfig(8) is too complex and very difficult to verify correct operations, I patched domediaopt() which is *not* correct fix. I'd like to see correct fix from commiters with thorough knowledge of ifconfig(8). --- ifmedia.c.orig Fri Jan 16 00:19:19 2004 +++ ifmedia.c Sat Jul 31 14:50:16 2004 @@ -250,7 +250,7 @@ domediaopt(const char *val, int clear, int s) { struct ifmediareq ifmr; - int *mwords, options; + int *mwords, options, optold; (void) memset(&ifmr, 0, sizeof(ifmr)); (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name)); @@ -281,6 +281,7 @@ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_media = ifmr.ifm_current; + optold = ifr.ifr_media; if (clear) ifr.ifr_media &= ~options; else @@ -288,6 +289,7 @@ if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) err(1, "SIOCSIFMEDIA (mediaopt)"); + ifr.ifr_media = optold; /* XXX */ } Best regards, Pyun YongHyeon -- Pyun YongHyeon <http://www.kr.freebsd.org/~yongari>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040731061132.GC19761>