static int set_ethtool_eee(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_eee_t *eee; char *key = NULL, *val = NULL; ni_bool_t enabled; int ret = -1, n; if (!(eee = ni_ethtool_eee_new())) return ret; for (n = 0; n < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; if (n < args->argc) val = args->argv[n]; else break; if (ni_string_eq(key, "eee")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&eee->status.enabled, enabled); } else if (ni_string_eq(key, "tx-lpi")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&eee->tx_lpi.enabled, enabled); } else if (ni_string_eq(key, "tx-timer")) { ni_parse_uint(val, &eee->tx_lpi.timer, 10); } else if (ni_string_eq(key, "advertise")) { if (!set_ethtool_link_advertise(val, &eee->speed.advertising)) break; } else { val = key; key = NULL; break; } key = NULL; val = NULL; } if (key) { if (val) fprintf(stderr, "%s: cannot parse eee '%s' argument '%s'\n", ref->name, key, val); else fprintf(stderr, "%s: missing eee '%s' value argument\n", ref->name, key); } else { if (val) fprintf(stderr, "%s: unknown eee setting name '%s'\n", ref->name, val); else ret = ni_ethtool_set_eee(ref, ethtool, eee); } ni_ethtool_eee_free(eee); return ret; }
static int set_ethtool_pause(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_pause_t *pause; char *key = NULL, *val = NULL; ni_bool_t enabled; int ret = -1, n; if (!(pause = ni_ethtool_pause_new())) return ret; for (n = 0; n < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; if (n < args->argc) val = args->argv[n]; else break; if (ni_string_eq(key, "tx")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&pause->tx, enabled); } else if (ni_string_eq(key, "rx")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&pause->rx, enabled); } else if (ni_string_eq(key, "autoneg")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&pause->autoneg, enabled); } else { val = key; key = NULL; break; } key = NULL; val = NULL; } if (key) { if (val) fprintf(stderr, "%s: cannot parse pause '%s' argument '%s'\n", ref->name, key, val); else fprintf(stderr, "%s: missing pause '%s' value argument\n", ref->name, key); } else { if (val) fprintf(stderr, "%s: unknown pause setting name '%s'\n", ref->name, val); else ret = ni_ethtool_set_pause(ref, ethtool, pause); } ni_ethtool_pause_free(pause); return ret; }
static int set_ethtool_priv_flags(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_priv_flags_t *pflags; ni_bool_t enabled; char *key, *val; int ret = -1, n; if (!(pflags = ni_ethtool_priv_flags_new())) return ret; for (n = 0; n + 1 < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; val = args->argv[n]; if (ni_parse_boolean(val, &enabled) || ni_string_array_append(&pflags->names, key)) goto cleanup; if (enabled) pflags->bitmap |= NI_BIT(pflags->names.count - 1); } ret = ni_ethtool_set_priv_flags(ref, ethtool, pflags); cleanup: ni_ethtool_priv_flags_free(pflags); return ret; }
static int set_ethtool_features(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_features_t *features; char *key = NULL, *val = NULL; ni_bool_t enabled; int ret = -1, n; if (!(features = ni_ethtool_features_new())) return ret; for (n = 0; n < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; if (n < args->argc) val = args->argv[n]; else break; if (ni_parse_boolean(val, &enabled) < 0) break; ni_ethtool_features_set(features, key, enabled ? NI_ETHTOOL_FEATURE_ON : NI_ETHTOOL_FEATURE_OFF); key = NULL; val = NULL; } if (key) { if (val) fprintf(stderr, "%s: cannot parse feature '%s' value argument '%s'\n", ref->name, key, val); else fprintf(stderr, "%s: missing feature '%s' value argument\n", ref->name, key); } else { ret = ni_ethtool_set_features(ref, ethtool, features); } ni_ethtool_features_free(features); return ret; }
unsigned int ni_bridge_waittime_from_xml(const xml_node_t *brnode) { unsigned int waittime = 0; ni_bridge_t bridge; xml_node_t *child; if (xml_node_is_empty(brnode)) return waittime; __ni_bridge_init(&bridge); for (child = brnode->children; child; child = child->next) { if (ni_string_eq(child->name, "stp")) { if (ni_parse_boolean(child->cdata, &bridge.stp)) continue; } else if (ni_string_eq(child->name, "forward-delay")) { if (ni_parse_double(child->cdata, &bridge.forward_delay)) continue; if (bridge.forward_delay > NI_BRIDGE_FORWARD_DELAY_MAX) bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MAX; else if (bridge.forward_delay < NI_BRIDGE_FORWARD_DELAY_MIN) bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MIN; } else if (ni_string_eq(child->name, "max-age")) { if (ni_parse_double(child->cdata, &bridge.max_age)) continue; if (bridge.max_age > NI_BRIDGE_MAX_AGE_MAX) bridge.max_age = NI_BRIDGE_MAX_AGE_MAX; else if (bridge.max_age < NI_BRIDGE_MAX_AGE_MIN) bridge.max_age = NI_BRIDGE_MAX_AGE_MIN; } } waittime = ni_bridge_waittime(&bridge); return waittime; }
static int set_ethtool_coalesce(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_coalesce_t *coalesce; char *key = NULL, *val = NULL; ni_bool_t enabled; int ret = -1, n; if (!(coalesce = ni_ethtool_coalesce_new())) return ret; for (n = 0; n < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; if (n < args->argc) val = args->argv[n]; else break; if (ni_string_eq(key, "adaptive-rx")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&coalesce->adaptive_rx, enabled); } else if (ni_string_eq(key, "adaptive-tx")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&coalesce->adaptive_tx, enabled); } else if (ni_string_eq(key, "rx-usecs")) { ni_parse_uint(val, &coalesce->rx_usecs, 10); } else if (ni_string_eq(key, "rx-frames")) { ni_parse_uint(val, &coalesce->rx_frames, 10); } else if (ni_string_eq(key, "rx-usecs-irq")) { ni_parse_uint(val, &coalesce->rx_usecs_irq, 10); } else if (ni_string_eq(key, "rx-frames-irq")) { ni_parse_uint(val, &coalesce->rx_frames_irq, 10); } else if (ni_string_eq(key, "tx-usecs")) { ni_parse_uint(val, &coalesce->tx_usecs, 10); } else if (ni_string_eq(key, "tx-frames")) { ni_parse_uint(val, &coalesce->tx_frames, 10); } else if (ni_string_eq(key, "tx-usecs-irq")) { ni_parse_uint(val, &coalesce->tx_usecs_irq, 10); } else if (ni_string_eq(key, "tx-frames-irq")) { ni_parse_uint(val, &coalesce->rx_frames_irq, 10); } else if (ni_string_eq(key, "stats-block-usecs")) { ni_parse_uint(val, &coalesce->stats_block_usecs, 10); } else if (ni_string_eq(key, "pkt-rate-low")) { ni_parse_uint(val, &coalesce->pkt_rate_low, 10); } else if (ni_string_eq(key, "rx-usecs-low")) { ni_parse_uint(val, &coalesce->rx_usecs_low, 10); } else if (ni_string_eq(key, "rx-frames-low")) { ni_parse_uint(val, &coalesce->rx_frames_low, 10); } else if (ni_string_eq(key, "tx-usecs-low")) { ni_parse_uint(val, &coalesce->tx_usecs_low, 10); } else if (ni_string_eq(key, "tx-frames-low")) { ni_parse_uint(val, &coalesce->tx_frames_low, 10); } else if (ni_string_eq(key, "pkt-rate-high")) { ni_parse_uint(val, &coalesce->pkt_rate_high, 10); } else if (ni_string_eq(key, "rx-usecs-high")) { ni_parse_uint(val, &coalesce->rx_usecs_high, 10); } else if (ni_string_eq(key, "rx-frames-high")) { ni_parse_uint(val, &coalesce->rx_frames_high, 10); } else if (ni_string_eq(key, "tx-usecs-high")) { ni_parse_uint(val, &coalesce->tx_usecs_high, 10); } else if (ni_string_eq(key, "tx-frames-high")) { ni_parse_uint(val, &coalesce->tx_frames_high, 10); } else if (ni_string_eq(key, "sample_interval")) { ni_parse_uint(val, &coalesce->sample_interval, 10); } else { val = key; key = NULL; break; } key = NULL; val = NULL; } if (key) { if (val) fprintf(stderr, "%s: cannot parse coalesce '%s' argument '%s'\n", ref->name, key, val); else fprintf(stderr, "%s: missing coalesce '%s' value argument\n", ref->name, key); } else { if (val) fprintf(stderr, "%s: unknown coalesce setting name '%s'\n", ref->name, val); else ret = ni_ethtool_set_coalesce(ref, ethtool, coalesce); } ni_ethtool_coalesce_free(coalesce); return ret; }
static int set_ethtool_link_settings(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args) { ni_ethtool_link_settings_t *link; char *key = NULL, *val = NULL; unsigned int value; ni_bool_t enabled; int ret = -1, n; if (!(link = ni_ethtool_link_settings_new())) return ret; for (n = 0; n < args->argc && args->argv[n]; ++n) { key = args->argv[n++]; if (n < args->argc) val = args->argv[n]; else break; if (ni_string_eq(key, "autoneg")) { if (ni_parse_boolean(val, &enabled) != 0) break; ni_tristate_set(&link->autoneg, enabled); } else if (ni_string_eq(key, "speed")) { if (ni_parse_uint(val, &value, 10) != 0) break; link->speed = value; } else if (ni_string_eq(key, "duplex")) { if (!ni_ethtool_link_duplex_type(val, &value)) break; link->duplex = value; } else if (ni_string_eq(key, "port")) { if (!ni_ethtool_link_port_type(val, &value)) break; link->port = value; } else if (ni_string_eq(key, "mdix")) { if (!ni_ethtool_link_mdix_type(val, &value)) break; link->tp_mdix = value; } else if (ni_string_eq(key, "phy-address")) { if (ni_parse_uint(val, &value, 10) != 0) break; link->phy_address = value; } else if (ni_string_eq(key, "transceiver")) { if (!ni_ethtool_link_xcvr_type(val, &value)) break; link->transceiver = value; } else if (ni_string_eq(key, "advertise")) { if (!set_ethtool_link_advertise(val, &link->advertising)) break; } else { val = key; key = NULL; break; } key = NULL; val = NULL; } if (key) { if (val) fprintf(stderr, "%s: cannot parse link '%s' argument '%s'\n", ref->name, key, val); else fprintf(stderr, "%s: missing link '%s' value argument\n", ref->name, key); } else { if (val) fprintf(stderr, "%s: unknown link setting name '%s'\n", ref->name, val); else ret = ni_ethtool_set_link_settings(ref, ethtool, link); } ni_ethtool_link_settings_free(link); return ret; }
static ni_bool_t ni_dhcp4_tester_req_xml_init(ni_dhcp4_request_t *req, xml_document_t *doc) { xml_node_t *xml, *child; const char *type; xml = xml_document_root(doc); if (xml && !xml->name && xml->children) xml = xml->children; if (!xml || !ni_string_eq(xml->name, "request")) { ni_error("Invalid dhcp4 request xml '%s'", xml ? xml_node_location(xml) : NULL); return FALSE; } type = xml_node_get_attr(xml, "type"); if (ni_string_eq(type, "offer")) { req->dry_run = NI_DHCP4_RUN_OFFER; } else if (ni_string_eq(type, "lease")) { req->dry_run = NI_DHCP4_RUN_LEASE; } for (child = xml->children; child; child = child->next) { if (ni_string_eq(child->name, "uuid")) { if (ni_uuid_parse(&req->uuid, child->cdata) != 0) goto failure; } else if (ni_string_eq(child->name, "acquire-timeout")) { if (ni_parse_uint(child->cdata, &req->acquire_timeout, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "hostname")) { if (!ni_check_domain_name(child->cdata, ni_string_len(child->cdata), 0)) goto failure; ni_string_dup(&req->hostname, child->cdata); } else if (ni_string_eq(child->name, "fqdn")) { const xml_node_t *ptr; for (ptr = child->children; ptr; ptr = ptr->next) { if (ni_string_eq(ptr->name, "enabled")) { ni_bool_t b; if (ni_parse_boolean(ptr->cdata, &b) == 0) ni_tristate_set(&req->fqdn.enabled, b); else if (ni_string_eq(ptr->cdata, "default")) req->fqdn.enabled = NI_TRISTATE_DEFAULT; else goto failure; } else if (ni_string_eq(ptr->name, "update")) { if (!ni_dhcp_fqdn_update_name_to_mode(ptr->cdata, &req->fqdn.update)) goto failure; } else if (ni_string_eq(ptr->name, "encode")) { if (ni_parse_boolean(ptr->cdata, &req->fqdn.encode) != 0) goto failure; } else if (ni_string_eq(ptr->name, "qualify")) { if (ni_parse_boolean(ptr->cdata, &req->fqdn.qualify) != 0) goto failure; } } } else if (ni_string_eq(child->name, "clientid")) { ni_opaque_t duid; if (ni_parse_hex(child->cdata, duid.data, sizeof(duid.data)) <= 0) goto failure; ni_string_dup(&req->clientid, child->cdata); } else if(ni_string_eq(child->name, "start-delay")) { if (ni_parse_uint(child->cdata, &req->start_delay, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "lease-time")) { if (ni_parse_uint(child->cdata, &req->lease_time, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "recover-lease")) { if (ni_parse_boolean(child->cdata, &req->recover_lease) != 0) goto failure; } else if (ni_string_eq(child->name, "release-lease")) { if (ni_parse_boolean(child->cdata, &req->release_lease) != 0) goto failure; } else if (ni_string_eq(child->name, "request-options")) { xml_node_t *opt; for (opt = child->children; opt; opt = opt->next) { if (ni_string_empty(opt->cdata)) continue; ni_string_array_append(&req->request_options, opt->cdata); } } } return TRUE; failure: if (child) { ni_error("Cannot parse dhcp4 request '%s': %s", child->name, xml_node_location(child)); } return FALSE; }
static ni_bool_t dhcp4_tester_req_xml_init(ni_dhcp4_request_t *req, xml_document_t *doc) { xml_node_t *xml, *child; const char *type; xml = xml_document_root(doc); if (xml && !xml->name && xml->children) xml = xml->children; if (!xml || !ni_string_eq(xml->name, "request")) { ni_error("Invalid dhcp4 request xml '%s'", xml ? xml_node_location(xml) : NULL); return FALSE; } type = xml_node_get_attr(xml, "type"); if (ni_string_eq(type, "offer")) { req->dry_run = NI_DHCP4_RUN_OFFER; } else if (ni_string_eq(type, "lease")) { req->dry_run = NI_DHCP4_RUN_LEASE; } for (child = xml->children; child; child = child->next) { if (ni_string_eq(child->name, "uuid")) { if (ni_uuid_parse(&req->uuid, child->cdata) != 0) goto failure; } else if (ni_string_eq(child->name, "acquire-timeout")) { if (ni_parse_uint(child->cdata, &req->acquire_timeout, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "hostname")) { if (!ni_check_domain_name(child->cdata, ni_string_len(child->cdata), 0)) goto failure; ni_string_dup(&req->hostname, child->cdata); } else if (ni_string_eq(child->name, "clientid")) { ni_opaque_t duid; if (ni_parse_hex(child->cdata, duid.data, sizeof(duid.data)) <= 0) goto failure; ni_string_dup(&req->clientid, child->cdata); } else if(ni_string_eq(child->name, "start-delay")) { if (ni_parse_uint(child->cdata, &req->start_delay, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "lease-time")) { if (ni_parse_uint(child->cdata, &req->lease_time, 10) != 0) goto failure; } else if (ni_string_eq(child->name, "recover-lease")) { if (ni_parse_boolean(child->cdata, &req->recover_lease) != 0) goto failure; } else if (ni_string_eq(child->name, "release-lease")) { if (ni_parse_boolean(child->cdata, &req->release_lease) != 0) goto failure; } } return TRUE; failure: if (child) { ni_error("Cannot parse dhcp4 request '%s': %s", child->name, xml_node_location(child)); } return FALSE; }
ni_bool_t __ni_config_parse(ni_config_t *conf, const char *filename, ni_init_appdata_callback_t *cb, void *appdata) { xml_document_t *doc; xml_node_t *node, *child; ni_debug_wicked("Reading config file %s", filename); doc = xml_document_read(filename); if (!doc) { ni_error("%s: error parsing configuration file", filename); goto failed; } node = xml_node_get_child(doc->root, "config"); if (!node) { ni_error("%s: no <config> element", filename); goto failed; } /* Loop over all elements in the config file */ for (child = node->children; child; child = child->next) { if (strcmp(child->name, "include") == 0) { const char *attrval, *path; if ((attrval = xml_node_get_attr(child, "name")) == NULL) { ni_error("%s: <include> element lacks filename", xml_node_location(child)); goto failed; } if (!(path = ni_config_build_include(filename, attrval))) goto failed; if (!__ni_config_parse(conf, path, cb, appdata)) goto failed; } else if (strcmp(child->name, "use-nanny") == 0) { if (ni_parse_boolean(child->cdata, &conf->use_nanny)) { ni_error("%s: invalid <%s>%s</%s> element value", filename, child->name, child->name, child->cdata); goto failed; } } else if (strcmp(child->name, "piddir") == 0) { ni_config_parse_fslocation(&conf->piddir, child); } else if (strcmp(child->name, "statedir") == 0) { ni_config_parse_fslocation(&conf->statedir, child); } else if (strcmp(child->name, "storedir") == 0) { ni_config_parse_fslocation(&conf->storedir, child); } else if (strcmp(child->name, "dbus") == 0) { const char *attrval; if ((attrval = xml_node_get_attr(child, "name")) != NULL) ni_string_dup(&conf->dbus_name, attrval); if ((attrval = xml_node_get_attr(child, "type")) != NULL) ni_string_dup(&conf->dbus_type, attrval); } else if (strcmp(child->name, "schema") == 0) { const char *attrval; if ((attrval = xml_node_get_attr(child, "name")) != NULL) ni_string_dup(&conf->dbus_xml_schema_file, attrval); } else if (strcmp(child->name, "addrconf") == 0) { xml_node_t *gchild; for (gchild = child->children; gchild; gchild = gchild->next) { if (!strcmp(gchild->name, "default-allow-update")) ni_config_parse_update_targets(&conf->addrconf.default_allow_update, gchild); if (!strcmp(gchild->name, "dhcp4") && !ni_config_parse_addrconf_dhcp4(&conf->addrconf.dhcp4, gchild)) goto failed; if (!strcmp(gchild->name, "dhcp6") && !ni_config_parse_addrconf_dhcp6(&conf->addrconf.dhcp6, gchild)) goto failed; } } else if (strcmp(child->name, "sources") == 0) { if (!ni_config_parse_sources(conf, child)) goto failed; } else if (strcmp(child->name, "extension") == 0 || strcmp(child->name, "dbus-service") == 0) { if (!ni_config_parse_objectmodel_extension(&conf->dbus_extensions, child)) goto failed; } else if (strcmp(child->name, "netif-naming-services") == 0) { if (!ni_config_parse_objectmodel_netif_ns(&conf->ns_extensions, child)) goto failed; } else if (strcmp(child->name, "netif-firmware-discovery") == 0) { if (!ni_config_parse_objectmodel_firmware_discovery(&conf->fw_extensions, child)) goto failed; } else if (strcmp(child->name, "system-updater") == 0) { if (!ni_config_parse_system_updater(&conf->updater_extensions, child)) goto failed; } else if (cb != NULL) { if (!cb(appdata, child)) goto failed; } } if (conf->backupdir.path == NULL) { char pathname[PATH_MAX]; snprintf(pathname, sizeof(pathname), "%s/backup", conf->statedir.path); ni_config_fslocation_init(&conf->backupdir, pathname, 0700); } xml_document_free(doc); return TRUE; failed: if (doc) xml_document_free(doc); return FALSE; }