Summary: | [net] [patch] em0 reinitialization while adding aliases to interface | ||
---|---|---|---|
Product: | Base System | Reporter: | Dmitry Sergienko <dmitry> |
Component: | kern | Assignee: | Eric Joyner <erj> |
Status: | Closed Unable to Reproduce | ||
Severity: | Affects Only Me | CC: | linimon, sbruno, shurd |
Priority: | Normal | Keywords: | IntelNetworking |
Version: | 5.4-RELEASE | ||
Hardware: | Any | ||
OS: | Any |
Description
Dmitry Sergienko
2005-05-17 11:00:25 UTC
On Tue, May 17, 2005 at 12:55:57PM +0300, Dmitry Sergienko wrote: > Network card looses link while adding an alias to interface em0. > This affects only em0 - neither vlans with vlandev em0, nor fxp0. > Problem was detected on two different machines with the same netcards > This simple patch works for me: %%% Index: if_em.c =================================================================== RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v retrieving revision 1.63 diff -u -p -r1.63 if_em.c --- if_em.c 5 Apr 2005 07:06:47 -0000 1.63 +++ if_em.c 14 Apr 2005 19:03:36 -0000 @@ -832,12 +832,14 @@ em_init_locked(struct adapter * adapter) bcopy(adapter->interface_data.ac_enaddr, adapter->hw.mac_addr, ETHER_ADDR_LEN); +#if 0 /* Initialize the hardware */ if (em_hardware_init(adapter)) { printf("em%d: Unable to initialize the hardware\n", adapter->unit); return; } +#endif if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) em_enable_vlans(adapter); %%% -- Ruslan Ermilov ru@FreeBSD.org FreeBSD committer Responsible Changed From-To: freebsd-bugs->tackerman Pass the PR and patch over to an official maintainer. Thanks, this patch solved my problem on 5.4-RELEASE. Will also try on 4.10 later. Hope it will be committed ASAP. -- Best wishes, Dmitry Sergienko (SDA104-RIPE) Trifle Co., Ltd. The problem seems to be at a higher level : ether_ioctl (net/if_ethersubr.c) The process when alias is added : 1) in_control (netinet/in.c) : int in_control(so, cmd, data, ifp, td) struct socket *so; u_long cmd; caddr_t data; register struct ifnet *ifp; struct thread *td; { ... case SIOCAIFADDR: ... if (ifra->ifra_addr.sin_family == AF_INET && (hostIsNew || maskIsNew)) error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 2) in_ifinit (netinet/in.c) : static int in_ifinit(ifp, ia, sin, scrub) register struct ifnet *ifp; register struct in_ifaddr *ia; struct sockaddr_in *sin; int scrub; { ... /* * Give the interface a chance to initialize * if this is its first address, * and to validate the address if necessary. */ if (ifp->if_ioctl) { error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia); 3) em_ioctl (dev/em/if_em.c) : static int em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { ... case SIOCSIFADDR: case SIOCGIFADDR: IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)"); ether_ioctl(ifp, command, data); break; 4) ether_ioctl (net/f_ethersubr.c) : int ether_ioctl(struct ifnet *ifp, int command, caddr_t data) { ... #ifdef INET case AF_INET: ifp->if_init(ifp->if_softc); /* before arpwhohas */ arp_ifinit(ifp, ifa); break; #endif At this step, the interface is reinitialized by the driver (em_init is registered as the interface init function). The question is : why do we need to reinitialize the hardware when the interface is up and running ? This behaviour seems to be transparent on some drivers (fxp, bge etc.) but certainly not with em. The patch that follows is inspired by NetBSD code : *** sys/net/if_ethersubr.c.gen Thu Jan 19 17:29:40 2006 --- sys/net/if_ethersubr.c Thu Jan 19 18:17:02 2006 *************** *** 1057,1063 **** switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: ! ifp->if_init(ifp->if_softc); /* before arpwhohas */ arp_ifinit(ifp, ifa); break; #endif --- 1057,1065 ---- switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: ! /* init only if not running */ ! if ((ifp->if_flags & IFF_RUNNING) == 0) ! ifp->if_init(ifp->if_softc); /* before arpwhohas */ arp_ifinit(ifp, ifa); break; #endif This patch has been tested and is functionnal with fxp, em, bge on 5.4-STABLE / i386. It could be applied on 5.x and 6.x (not looked at 4.x). Belaid Aitdahmane. State Changed From-To: open->feedback Is this still a problem with current versions of FreeBSD? Responsible Changed From-To: tackerman->linimon Reset PR assigned to inactive committer. Hat: gnats-admin State Changed From-To: feedback->suspended Feedback timeout. Set to suspended since it contains a patch. Responsible Changed From-To: linimon->freebsd-bugs Return this one to the pool. Responsible Changed From-To: freebsd-bugs->freebsd-net I'm going to reclassify this one. The original submitter did indeed submit a patch, which was kind of hacky; I got no response when asking for feedback. However, a later correspondant noted that this was more of a general problem, and submitted a patch against sys/net/if_ethersubr.c. Since that patch may need to be evaluated, I'll reassign this to -net. Responsible Changed From-To: freebsd-net->jfv Over to maintainer. Reassign to erj@ for triage. To submitter: is this issue still relevant? |