kern/103019: [patch] MFC link flapping workaround for em(4) to RELENG_4

Eugene Grosbein eugen at grosbein.pp.ru
Fri Sep 8 09:10:24 UTC 2006


>Number:         103019
>Category:       kern
>Synopsis:       [patch] MFC link flapping workaround for em(4) to RELENG_4
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 08 09:10:22 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.11-STABLE i386
>Organization:
Svyaz Service JSC
>Environment:
System: FreeBSD www.svzserv.kemerovo.su 4.11-STABLE FreeBSD 4.11-STABLE #17: Fri Sep 8 12:21:26 KRAST 2006 eu at www.svzserv.kemerovo.su:/home4/obj/home/src/sys/WWW i386

>Description:

	Please MFC part of if_em.c,v1.119 to RELENG_4 to work aroung
	link flapping problem. Path follows (tested).

>How-To-Repeat:
	ifconfig em0 inet ... alias produces timeout, link regenitiation
	and there is no outgoing ARP cache update packet.
>Fix:

--- sys/dev/em/if_em.c.orig	Fri Sep  8 10:36:26 2006
+++ sys/dev/em/if_em.c	Fri Sep  8 12:19:50 2006
@@ -61,6 +61,7 @@
 
 #include <netinet/in_systm.h>
 #include <netinet/in.h>
+#include <netinet/if_ether.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
@@ -729,6 +730,7 @@
 {
 	struct adapter	*adapter = ifp->if_softc;
 	struct ifreq *ifr = (struct ifreq *)data;
+	struct ifaddr *ifa = (struct ifaddr *)data;
 	int error = 0;
 	int s;
 
@@ -741,7 +743,21 @@
 	case SIOCSIFADDR:
 	case SIOCGIFADDR:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
-		ether_ioctl(ifp, command, data);
+		if (ifa->ifa_addr->sa_family == AF_INET) {
+			/*
+			 * XXX
+			 * Since resetting hardware takes a very long time
+			 * and results in link renegotiation we only
+			 * initialize the hardware only when it is absolutely
+			 * required.
+			 */
+			ifp->if_flags |= IFF_UP;
+			if (!(ifp->if_flags & IFF_RUNNING)) {
+				em_init(adapter);
+			}
+			arp_ifinit(ifp, ifa);
+		} else
+			error = ether_ioctl(ifp, command, data);
 		break;
 	case SIOCSIFMTU:
 	    {
@@ -790,12 +806,13 @@
 	case SIOCSIFFLAGS:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
 		if (ifp->if_flags & IFF_UP) {
-			if (!(ifp->if_flags & IFF_RUNNING)) {
+			if ((ifp->if_flags & IFF_RUNNING)) {
+				if (ifp->if_flags & IFF_PROMISC) {
+					em_disable_promisc(adapter);
+					em_set_promisc(adapter);
+				}
+			} else
 				em_init(adapter);
-			}
-
-			em_disable_promisc(adapter);
-			em_set_promisc(adapter);
 		} else {
 			if (ifp->if_flags & IFF_RUNNING) {
 				em_stop(adapter);



Eugene Grosbein
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list