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; }
/* * Discover current IPv6 device settings */ int ni_system_ipv6_devinfo_get(ni_netdev_t *dev, ni_ipv6_devinfo_t *ipv6) { if (ipv6 == NULL) ipv6 = ni_netdev_get_ipv6(dev); if (!ni_ipv6_supported()) { __ni_ipv6_devconf_reset(&ipv6->conf); __ni_ipv6_ra_info_reset(&ipv6->radv); ipv6->conf.enabled = NI_TRISTATE_DISABLE; return 0; } /* * dhcpcd does something very odd when shutting down an interface; * in addition to removing all IPv4 addresses, it also removes any * IPv6 addresses. The kernel seems to take this as "disable IPv6 * on this interface", and subsequently, /proc/sys/ipv6/conf/<ifname> * is gone. * When we bring the interface back up, everything is fine; but until * then we need to ignore this glitch. */ if (ni_sysctl_ipv6_ifconfig_is_present(dev->name)) { int val; if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "disable_ipv6", &val) >= 0) ni_tristate_set(&ipv6->conf.enabled, !val); if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "forwarding", &val) >= 0) ni_tristate_set(&ipv6->conf.forwarding, !!val); if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "autoconf", &val) >= 0) ni_tristate_set(&ipv6->conf.autoconf, !!val); if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "accept_redirects", &val) >= 0) ni_tristate_set(&ipv6->conf.accept_redirects, !!val); if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "use_tempaddr", &val) >= 0) ipv6->conf.privacy = val < -1 ? -1 : (val > 2 ? 2 : val); } else { ni_warn("%s: cannot get ipv6 device attributes", dev->name); /* Reset to defaults */ __ni_ipv6_devconf_reset(&ipv6->conf); __ni_ipv6_ra_info_reset(&ipv6->radv); } return 0; }
int ni_system_ipv6_devinfo_set(ni_netdev_t *dev, const ni_ipv6_devconf_t *conf) { ni_ipv6_devinfo_t *ipv6; if (!conf || !(ipv6 = ni_netdev_get_ipv6(dev))) return -1; if (!ni_ipv6_supported()) { ipv6->conf.enabled = NI_TRISTATE_DISABLE; if (ni_tristate_is_enabled(conf->enabled)) { errno = EAFNOSUPPORT; return -1; } return 0; } if (ni_tristate_is_set(conf->enabled)) { if (__ni_system_ipv6_devinfo_change_int(dev->name, "disable_ipv6", ni_tristate_is_enabled(conf->enabled) ? 0 : 1) < 0) return -1; ni_tristate_set(&ipv6->conf.enabled, conf->enabled); } /* If we're disabling IPv6 on this interface, we're done! */ if (ni_tristate_is_disabled(conf->enabled)) { __ni_ipv6_ra_info_reset(&dev->ipv6->radv); return 0; } if (__ni_system_ipv6_devinfo_change_int(dev->name, "autoconf", conf->autoconf) == 0) ipv6->conf.autoconf = conf->autoconf; if (__ni_system_ipv6_devinfo_change_int(dev->name, "forwarding", conf->forwarding) == 0) ipv6->conf.forwarding = conf->forwarding; if (__ni_system_ipv6_devinfo_change_int(dev->name, "accept_redirects", conf->accept_redirects) == 0) ipv6->conf.accept_redirects = conf->accept_redirects; if (ipv6->conf.privacy != NI_TRISTATE_DEFAULT) { /* kernel is using -1 for loopback, ptp, ... */ if (__ni_system_ipv6_devinfo_change_int(dev->name, "use_tempaddr", conf->privacy) == 0) { ipv6->conf.privacy = conf->privacy; } } return 0; }
ni_tristate_t ni_netdev_guess_link_required(const ni_netdev_t *dev) { ni_tristate_t link_required = NI_TRISTATE_DEFAULT; switch (dev->link.type) { case NI_IFTYPE_OVS_SYSTEM: case NI_IFTYPE_TUN: case NI_IFTYPE_TAP: ni_tristate_set(&link_required, FALSE); break; case NI_IFTYPE_BRIDGE: if (dev->bridge && dev->bridge->stp && !dev->bridge->ports.count) ni_tristate_set(&link_required, FALSE); break; default: break; } return link_required; }
static dbus_bool_t ni_objectmodel_ethtool_set_link_settings(ni_dbus_object_t *object, const ni_dbus_property_t *property, const ni_dbus_variant_t *argument, DBusError *error) { ni_ethtool_link_settings_t *link; const ni_dbus_variant_t *adv; uint32_t uv32; int32_t sv32; if (!(link = ni_objectmodel_ethtool_link_settings_write_handle(object, error))) return FALSE; if (ni_dbus_dict_get_int32(argument, "autoneg", &sv32) && ni_tristate_is_set(sv32)) ni_tristate_set(&link->autoneg, sv32); if (ni_dbus_dict_get_uint32(argument, "speed", &uv32) && uv32 <= INT_MAX) link->speed = uv32; if (ni_dbus_dict_get_uint32(argument, "duplex", &uv32) && uv32 < NI_ETHTOOL_DUPLEX_UNKNOWN) link->duplex = uv32; if (ni_dbus_dict_get_uint32(argument, "port", &uv32) && uv32 <= NI_ETHTOOL_PORT_OTHER) link->port = uv32; if (ni_dbus_dict_get_uint32(argument, "mdix", &uv32)) link->tp_mdix = uv32; if (ni_dbus_dict_get_uint32(argument, "mdio", &uv32)) link->mdio_support = uv32; if (ni_dbus_dict_get_uint32(argument, "phy-address", &uv32)) link->phy_address = uv32; if (ni_dbus_dict_get_uint32(argument, "transceiver", &uv32)) link->transceiver = uv32; if ((adv = ni_dbus_dict_get(argument, "advertise"))) { /* config */ ni_objectmodel_ethtool_link_adv_bitfield_from_array(adv, &link->advertising, ni_ethtool_link_adv_type); } else { /* states */ ni_objectmodel_ethtool_link_adv_from_dict(argument, "supported", &link->supported); ni_objectmodel_ethtool_link_adv_from_dict(argument, "advertising", &link->advertising); ni_objectmodel_ethtool_link_adv_from_dict(argument, "lp-advertising", &link->lp_advertising); } return TRUE; }
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; }