static ni_netdev_t * __ni_objectmodel_dummy_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev_ifp = NULL; int rv; if (ni_string_empty(ifname)) { if (ni_string_empty(cfg_ifp->name) && (ifname = ni_netdev_make_name(nc, "dummy", 0))) { ni_string_dup(&cfg_ifp->name, ifname); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create dummy interface: " "name argument missed"); goto out; } ifname = NULL; } else if(!ni_string_eq(cfg_ifp->name, ifname)) { ni_string_dup(&cfg_ifp->name, ifname); } if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create dummy interface: " "invalid ethernet address '%s'", ni_link_address_print(&cfg_ifp->link.hwaddr)); return NULL; } } if ((rv = ni_system_dummy_create(nc, cfg_ifp, &dev_ifp)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL || (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create dummy interface: %s", ni_strerror(rv)); dev_ifp = NULL; goto out; } ni_debug_dbus("dummy interface exists (and name matches)"); } if (dev_ifp->link.type != NI_IFTYPE_DUMMY) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create dummy interface: " "new interface is of type %s", ni_linktype_type_to_name(dev_ifp->link.type)); dev_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return dev_ifp; }
/* * Interface.acquire(dict options) * Acquire a lease for the given interface. * * Server side method implementation */ static dbus_bool_t __wicked_dbus_autoip4_acquire_svc(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_autoip_device_t *dev = ni_objectmodel_unwrap_autoip4_device(object); dbus_bool_t ret = FALSE; int rv; ni_debug_dbus("%s(dev=%s)", __func__, dev->ifname); /* Ignore all arguments for now */ if ((rv = ni_autoip_acquire(dev)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot configure interface %s: %s", dev->ifname, ni_strerror(rv)); goto failed; } /* We've now initiated the IPv4ll exchange. It will complete * asynchronously, and when done, we will emit a signal that * notifies the sender of its results. */ ret = TRUE; failed: return ret; }
/* * Interface.drop(void) * Drop a IPv4ll lease */ static dbus_bool_t __wicked_dbus_autoip4_drop_svc(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_autoip_device_t *dev = ni_objectmodel_unwrap_autoip4_device(object); dbus_bool_t ret = FALSE; ni_uuid_t uuid; int rv; ni_debug_dbus("%s(dev=%s)", __func__, dev->ifname); memset(&uuid, 0, sizeof(uuid)); if (argc == 1) { /* Extract the lease uuid and pass that along to ni_autoip_release. * This makes sure we don't cancel the wrong lease. */ if (!ni_dbus_variant_get_uuid(&argv[0], &uuid)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "bad uuid argument"); goto failed; } } if ((rv = ni_autoip_release(dev, &uuid)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to drop IPv4ll lease for interface %s: %s", dev->ifname, ni_strerror(rv)); goto failed; } ret = TRUE; failed: return ret; }
static dbus_bool_t ni_objectmodel_addrconf_static_drop(ni_dbus_object_t *object, unsigned int addrfamily, ni_dbus_message_t *reply, DBusError *error) { ni_addrconf_lease_t *lease = NULL; ni_netdev_t *dev; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; lease = ni_addrconf_lease_new(NI_ADDRCONF_STATIC, addrfamily); lease->state = NI_ADDRCONF_STATE_RELEASED; rv = __ni_system_interface_update_lease(dev, &lease); if (lease) ni_addrconf_lease_free(lease); if (rv < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error dropping static %s addresses: %s", ni_addrfamily_type_to_name(addrfamily), ni_strerror(rv)); return FALSE; } /* Don't return anything */ return TRUE; }
/* * InfinibandChild.Factory.newDevice: * Create a new infiniband child interface */ static ni_netdev_t * __ni_objectmodel_ib_newchild(ni_netdev_t *cfg, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev = NULL; const ni_infiniband_t *ib; const char *err; int rv; ib = ni_netdev_get_infiniband(cfg); if ((err = ni_infiniband_validate(NI_IFTYPE_INFINIBAND_CHILD, ib, &cfg->link.lowerdev)) != NULL) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err); return NULL; } if (ni_string_empty(ifname)) { if (ni_string_empty(cfg->name) && !ni_string_printf(&cfg->name, "%s.%04x", cfg->link.lowerdev.name, ib->pkey)) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create infiniband child: " "name argument missed, failed to construct"); return NULL; } ifname = NULL; } else if (!ni_string_eq(cfg->name, ifname)) { ni_string_dup(&cfg->name, ifname); } if (ni_string_eq(cfg->name, cfg->link.lowerdev.name)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot to create infiniband child: " "child name %s equal with parent device name", cfg->name); return NULL; } if ((rv = ni_system_infiniband_child_create(nc, cfg, &dev)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || !dev || (ifname && dev && !ni_string_eq(ifname, dev->name))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create infiniband child interface: %s", ni_strerror(rv)); return NULL; } } if (dev && dev->link.type != NI_IFTYPE_INFINIBAND_CHILD) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create infiniband child interface %s: it exists with type %s", cfg->name, ni_linktype_type_to_name(dev->link.type)); return NULL; } return dev; }
static ni_netdev_t * __ni_objectmodel_team_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *new_ifp = NULL; int rv; ni_netdev_get_team(cfg_ifp); if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "team", 0))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface - too many interfaces"); goto out; } ni_string_dup(&cfg_ifp->name, ifname); if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create team interface: invalid ethernet address '%s'", ni_link_address_print(&cfg_ifp->link.hwaddr)); goto out; } } if ((rv = ni_system_team_create(nc, cfg_ifp, &new_ifp)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface '%s'", cfg_ifp->name); new_ifp = NULL; goto out; #if 0 if (rv != -NI_ERROR_DEVICE_EXISTS && (ifname != NULL && strcmp(ifname, new_ifp->name))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface: %s", ni_strerror(rv)); goto out; } ni_debug_dbus("Bonding interface exists (and name matches)"); #endif } if (new_ifp->link.type != NI_IFTYPE_TEAM) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface: new interface is of type %s", ni_linktype_type_to_name(new_ifp->link.type)); new_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return new_ifp; }
/* * Generic functions for static address configuration */ static dbus_bool_t ni_objectmodel_addrconf_static_request(ni_dbus_object_t *object, unsigned int addrfamily, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_addrconf_lease_t *lease = NULL; const ni_dbus_variant_t *dict; const char *string_value; ni_netdev_t *dev; ni_address_t *ap; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; if (argc != 1 || !ni_dbus_variant_is_dict(&argv[0])) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "requestLease: expected one dict argument"); return FALSE; } dict = &argv[0]; lease = ni_addrconf_lease_new(NI_ADDRCONF_STATIC, addrfamily); lease->state = NI_ADDRCONF_STATE_GRANTED; ni_uuid_generate(&lease->uuid); if (!__ni_objectmodel_set_address_dict(&lease->addrs, dict, error) || !__ni_objectmodel_set_route_dict(&lease->routes, dict, error) || !__ni_objectmodel_set_resolver_dict(&lease->resolver, dict, error)) { ni_addrconf_lease_free(lease); return FALSE; } if (__ni_objectmodel_get_domain_string(dict, "hostname", &string_value)) ni_string_dup(&lease->hostname, string_value); /* mark all addresses tentative, causing to verify them */ for (ap = lease->addrs; ap; ap = ap->next) ni_address_set_tentative(ap, TRUE); rv = __ni_system_interface_update_lease(dev, &lease); if (lease) ni_addrconf_lease_free(lease); if (rv < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error configuring static %s addresses: %s", ni_addrfamily_type_to_name(addrfamily), ni_strerror(rv)); return FALSE; } /* Don't return anything. */ return TRUE; }
/* * Refresh the device mtu and MAC address info prior to taking any actions */ int ni_dhcp4_device_refresh(ni_dhcp4_device_t *dev) { ni_netconfig_t *nih = ni_global_state_handle(0); int rv; if ((rv = __ni_device_refresh_link_info(nih, &dev->link)) < 0) { ni_error("%s: cannot refresh interface: %s", __func__, ni_strerror(rv)); return rv; } return ni_capture_devinfo_refresh(&dev->system, dev->ifname, &dev->link); }
/* * Process a request to reconfigure the device (ie rebind a lease, or discover * a new lease). */ int ni_autoip_device_refresh(ni_autoip_device_t *dev) { ni_netconfig_t *nih = ni_global_state_handle(0); int rv; /* Go back to INIT state to force a reclaim */ dev->fsm.state = NI_AUTOIP_STATE_INIT; if ((rv = __ni_device_refresh_link_info(nih, &dev->link)) < 0) { ni_error("%s: cannot refresh interface: %s", __func__, ni_strerror(rv)); return rv; } return ni_capture_devinfo_refresh(&dev->devinfo, dev->ifname, &dev->link); }
static ni_netdev_t * __ni_objectmodel_bond_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *new_ifp = NULL; const ni_bonding_t *bond; int rv; bond = ni_netdev_get_bonding(cfg_ifp); if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "bond", 0))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface - too many interfaces"); goto out; } ni_string_dup(&cfg_ifp->name, ifname); if ((rv = ni_system_bond_create(nc, cfg_ifp->name, bond, &new_ifp)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface '%s'", cfg_ifp->name); new_ifp = NULL; goto out; #if 0 if (rv != -NI_ERROR_DEVICE_EXISTS && (ifname != NULL && strcmp(ifname, new_ifp->name))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface: %s", ni_strerror(rv)); goto out; } ni_debug_dbus("Bonding interface exists (and name matches)"); #endif } if (new_ifp->link.type != NI_IFTYPE_BOND) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface: new interface is of type %s", ni_linktype_type_to_name(new_ifp->link.type)); new_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return new_ifp; }
/* * Bring up the device */ void ni_managed_device_down(ni_managed_device_t *mdev) { ni_fsm_t *fsm = mdev->nanny->fsm; ni_ifworker_t *w = mdev->worker; int rv; ni_ifworker_set_completion_callback(w, ni_managed_device_down_done, mdev->nanny); ni_ifworker_set_config(w, mdev->selected_config, w->config.meta.origin); w->target_range.min = NI_FSM_STATE_NONE; w->target_range.max = NI_FSM_STATE_DEVICE_DOWN; if ((rv = ni_ifworker_start(fsm, w, fsm->worker_timeout)) >= 0) { mdev->state = NI_MANAGED_STATE_STOPPING; } else { ni_error("%s: cannot stop device: %s", w->name, ni_strerror(rv)); mdev->state = NI_MANAGED_STATE_FAILED; } }
static ni_netdev_t * __ni_objectmodel_ovs_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *new_ifp = NULL; int rv; ni_netdev_get_ovs_bridge(cfg_ifp); if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ovsbr", 0))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ovs bridge interface - too many interfaces"); goto out; } ni_string_dup(&cfg_ifp->name, ifname); if ((rv = ni_system_ovs_bridge_create(nc, cfg_ifp, &new_ifp)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || new_ifp == NULL || (ifname && new_ifp && !ni_string_eq(ifname, new_ifp->name))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create OVS bridge device: %s", ni_strerror(rv)); new_ifp = NULL; goto out; } ni_debug_dbus("OVS bridge device %s exists (and with correct type)", ifname); } if (new_ifp->link.type != NI_IFTYPE_OVS_BRIDGE) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ovs bridge interface: new interface is of type %s", ni_linktype_type_to_name(new_ifp->link.type)); new_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return new_ifp; }
/* * Delete a PPP interface */ dbus_bool_t ni_objectmodel_ppp_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netdev_t *dev; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("dev=%s", dev->name); if ((rv = ni_system_ppp_delete(dev)) < 0) { ni_dbus_set_error_from_code(error, rv, "Unable to delete PPP interface %s: %s", dev->name, ni_strerror(rv)); return FALSE; } ni_dbus_object_free(object); return TRUE; }
static dbus_bool_t __ni_objectmodel_macvlan_delete(ni_dbus_object_t *object, const ni_dbus_method_t *method, unsigned int argc, const ni_dbus_variant_t *argv, ni_dbus_message_t *reply, DBusError *error) { ni_netdev_t *dev; int rv; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return FALSE; NI_TRACE_ENTER_ARGS("dev=%s", dev->name); if ((rv = ni_system_macvlan_delete(dev)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error deleting macvlan interface %s: %s", dev->name, ni_strerror(rv)); return FALSE; } ni_client_state_drop(dev->link.ifindex); return TRUE; }
static ni_netdev_t * __ni_objectmodel_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *new_ifp = NULL; const ni_bridge_t *bridge; int rv; bridge = ni_netdev_get_bridge(cfg_ifp); if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "br", 0))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bridging interface - too many interfaces"); goto out; } ni_string_dup(&cfg_ifp->name, ifname); if ((rv = ni_system_bridge_create(nc, cfg_ifp->name, bridge, &new_ifp)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bridging interface: %s", ni_strerror(rv)); new_ifp = NULL; goto out; } if (new_ifp->link.type != NI_IFTYPE_BRIDGE) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bridging interface: new interface is of type %s", ni_linktype_type_to_name(new_ifp->link.type)); new_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return new_ifp; }
/* * Bring up the device */ static int ni_managed_device_up(ni_managed_device_t *mdev, const char *origin) { ni_fsm_t *fsm = mdev->nanny->fsm; ni_ifworker_t *w = mdev->worker; unsigned int previous_state; unsigned int target_state; ni_security_id_t security_id = NI_SECURITY_ID_INIT; ni_ifworker_array_t ifmarked = NI_IFWORKER_ARRAY_INIT; ni_ifmarker_t ifmarker; int rv = -NI_ERROR_DEVICE_NOT_COMPATIBLE; memset(&ifmarker, 0, sizeof(ifmarker)); switch (w->type) { case NI_IFWORKER_TYPE_NETDEV: mdev->max_fail_count = 3; if (w->device->link.type == NI_IFTYPE_WIRELESS) { const char *essid; ni_security_id_init(&security_id, "wireless"); if ((essid = ni_managed_device_get_essid(mdev->selected_config)) != NULL) ni_security_id_set_attr(&security_id, "essid", essid); } target_state = NI_FSM_STATE_ADDRCONF_UP; break; case NI_IFWORKER_TYPE_MODEM: mdev->max_fail_count = 1; ni_security_id_init(&security_id, "modem"); if (w->modem->identify.equipment) ni_security_id_set_attr(&security_id, "equipment-id", w->modem->identify.equipment); target_state = NI_FSM_STATE_LINK_UP; break; default: goto failed; } if (ni_security_id_valid(&security_id)) ni_managed_device_set_security_id(mdev, &security_id); ni_ifworker_set_completion_callback(w, ni_managed_device_up_done, mdev->nanny); ni_ifworker_set_config(w, mdev->selected_config, origin); ifmarker.target_range.min = target_state; ifmarker.target_range.max = __NI_FSM_STATE_MAX; ifmarker.persistent = w->control.persistent; ni_ifworker_array_append(&ifmarked, w); ni_fsm_pull_in_children(&ifmarked); /* Binding: this validates the XML configuration document, * resolves any references to other devices (if there are any), * and retrieves any keys/passwords etc via the prompt callback. * Inside the prompt callback, we record all secrets for tracking */ ni_secret_array_destroy(&mdev->secrets); previous_state = mdev->state; mdev->state = NI_MANAGED_STATE_BINDING; if ((rv = ni_ifworker_bind_early(w, fsm, TRUE)) < 0) goto failed; if (mdev->missing_secrets) { /* FIXME: Emit an event listing the secrets we're missing. */ mdev->state = previous_state; return -1; } mdev->state = NI_MANAGED_STATE_STARTING; ni_fsm_mark_matching_workers(fsm, &ifmarked, &ifmarker); ni_ifworker_array_destroy(&ifmarked); return 0; failed: ni_error("%s: cannot start device: %s", w->name, ni_strerror(rv)); mdev->state = NI_MANAGED_STATE_FAILED; return -1; }
/* * Install information from a lease, and remember that we did */ static ni_bool_t ni_system_updater_install(ni_updater_t *updater, const ni_addrconf_lease_t *lease, const char *ifname) { ni_string_array_t arguments = NI_STRING_ARRAY_INIT; const char *statedir = NULL; char *file = NULL; ni_bool_t result = FALSE; int rv = 0; ni_debug_ifconfig("Updating system %s settings from %s/%s lease", ni_updater_name(updater->kind), ni_addrconf_type_to_name(lease->type), ni_addrfamily_type_to_name(lease->family)); if (!updater->proc_install) return TRUE; if (!ifname || (!updater->have_backup && !ni_system_updater_backup(updater, ifname))) return FALSE; ni_string_array_append(&arguments, "-i"); ni_string_array_append(&arguments, ifname); ni_string_array_append(&arguments, "-t"); ni_string_array_append(&arguments, ni_addrconf_type_to_name(lease->type)); ni_string_array_append(&arguments, "-f"); ni_string_array_append(&arguments, ni_addrfamily_type_to_name(lease->family)); switch (updater->kind) { case NI_ADDRCONF_UPDATER_GENERIC: switch (updater->format) { case NI_ADDRCONF_UPDATER_FORMAT_INFO: ni_leaseinfo_dump(NULL, lease, ifname, NULL); if (!(file = ni_leaseinfo_path(ifname, lease->type, lease->family))) { ni_error("Unable to determine leaseinfo file path."); goto done; } ni_string_array_append(&arguments, file); break; default: ni_error("Unsupported %s updater data format.", ni_updater_name(updater->kind)); goto done; } ni_string_array_append(&arguments, ni_updater_format_name(updater->format)); break; case NI_ADDRCONF_UPDATER_RESOLVER: statedir = ni_extension_statedir(ni_updater_name(updater->kind)); if (!statedir) { ni_error("failed to get %s statedir", ni_updater_name(updater->kind)); goto done; } ni_string_printf(&file, "%s/resolv.conf.%s.%s.%s", statedir, ifname, ni_addrconf_type_to_name(lease->type), ni_addrfamily_type_to_name(lease->family)); ni_string_array_append(&arguments, file); if ((rv = ni_resolver_write_resolv_conf(file, lease->resolver, NULL)) < 0) { ni_error("failed to write resolver info to file: %s", ni_strerror(rv)); goto done; } break; case NI_ADDRCONF_UPDATER_HOSTNAME: if (!ni_string_empty(lease->hostname)) { ni_string_array_append(&arguments, lease->hostname); } else { const ni_address_t *ap; char *name = NULL; unsigned int count; /* bnc#861476 workaround */ if (!can_try_reverse_lookup(lease)) goto done; for (count = 0, ap = lease->addrs; ap; ap = ap->next) { if (!ni_sockaddr_is_specified(&ap->local_addr)) continue; if (!ni_resolve_reverse_timed(&ap->local_addr, &name, NI_UPDATER_REVERSE_TIMEOUT)) break; ni_info("Unable to resolve %s to hostname", ni_sockaddr_print(&ap->local_addr)); if (++count >= NI_UPDATER_REVERSE_MAX_CNT) break; } if (ni_string_empty(name)) { ni_note("Skipping hostname update, none available"); goto done; } ni_string_array_append(&arguments, name); ni_string_free(&name); } break; default: ni_error("cannot install new %s settings - file format not understood", ni_updater_name(updater->kind)); goto done; } if (!ni_system_updater_run(updater->proc_install, &arguments)) { ni_error("failed to install %s settings", ni_updater_name(updater->kind)); goto done; } result = TRUE; switch (updater->kind) { case NI_ADDRCONF_UPDATER_RESOLVER: if (ni_global.other_event) ni_global.other_event(NI_EVENT_RESOLVER_UPDATED); break; case NI_ADDRCONF_UPDATER_HOSTNAME: if (ni_global.other_event) ni_global.other_event(NI_EVENT_HOSTNAME_UPDATED); break; case NI_ADDRCONF_UPDATER_GENERIC: if (ni_global.other_event) ni_global.other_event(NI_EVENT_GENERIC_UPDATED); break; default: break; } done: if (file) free(file); ni_string_array_destroy(&arguments); return result; }
int ni_dhcp4_tester_run(ni_dhcp4_tester_t *opts) { ni_netconfig_t *nc; ni_netdev_t *ifp = NULL; ni_dhcp4_device_t *dev = NULL; ni_dhcp4_request_t *req = NULL; unsigned int link_timeout = 20; int rv; if (opts->timeout && opts->timeout != -1U) { link_timeout = (opts->timeout * 2) / 3; opts->timeout -= link_timeout; } if (!opts || ni_string_empty(opts->ifname)) ni_fatal("Invalid start parameters!"); dhcp4_tester_opts = *opts; dhcp4_tester_status = NI_WICKED_RC_ERROR; if (!(nc = ni_global_state_handle(1))) ni_fatal("Cannot refresh interface list!"); if (!(ifp = ni_netdev_by_name(nc, opts->ifname))) ni_fatal("Cannot find interface with name '%s'", opts->ifname); if (!ni_dhcp4_supported(ifp)) ni_fatal("DHCPv4 not supported on '%s'", opts->ifname); if (!(dev = ni_dhcp4_device_new(ifp->name, &ifp->link))) ni_fatal("Cannot allocate dhcp4 client for '%s'", opts->ifname); ni_dhcp4_set_event_handler(ni_dhcp4_tester_protocol_event); if (!(req = ni_dhcp4_request_new())) { ni_error("Cannot allocate dhcp4 request"); goto failure; } if (!ni_dhcp4_tester_req_init(req, opts->request)) goto failure; if (!ni_netdev_link_is_up(ifp)) { ni_netdev_req_t *ifreq; ni_debug_dhcp("%s: Link is not up, trying to bring it up", ifp->name); ifreq = ni_netdev_req_new(); ifreq->ifflags = NI_IFF_LINK_UP | NI_IFF_NETWORK_UP; if ((rv = ni_system_interface_link_change(ifp, ifreq)) < 0) { ni_error("%s: Unable to set up link", ifp->name); ni_netdev_req_free(ifreq); goto failure; } ni_netdev_req_free(ifreq); do { sleep(1); if (!(nc = ni_global_state_handle(1))) goto failure; if (!(ifp = ni_netdev_by_index(nc, dev->link.ifindex))) break; if (ni_netdev_link_is_up(ifp)) break; ni_debug_dhcp("%s: Link is not (yet) up", ifp->name); } while (link_timeout-- > 1); if (!ifp || !ni_netdev_link_is_up(ifp) || !link_timeout) { ni_error("%s: Unable to bring link up", ifp && ifp->name ? ifp->name : dev->ifname); goto failure; } /* Do not try to send too early, even link is reported up now */ sleep(1); } if (opts->timeout && opts->timeout != -1U) req->acquire_timeout = opts->timeout; req->broadcast = opts->broadcast; if ((rv = ni_dhcp4_acquire(dev, req)) < 0) { ni_error("%s: DHCP4v6 acquire request %s failed: %s", dev->ifname, ni_uuid_print(&req->uuid), ni_strerror(rv)); goto failure; } dhcp4_tester_status = NI_WICKED_RC_IN_PROGRESS; while (!ni_caught_terminal_signal()) { long timeout; timeout = ni_timer_next_timeout(); if (ni_socket_wait(timeout) != 0) break; } ni_server_deactivate_interface_events(); ni_socket_deactivate_all(); failure: if (dev) ni_dhcp4_device_put(dev); if (req) ni_dhcp4_request_free(req); return dhcp4_tester_status; }
static ni_netdev_t * __ni_objectmodel_macvlan_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev_ifp = NULL; const ni_macvlan_t *macvlan; const char *err; const char *cfg_ifp_iftype = NULL; int rv; cfg_ifp_iftype = ni_linktype_type_to_name(cfg_ifp->link.type); if (ni_string_empty(cfg_ifp->link.lowerdev.name)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Incomplete arguments: need a lower device name"); return NULL; } else if (!ni_netdev_ref_bind_ifindex(&cfg_ifp->link.lowerdev, nc)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to find %s lower device %s by name", cfg_ifp_iftype, cfg_ifp->link.lowerdev.name); return NULL; } macvlan = ni_netdev_get_macvlan(cfg_ifp); if ((err = ni_macvlan_validate(macvlan))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err); goto out; } if (ni_string_empty(ifname)) { if (ni_string_empty(cfg_ifp->name) && (ifname = ni_netdev_make_name( nc, cfg_ifp_iftype, 0))) { ni_string_dup(&cfg_ifp->name, ifname); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create %s interface: " "name argument missed", cfg_ifp_iftype); goto out; } ifname = NULL; } else if(!ni_string_eq(cfg_ifp->name, ifname)) { ni_string_dup(&cfg_ifp->name, ifname); } if (ni_string_eq(cfg_ifp->name, cfg_ifp->link.lowerdev.name)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create %s interface: " "macvlan name %s equal with lower device name", cfg_ifp_iftype, cfg_ifp->name); return NULL; } if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create %s interface: " "invalid ethernet address '%s'", cfg_ifp_iftype, ni_link_address_print(&cfg_ifp->link.hwaddr)); return NULL; } } if ((rv = ni_system_macvlan_create(nc, cfg_ifp, &dev_ifp)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL || (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create %s interface: %s", cfg_ifp_iftype, ni_strerror(rv)); dev_ifp = NULL; goto out; } ni_debug_dbus("%s interface exists (and name matches)", cfg_ifp_iftype); } if (dev_ifp->link.type != cfg_ifp->link.type) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create %s interface: " "new interface is of type %s", cfg_ifp_iftype, ni_linktype_type_to_name(dev_ifp->link.type)); dev_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return dev_ifp; }