netdev: Reset interface state on init and exit
Take any managed interface down when iwd detects it and bring it back up to start with a clean state. On exit take interfaces down.
This commit is contained in:
parent
2e845b5ee2
commit
19fa024bd8
|
@ -63,6 +63,7 @@ static void signal_handler(struct l_signal *signal, uint32_t signo,
|
||||||
l_info("Terminate");
|
l_info("Terminate");
|
||||||
|
|
||||||
dbus_shutdown();
|
dbus_shutdown();
|
||||||
|
netdev_shutdown();
|
||||||
|
|
||||||
timeout = l_timeout_create(1, main_loop_quit, NULL, NULL);
|
timeout = l_timeout_create(1, main_loop_quit, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
79
src/netdev.c
79
src/netdev.c
|
@ -54,6 +54,7 @@ struct netdev {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint8_t addr[ETH_ALEN];
|
uint8_t addr[ETH_ALEN];
|
||||||
struct device *device;
|
struct device *device;
|
||||||
|
struct wiphy *wiphy;
|
||||||
unsigned int ifi_flags;
|
unsigned int ifi_flags;
|
||||||
|
|
||||||
netdev_event_func_t event_filter;
|
netdev_event_func_t event_filter;
|
||||||
|
@ -269,6 +270,15 @@ static void netdev_free(void *data)
|
||||||
|
|
||||||
l_debug("Freeing netdev %s[%d]", netdev->name, netdev->index);
|
l_debug("Freeing netdev %s[%d]", netdev->name, netdev->index);
|
||||||
|
|
||||||
|
l_queue_destroy(netdev->watches, l_free);
|
||||||
|
|
||||||
|
l_free(netdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void netdev_shutdown_one(void *data, void *user_data)
|
||||||
|
{
|
||||||
|
struct netdev *netdev = data;
|
||||||
|
|
||||||
device_remove(netdev->device);
|
device_remove(netdev->device);
|
||||||
|
|
||||||
if (netdev->sm) {
|
if (netdev->sm) {
|
||||||
|
@ -288,9 +298,8 @@ static void netdev_free(void *data)
|
||||||
netdev_operstate_down_cb,
|
netdev_operstate_down_cb,
|
||||||
L_UINT_TO_PTR(netdev->index));
|
L_UINT_TO_PTR(netdev->index));
|
||||||
|
|
||||||
l_queue_destroy(netdev->watches, l_free);
|
if (netdev_get_is_up(netdev))
|
||||||
|
netdev_set_powered(netdev, false, NULL, NULL, NULL);
|
||||||
l_free(netdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool netdev_match(const void *a, const void *b)
|
static bool netdev_match(const void *a, const void *b)
|
||||||
|
@ -1198,11 +1207,46 @@ static void netdev_dellink_notify(const struct ifinfomsg *ifi, int bytes)
|
||||||
netdev_free(netdev);
|
netdev_free(netdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void netdev_initial_up_cb(struct netdev *netdev, int result,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
if (result != 0) {
|
||||||
|
l_error("Error bringing interface %i up: %s", netdev->index,
|
||||||
|
strerror(-result));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
||||||
|
IF_OPER_DORMANT,
|
||||||
|
netdev_operstate_dormant_cb,
|
||||||
|
netdev);
|
||||||
|
|
||||||
|
l_debug("Interface %i initialized", netdev->index);
|
||||||
|
|
||||||
|
netdev->device = device_create(netdev->wiphy, netdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void netdev_initial_down_cb(struct netdev *netdev, int result,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
if (result != 0) {
|
||||||
|
l_error("Error taking interface %i down: %s", netdev->index,
|
||||||
|
strerror(-result));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_set_powered(netdev, true, netdev_initial_up_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void netdev_getlink_cb(int error, uint16_t type, const void *data,
|
static void netdev_getlink_cb(int error, uint16_t type, const void *data,
|
||||||
uint32_t len, void *user_data)
|
uint32_t len, void *user_data)
|
||||||
{
|
{
|
||||||
const struct ifinfomsg *ifi = data;
|
const struct ifinfomsg *ifi = data;
|
||||||
unsigned int bytes;
|
unsigned int bytes;
|
||||||
|
struct netdev *netdev;
|
||||||
|
|
||||||
if (error != 0 || ifi->ifi_type != ARPHRD_ETHER ||
|
if (error != 0 || ifi->ifi_type != ARPHRD_ETHER ||
|
||||||
type != RTM_NEWLINK) {
|
type != RTM_NEWLINK) {
|
||||||
|
@ -1211,9 +1255,23 @@ static void netdev_getlink_cb(int error, uint16_t type, const void *data,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netdev = netdev_find(ifi->ifi_index);
|
||||||
|
if (!netdev)
|
||||||
|
return;
|
||||||
|
|
||||||
bytes = len - NLMSG_ALIGN(sizeof(struct ifinfomsg));
|
bytes = len - NLMSG_ALIGN(sizeof(struct ifinfomsg));
|
||||||
|
|
||||||
netdev_newlink_notify(ifi, bytes);
|
netdev_newlink_notify(ifi, bytes);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the interface is UP, reset it to ensure a clean state,
|
||||||
|
* otherwise just bring it UP.
|
||||||
|
*/
|
||||||
|
if (netdev_get_is_up(netdev)) {
|
||||||
|
netdev_set_powered(netdev, false, netdev_initial_down_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
} else
|
||||||
|
netdev_initial_down_cb(netdev, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool netdev_is_managed(const char *ifname)
|
static bool netdev_is_managed(const char *ifname)
|
||||||
|
@ -1342,16 +1400,11 @@ static void netdev_get_interface_callback(struct l_genl_msg *msg,
|
||||||
netdev->rekey_offload_support = true;
|
netdev->rekey_offload_support = true;
|
||||||
memcpy(netdev->addr, ifaddr, sizeof(netdev->addr));
|
memcpy(netdev->addr, ifaddr, sizeof(netdev->addr));
|
||||||
memcpy(netdev->name, ifname, ifname_len);
|
memcpy(netdev->name, ifname, ifname_len);
|
||||||
|
netdev->wiphy = wiphy;
|
||||||
|
|
||||||
l_queue_push_tail(netdev_list, netdev);
|
l_queue_push_tail(netdev_list, netdev);
|
||||||
|
|
||||||
netdev_set_linkmode_and_operstate(netdev->index, 1,
|
|
||||||
IF_OPER_DORMANT,
|
|
||||||
netdev_operstate_dormant_cb,
|
|
||||||
netdev);
|
|
||||||
|
|
||||||
l_debug("Found interface %s[%d]", netdev->name, netdev->index);
|
l_debug("Found interface %s[%d]", netdev->name, netdev->index);
|
||||||
netdev->device = device_create(wiphy, netdev);
|
|
||||||
|
|
||||||
/* Query interface flags */
|
/* Query interface flags */
|
||||||
bufsize = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
bufsize = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
|
@ -1569,3 +1622,11 @@ bool netdev_exit(void)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void netdev_shutdown(void)
|
||||||
|
{
|
||||||
|
if (!rtnl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
l_queue_foreach(netdev_list, netdev_shutdown_one, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -85,3 +85,4 @@ bool netdev_watch_remove(struct netdev *netdev, uint32_t id);
|
||||||
bool netdev_init(struct l_genl_family *in,
|
bool netdev_init(struct l_genl_family *in,
|
||||||
const char *whitelist, const char *blacklist);
|
const char *whitelist, const char *blacklist);
|
||||||
bool netdev_exit(void);
|
bool netdev_exit(void);
|
||||||
|
void netdev_shutdown(void);
|
||||||
|
|
Loading…
Reference in New Issue