vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| How often do you hear the phrase "if you want it done, fix it" here? So I waste some sleep to fix it, and you guys seem annoyed that I do it before you? If you would have told me you were working on it, Ted, I wouldn't have wasted the hours. Also, I didn't know one driver needed fixing "so the patch actually works" (for that driver), which I why I asked here if anyone know of any special case that needs fixing... Anyway the code is a pretty direct port of freebsd code with only a few short specific parts. Among others setting the interface down and up, which btw you do wrong and instead break it. + ifp->if_flags &= IFF_UP; If you look closer at my code you'll see that it should be "|=". If you look further you will find that my code actually sends the arps through arp_ifinit(). /Fredrik Widlund p.s. using 60 instead of 31 for siocsiflladdr constant makes it freebsd compatible. Ted Unangst wrote: >sigh, this is what i get for being slow. this diff is similar, basically >prs 2117 and 2118 updated for the now. also includes an em diff so it >actually works. between the two, i like making the setiflladdr a >function, instead of inlined in the switch, but that seems the only >difference. > >the missing piece which we should have is that the kernel should send arps >so that other machines become aware of the change. i was looking into >this when i saw your mail. > >Index: sys/sys/sockio.h >================================================= ================== >RCS file: /cvs/src/sys/sys/sockio.h,v >retrieving revision 1.32 >diff -u -r1.32 sockio.h >--- sys/sys/sockio.h 2005/01/14 11:49:01 1.32 >+++ sys/sys/sockio.h 2005/03/26 09:36:45 >@@ -70,6 +70,7 @@ > #define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */ > #define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */ > #define SIOCGIFDATA _IOWR('i', 27, struct ifreq) /* get if_data */ >+#define SIOCSIFLLADDR _IOW('i', 31, struct ifreq) /* set link level addr */ > > /* KAME IPv6 */ > /* SIOCAIFALIAS? */ >Index: sbin/ifconfig/ifconfig.c >================================================= ================== >RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v >retrieving revision 1.131 >diff -u -r1.131 ifconfig.c >--- sbin/ifconfig/ifconfig.c 2005/02/15 19:45:22 1.131 >+++ sbin/ifconfig/ifconfig.c 2005/03/26 09:36:46 >@@ -159,6 +159,7 @@ > void setifgroup(const char *, int); > void unsetifgroup(const char *, int); > void setifaddr(const char *, int); >+void setiflladdr(const char *, int); > void setifdstaddr(const char *, int); > void setifflags(const char *, int); > void setifbroadaddr(const char *, int); >@@ -351,6 +352,7 @@ > { "mode", NEXTARG, A_MEDIAMODE, setmediamode }, > { "instance", NEXTARG, A_MEDIAINST, setmediainst }, > { "inst", NEXTARG, A_MEDIAINST, setmediainst }, >+ { "lladdr", NEXTARG, 0, setiflladdr }, > { "description", NEXTARG, 0, setifdesc }, > { "descr", NEXTARG, 0, setifdesc }, > { NULL, /*src*/ 0, 0, setifaddr }, >@@ -3337,7 +3339,7 @@ > "\t[[-]debug] [delete] [up] [down] [ipdst addr]\n" > "\t[tunnel src_address dest_address] [deletetunnel]\n" > "\t[description value] [[-]group group-name]\n" >- "\t[[-]link0] [[-]link1] [[-]link2]\n" >+ "\t[[-]link0] [[-]link1] [[-]link2] [lladdr addr]\n" > "\t[media type] [[-]mediaopt opts] [mode mode] [instance minst]\n" > "\t[mtu value] [metric nhops] [netmask mask] [prefixlen n]\n" > "\t[nwid id] [nwkey key] [nwkey persist[:key]] [-nwkey]\n" >@@ -3449,3 +3451,21 @@ > return (result); > } > #endif /* INET6 */ >+ >+void >+setiflladdr(const char *addr, int param) >+{ >+ struct ether_addr *eap; >+ >+ eap = ether_aton(addr); >+ if (eap == NULL) { >+ warnx("malformed link-level address"); >+ return; >+ } >+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); >+ ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; >+ ifr.ifr_addr.sa_family = AF_LINK; >+ bcopy(eap, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN); >+ if (ioctl(s, SIOCSIFLLADDR, (caddr_t)&ifr) < 0) >+ warn("SIOCSIFLLADDR"); >+} >Index: sys/net/if.c >================================================= ================== >RCS file: /cvs/src/sys/net/if.c,v >retrieving revision 1.104 >diff -u -r1.104 if.c >--- sys/net/if.c 2005/02/07 15:00:16 1.104 >+++ sys/net/if.c 2005/03/26 09:36:46 >@@ -128,6 +128,7 @@ > int if_detached_ioctl(struct ifnet *, u_long, caddr_t); > int if_detached_init(struct ifnet *); > void if_detached_watchdog(struct ifnet *); >+int if_setlladdr(struct ifnet *, u_char *, int); > > int if_clone_list(struct if_clonereq *); > struct if_clone *if_clone_lookup(const char *, int *); >@@ -1345,6 +1346,13 @@ > return (error); > break; > >+ case SIOCSIFLLADDR: >+ if ((error = suser(p, 0)) != 0) >+ return (error); >+ return if_setlladdr(ifp, ifr->ifr_addr.sa_data, >+ ifr->ifr_addr.sa_len); >+ break; >+ > default: > if (so->so_proto == 0) > return (EOPNOTSUPP); >@@ -1692,4 +1700,54 @@ > } > ifr.ifr_flags = ifp->if_flags; > return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); >+} >+ >+/* >+ * Set the link layer address on an interface. >+ * >+ * At this time we only support certain types of interfaces, >+ * and we don't allow the length of the address to change. >+ */ >+int >+if_setlladdr(ifp, lladdr, lladdrlen) >+ struct ifnet *ifp; >+ u_char *lladdr; >+ int lladdrlen; >+{ >+ struct sockaddr_dl *sdl; >+ struct ifaddr *ifa; >+ >+ ifa = ifnet_addrs[ifp->if_index]; >+ if (ifa == NULL) >+ return (EINVAL); >+ sdl = (struct sockaddr_dl *)ifa->ifa_addr; >+ if (sdl == NULL) >+ return (EINVAL); >+ if (lladdrlen != ETHER_ADDR_LEN) >+ return (EINVAL); >+ switch (ifp->if_type) { >+ case IFT_ETHER: >+ case IFT_FDDI: >+ case IFT_XETHER: >+ case IFT_ISO88025: >+ /* finally copy new link level address */ >+ bcopy(lladdr, (caddr_t)((struct arpcom *)ifp)->ac_enaddr, >+ ETHER_ADDR_LEN); >+ bcopy(lladdr, LLADDR(sdl), ETHER_ADDR_LEN); >+ break; >+ default: >+ return (ENODEV); >+ } >+ >+ /* If the interface is already up, we need >+ * to re-init it in order to reprogram its >+ * address filter. >+ */ >+ if ((ifp->if_flags & IFF_UP) != 0) { >+ ifp->if_flags &= ~IFF_UP; >+ (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); >+ ifp->if_flags &= IFF_UP; >+ (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL); >+ } >+ return (0); > } >Index: sys/dev/pci/if_em.c >================================================= ================== >RCS file: /cvs/src/sys/dev/pci/if_em.c,v >retrieving revision 1.39 >diff -u -r1.39 if_em.c >--- sys/dev/pci/if_em.c 2005/03/16 11:59:09 1.39 >+++ sys/dev/pci/if_em.c 2005/03/26 09:36:47 >@@ -1074,11 +1074,9 @@ > INIT_DEBUGOUT1("em_init: pba=%dK",pba); > E1000_WRITE_REG(&sc->hw, PBA, pba); > >-#ifdef __FreeBSD__ > /* Get the latest mac address, User can use a LAA */ > bcopy(sc->interface_data.ac_enaddr, sc->hw.mac_addr, > ETHER_ADDR_LEN); >-#endif /* __FreeBSD__ */ > > /* Initialize the hardware */ > if (em_hardware_init(sc)) { |