3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-18 10:19:24 +01:00

netdev: React to interface address change

Handle the changes of interface address in RTNL New Link messages
similarly to the name changes, emit a NETDEV_WATCH_EVENT_ADDRESS_CHANGE
event and a propety change on dbus.

Note this can only happen when the interface is down so it doesn't
break anything but we need to handle it anyway.
This commit is contained in:
Andrew Zaborowski 2017-03-08 15:07:14 +01:00 committed by Denis Kenzior
parent 43a882e934
commit d67425c936
3 changed files with 24 additions and 5 deletions

View File

@ -1699,6 +1699,10 @@ static void device_netdev_notify(struct netdev *netdev,
l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Name");
break;
case NETDEV_WATCH_EVENT_ADDRESS_CHANGE:
l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Address");
break;
}
}

View File

@ -2585,6 +2585,7 @@ static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
struct netdev *netdev;
bool old_up, new_up;
char old_name[IFNAMSIZ];
uint8_t old_addr[ETH_ALEN];
struct rtattr *attr;
struct netdev_watch_event_data event;
@ -2594,17 +2595,23 @@ static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
old_up = netdev_get_is_up(netdev);
strcpy(old_name, netdev->name);
memcpy(old_addr, netdev->addr, ETH_ALEN);
netdev->ifi_flags = ifi->ifi_flags;
for (attr = IFLA_RTA(ifi); RTA_OK(attr, bytes);
attr = RTA_NEXT(attr, bytes)) {
if (attr->rta_type != IFLA_IFNAME)
continue;
switch (attr->rta_type) {
case IFLA_IFNAME:
strcpy(netdev->name, RTA_DATA(attr));
break;
case IFLA_ADDRESS:
if (RTA_PAYLOAD(attr) < ETH_ALEN)
break;
strcpy(netdev->name, RTA_DATA(attr));
break;
memcpy(netdev->addr, RTA_DATA(attr), ETH_ALEN);
break;
}
}
new_up = netdev_get_is_up(netdev);
@ -2623,6 +2630,13 @@ static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
l_queue_foreach(netdev->watches, netdev_watch_notify, &event);
}
if (memcmp(old_addr, netdev->addr, ETH_ALEN)) {
event.netdev = netdev;
event.type = NETDEV_WATCH_EVENT_ADDRESS_CHANGE;
l_queue_foreach(netdev->watches, netdev_watch_notify, &event);
}
}
static void netdev_dellink_notify(const struct ifinfomsg *ifi, int bytes)

View File

@ -52,6 +52,7 @@ enum netdev_watch_event {
NETDEV_WATCH_EVENT_UP,
NETDEV_WATCH_EVENT_DOWN,
NETDEV_WATCH_EVENT_NAME_CHANGE,
NETDEV_WATCH_EVENT_ADDRESS_CHANGE,
};
typedef void (*netdev_command_func_t) (bool result, void *user_data);