On Linux, it is not possible to set the mac address on "up" tap
interfaces. This commit temporarily "down"s the interface so the
address can be set for the netdev_linux_set_etheraddr() call.
Signed-off-by: Justin Pettit <jpettit@nicira.com>
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev_));
int error;
struct netdev_dev_linux *netdev_dev =
netdev_dev_linux_cast(netdev_get_dev(netdev_));
int error;
if (netdev_dev->cache_valid & VALID_ETHERADDR) {
if (netdev_dev->ether_addr_error) {
if (netdev_dev->cache_valid & VALID_ETHERADDR) {
if (netdev_dev->ether_addr_error) {
netdev_dev->cache_valid &= ~VALID_ETHERADDR;
}
netdev_dev->cache_valid &= ~VALID_ETHERADDR;
}
+ /* Tap devices must be brought down before setting the address. */
+ if (!strcmp(netdev_get_type(netdev_), "tap")) {
+ enum netdev_flags flags;
+
+ if (!netdev_get_flags(netdev_, &flags) && (flags & NETDEV_UP)) {
+ netdev_turn_flags_off(netdev_, NETDEV_UP, false);
+ up_again = true;
+ }
+ }
error = set_etheraddr(netdev_get_name(netdev_), mac);
if (!error || error == ENODEV) {
netdev_dev->ether_addr_error = error;
error = set_etheraddr(netdev_get_name(netdev_), mac);
if (!error || error == ENODEV) {
netdev_dev->ether_addr_error = error;
+ if (up_again) {
+ netdev_turn_flags_on(netdev_, NETDEV_UP, false);
+ }
+