Skip site navigation (1)Skip section navigation (2)
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>