em device hangs on ifconfig alias ...

Atanas atanas at asd.aplus.net
Thu Jul 6 01:24:10 UTC 2006


Pyun YongHyeon said the following on 6/30/06 8:54 PM:
> On Fri, Jun 30, 2006 at 12:28:49PM -0700, Atanas wrote:
>  > User Freebsd said the following on 6/29/06 9:29 PM:
>  > >
>  > >The other funny thing about the current em driver is that if you move an 
>  > >IP to it from a different server, the appropriate ARP packets aren't 
>  > >sent out to redirect the IP traffic .. recently, someone pointed me to 
>  > >arping, which has solved my problem *external* to the driver ...
>  > >
>  > That's the second reason why I (still) avoid em in mass-aliased systems.
>  > 
>  > I have a single pool of IP addresses shared by many servers with 
>  > multiple aliases each. When someone leaves and frees an IP, it gets 
>  > reused and brought up on a different server. In case it was previously 
>  > handled by em, the traffic doesn't get redirected to the new server.
>  > 
>  > Similar thing happens even with machines with single static IPs. For 
>  > instance when retiring an old production system, I usually request a new 
>  > box to be brought up on a different IP, make a fresh install on 
>  > everything and test, swap IP addresses and reboot. In case of em, after 
>  > a soft reboot both systems are inaccessible.
>  > 
>  > A workaround is to power both of the systems down and then power them 
>  > up. This however cannot be done remotely and in case there were IP 
>  > aliases, they still don't get any traffic.
>  > 
> 
> I haven't fully tested it but what about attached patch?
> It may fix your ARP issue. The patch also fixes other issues
> related with ioctls.
> Now em(4) will send a ARP packet when its IP address is changed even
> if there is no active link. Since em(4) is not mii-aware driver I
> can't sure this behaviour is correct.
> 
The patch is against if_em.c,v 1.116 2006/06/06, which is 7-CURRENT. I 
tried "merging" the relevant em driver files into a 6-STABLE 
installation by simply copying sys/dev/em/* and sys/modules/em/Makefile, 
but it seems that the new revision depends on other -CURRENT things and 
the module build fails:

# pwd
/usr/src/sys/modules/em
# make clean; make
...
/usr/src/sys/modules/em/../../dev/em/if_em.c: In function 
`em_setup_interface':
/usr/src/sys/modules/em/../../dev/em/if_em.c:2143: error: 
`IFCAP_VLAN_HWCSUM' undeclared (first use in this function)
...

I don't have a 7-CURRENT based box around. It seems too bleeding edge 
for me anyway. I was hoping to play with different if_em kernel modules 
on a semi-production (spare) box and eventually test the proposed em 
patch, but apparently it's not so easy.

Please let me know if I'm missing something obvious.

Thanks,
Atanas

> 
> 
> ------------------------------------------------------------------------
> 
> Index: if_em.c
> ===================================================================
> RCS file: /pool/ncvs/src/sys/dev/em/if_em.c,v
> retrieving revision 1.116
> diff -u -r1.116 if_em.c
> --- if_em.c	6 Jun 2006 08:03:49 -0000	1.116
> +++ if_em.c	1 Jul 2006 03:51:41 -0000
> @@ -692,7 +692,8 @@
>  
>  	EM_LOCK_ASSERT(sc);
>  
> -	if (!sc->link_active)
> +	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
> +	    IFF_DRV_RUNNING)
>  		return;
>  
>  	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
> @@ -751,11 +752,6 @@
>  		return (error);
>  
>  	switch (command) {
> -	case SIOCSIFADDR:
> -	case SIOCGIFADDR:
> -		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
> -		ether_ioctl(ifp, command, data);
> -		break;
>  	case SIOCSIFMTU:
>  	    {
>  		int max_frame_size;
> @@ -802,17 +798,19 @@
>  		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
>  		EM_LOCK(sc);
>  		if (ifp->if_flags & IFF_UP) {
> -			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
> +			if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
> +				if ((ifp->if_flags ^ sc->if_flags) &
> +				    IFF_PROMISC) {
> +					em_disable_promisc(sc);
> +					em_set_promisc(sc);
> +				}
> +			} else
>  				em_init_locked(sc);
> -			}
> -
> -			em_disable_promisc(sc);
> -			em_set_promisc(sc);
>  		} else {
> -			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
> +			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
>  				em_stop(sc);
> -			}
>  		}
> +		sc->if_flags = ifp->if_flags;
>  		EM_UNLOCK(sc);
>  		break;
>  	case SIOCADDMULTI:
> @@ -878,8 +876,8 @@
>  		break;
>  	    }
>  	default:
> -		IOCTL_DEBUGOUT1("ioctl received: UNKNOWN (0x%x)", (int)command);
> -		error = EINVAL;
> +		error = ether_ioctl(ifp, command, data);
> +		break;
>  	}
>  
>  	return (error);
> Index: if_em.h
> ===================================================================
> RCS file: /pool/ncvs/src/sys/dev/em/if_em.h,v
> retrieving revision 1.44
> diff -u -r1.44 if_em.h
> --- if_em.h	15 Feb 2006 08:39:50 -0000	1.44
> +++ if_em.h	1 Jul 2006 03:51:41 -0000
> @@ -259,6 +259,7 @@
>  	struct callout	timer;
>  	struct callout	tx_fifo_timer;
>  	int		io_rid;
> +	int		if_flags;
>  	struct mtx	mtx;
>  	int		em_insert_vlan_header;
>  	struct task	link_task;
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> freebsd-stable at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-stable
> To unsubscribe, send any mail to "freebsd-stable-unsubscribe at freebsd.org"



More information about the freebsd-stable mailing list