diff --git a/src/netconfig-commit.c b/src/netconfig-commit.c index 48ebe847..95b2a9d9 100644 --- a/src/netconfig-commit.c +++ b/src/netconfig-commit.c @@ -114,6 +114,32 @@ static void netconfig_commit_done(struct netconfig *netconfig, uint8_t family, enum l_netconfig_event event, bool success) { + bool connected = netconfig->connected[INDEX_FOR_AF(family)]; + + if (!success) { + netconfig->connected[INDEX_FOR_AF(family)] = false; + + if (netconfig->notify && family == AF_INET) + netconfig->notify(NETCONFIG_EVENT_FAILED, + netconfig->user_data); + return; + } + + switch (event) { + case L_NETCONFIG_EVENT_CONFIGURE: + case L_NETCONFIG_EVENT_UPDATE: + netconfig->connected[INDEX_FOR_AF(family)] = true; + + if (family == AF_INET && !connected && netconfig->notify) + netconfig->notify(NETCONFIG_EVENT_CONNECTED, + netconfig->user_data); + + break; + + case L_NETCONFIG_EVENT_UNCONFIGURE: + case L_NETCONFIG_EVENT_FAILED: + break; + } } static void netconfig_set_neighbor_entry_cb(int error, diff --git a/src/netconfig.c b/src/netconfig.c index 5b7a21ee..91830416 100644 --- a/src/netconfig.c +++ b/src/netconfig.c @@ -414,9 +414,8 @@ bool netconfig_configure(struct netconfig *netconfig, netconfig->notify = notify; netconfig->user_data = user_data; - /* TODO */ - - resolve_set_mdns(netconfig->resolve, netconfig->mdns); + if (unlikely(!l_netconfig_start(netconfig->nc))) + return false; return true; } @@ -449,6 +448,9 @@ bool netconfig_reset(struct netconfig *netconfig) l_netconfig_unconfigure(netconfig->nc); l_netconfig_stop(netconfig->nc); + netconfig->connected[0] = false; + netconfig->connected[1] = false; + netconfig_free_settings(netconfig); return true; } @@ -499,6 +501,44 @@ void netconfig_handle_fils_ip_resp(struct netconfig *netconfig, netconfig->fils_override = l_memdup(info, sizeof(*info)); } +static void netconfig_event_handler(struct l_netconfig *nc, uint8_t family, + enum l_netconfig_event event, + void *user_data) +{ + struct netconfig *netconfig = user_data; + + l_debug("l_netconfig event %d", event); + + netconfig_commit(netconfig, family, event); + + switch (event) { + case L_NETCONFIG_EVENT_CONFIGURE: + case L_NETCONFIG_EVENT_UPDATE: + break; + + case L_NETCONFIG_EVENT_UNCONFIGURE: + break; + + case L_NETCONFIG_EVENT_FAILED: + netconfig->connected[INDEX_FOR_AF(family)] = false; + + /* + * l_netconfig might have emitted an UNCONFIGURE before this + * but now it tells us it's given up on (re)establishing the + * IP setup. + */ + if (family == AF_INET && netconfig->notify) + netconfig->notify(NETCONFIG_EVENT_FAILED, + netconfig->user_data); + + break; + + default: + l_error("netconfig: Received unsupported l_netconfig event: %d", + event); + } +} + struct netconfig *netconfig_new(uint32_t ifindex) { struct netdev *netdev = netdev_find(ifindex); @@ -530,6 +570,9 @@ struct netconfig *netconfig_new(uint32_t ifindex) dhcp_priority = L_LOG_DEBUG; } + l_netconfig_set_event_handler(netconfig->nc, netconfig_event_handler, + netconfig, NULL); + l_dhcp_client_set_debug(l_netconfig_get_dhcp_client(netconfig->nc), do_debug, "[DHCPv4] ", NULL, dhcp_priority); diff --git a/src/netconfig.h b/src/netconfig.h index 9f4f3b77..50085aa7 100644 --- a/src/netconfig.h +++ b/src/netconfig.h @@ -27,6 +27,7 @@ struct ie_fils_ip_addr_response_info; enum netconfig_event { NETCONFIG_EVENT_CONNECTED, + NETCONFIG_EVENT_FAILED, }; typedef void (*netconfig_notify_func_t)(enum netconfig_event event, @@ -42,6 +43,7 @@ struct netconfig { bool static_config[2]; bool gateway_overridden[2]; bool dns_overridden[2]; + bool connected[2]; const struct l_settings *active_settings;