ifconfig(8) mediaopt bug and temporary fix
Pyun YongHyeon
yongari at kt-is.co.kr
Fri Jul 30 23:12:27 PDT 2004
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>
More information about the freebsd-sparc64
mailing list