From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthias Weisser Date: Sat, 03 Dec 2011 16:06:58 +0100 Subject: [U-Boot] [PATCH RFC] sandbox: Add tap based networking In-Reply-To: <201111291339.17625.vapier@gentoo.org> References: <1322575743-21760-1-git-send-email-weisserm@arcor.de> <201111291024.58943.vapier@gentoo.org> <4ED522B2.6030002@arcor.de> <201111291339.17625.vapier@gentoo.org> Message-ID: <4EDA3B12.9030705@arcor.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Am 29.11.2011 19:39, schrieb Mike Frysinger: >>>> +static int tap_set_hwaddr(struct eth_device *dev) >>>> > >> +{ >>>> > >> + /* Nothing to be done here */ >>>> > >> + return 0; >>>> > >> +} >>> > > >>> > > isn't there an ioctl that lets you control this ? >> > >> > Sure. But if I read the the docs correct it is an privileged operation >> > and I don't think we wan't to run u-boot as super user all the time. How >> > is the situation handled on real hardware when the MAC is programmed to >> > an EEPROM on the NIC. Can the MAC be read from the NIC and set to >> > u-boot? This would be the best solution as linux should take care about >> > MAC address assignment. > the tap_initialize() func should read the current MAC address assigned to the > tap device and write that to dev->enetaddr Done. > then when tap_set_hwaddr() gets called, if the MAC is different, it will > attempt to set the MAC to what the user requested. if they don't have > permission, then the code can yell at them. but if they do, this should work > imo. this gets us the best of all worlds i think. I looked into that. It seems that you have to shut down the interface, change the MAC and up the interface again. I tried now to do this using some ioctls but didn't got it working as user or as root. So I give up at this point. Should I submit the V2 patch without setting MAC function anyway or will it not be applied then? If someone has an idea: Here is the (simplified) code to set the MAC of a tap interface. void os_tap_set_hw_addr(int fd, unsigned char *hwaddr) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, "tap0", IFNAMSIZ); /* Get the interface flags */ if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { perror("Could not get interface flags"); } /* Shut down the interface */ ifr.ifr_flags &= ~(IFF_UP); if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { perror("Could not down the interface"); } /* Set the new hw address */ ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; memcpy(&ifr.ifr_hwaddr.sa_data, hwaddr, ETH_ALEN); if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) { perror("ioctl(SIOCSIFHWADDR)"); } /* Get the interface flags */ if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { perror("Could not get interface flags"); } /* Shut down the interface */ ifr.ifr_flags |= IFF_UP; if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) { perror("Could not up the interface"); } } The SIOC{G,S}IFFLAGS ioctl calls fail with "Invalid argument" and the SIOCSIFHWADDR fails with "Device or resource busy". -- Matthias