This is a discussion on Re: staring at the sea within the lucky.openbsd.tech forums, part of the OpenBSD category; --> sigh, this is what i get for being slow. this diff is similar, basically prs 2117 and 2118 updated ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| 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)) { -- quit whining you haven't done anything wrong because frankly you haven't done much of anything |