+static void
+proto_shell_check_dependencies(struct proto_shell_state *state)
+{
+ struct proto_shell_dependency *dep;
+ bool available = true;
+
+ list_for_each_entry(dep, &state->deps, list) {
+ if (dep->dep.iface)
+ continue;
+
+ available = false;
+ break;
+ }
+
+ interface_set_available(state->proto.iface, available);
+}
+
+static void
+proto_shell_if_up_cb(struct interface_user *dep, struct interface *iface,
+ enum interface_event ev);
+static void
+proto_shell_if_down_cb(struct interface_user *dep, struct interface *iface,
+ enum interface_event ev);
+
+static void
+proto_shell_update_host_dep(struct proto_shell_dependency *dep)
+{
+ struct interface *iface;
+
+ if (dep->dep.iface)
+ goto out;
+
+ iface = interface_ip_add_target_route(&dep->host, dep->v6);
+ if (!iface)
+ goto out;
+
+ interface_remove_user(&dep->dep);
+ dep->dep.cb = proto_shell_if_down_cb;
+ interface_add_user(&dep->dep, iface);
+
+out:
+ proto_shell_check_dependencies(dep->proto);
+}
+
+static void
+proto_shell_clear_host_dep(struct proto_shell_state *state)
+{
+ struct proto_shell_dependency *dep, *tmp;
+
+ list_for_each_entry_safe(dep, tmp, &state->deps, list) {
+ interface_remove_user(&dep->dep);
+ list_del(&dep->list);
+ free(dep);
+ }
+}
+