[U-Boot] [PATCH RFC] sandbox: Add tap based networking
Matthias Weisser
weisserm at arcor.de
Sat Dec 3 16:06:58 CET 2011
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
More information about the U-Boot
mailing list