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; }
/* * Helper function to obtain bonding config from dbus object */ static ni_bonding_t * __ni_objectmodel_bonding_handle(const ni_dbus_object_t *object, ni_bool_t write_access, DBusError *error) { ni_netdev_t *dev; ni_bonding_t *bond; if (!(dev = ni_objectmodel_unwrap_netif(object, error))) return NULL; if (!write_access) return dev->bonding; if (!(bond = ni_netdev_get_bonding(dev))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Error getting bonding handle for interface"); return NULL; } return bond; }
static ni_bool_t __ni_compat_generate_bonding(xml_node_t *ifnode, const ni_compat_netdev_t *compat) { ni_bonding_t *bond; xml_node_t *child, *slaves, *slave; unsigned int i; int verbose = 0; /* do not supress defaults */ bond = ni_netdev_get_bonding(compat->dev); child = xml_node_create(ifnode, "bond"); xml_node_new_element("mode", child, ni_bonding_mode_type_to_name(bond->mode)); if (bond->monitoring == NI_BOND_MONITOR_ARP) { xml_node_t *arpmon; xml_node_t *targets; arpmon = xml_node_create(child, "arpmon"); xml_node_new_element("interval", arpmon, ni_sprint_uint(bond->arpmon.interval)); xml_node_new_element("validate", arpmon, ni_bonding_arp_validate_type_to_name(bond->arpmon.validate)); targets = xml_node_create(arpmon, "targets"); for (i = 0; i < bond->arpmon.targets.count; ++i) { xml_node_new_element("ipv4-address", targets, bond->arpmon.targets.data[i]); } } else if (bond->monitoring == NI_BOND_MONITOR_MII) { xml_node_t *miimon; miimon = xml_node_create(child, "miimon"); xml_node_new_element("frequency", miimon, ni_sprint_uint(bond->miimon.frequency)); if (verbose || bond->miimon.updelay) { xml_node_new_element("updelay", miimon, ni_sprint_uint(bond->miimon.updelay)); } if (verbose || bond->miimon.downdelay) { xml_node_new_element("downdelay", miimon, ni_sprint_uint(bond->miimon.downdelay)); } xml_node_new_element("carrier", miimon, ni_bonding_mii_carrier_detect_name(bond->miimon.carrier_detect)); } slaves = xml_node_create(child, "slaves"); for (i = 0; i < bond->slave_names.count; ++i) { const char *slave_name = bond->slave_names.data[i]; slave = xml_node_new("slave", slaves); xml_node_new_element("device", slave, slave_name); switch (bond->mode) { case NI_BOND_MODE_ACTIVE_BACKUP: case NI_BOND_MODE_BALANCE_TLB: case NI_BOND_MODE_BALANCE_ALB: if (ni_string_eq(bond->primary_slave, slave_name)) { xml_node_new_element("primary", slave, "true"); } if (ni_string_eq(bond->active_slave, slave_name)) { xml_node_new_element("active", slave, "true"); } default: break; } } switch (bond->mode) { case NI_BOND_MODE_802_3AD: case NI_BOND_MODE_BALANCE_XOR: if (verbose || bond->xmit_hash_policy) { xml_node_new_element("xmit-hash-policy", child, ni_bonding_xmit_hash_policy_to_name(bond->xmit_hash_policy)); } default: break; } if (bond->mode == NI_BOND_MODE_802_3AD) { if (verbose || bond->lacp_rate) { xml_node_new_element("lacp-rate", child, ni_bonding_lacp_rate_name(bond->lacp_rate)); } if (verbose || bond->ad_select) { xml_node_new_element("ad-select", child, ni_bonding_ad_select_name(bond->ad_select)); } if (verbose || bond->min_links > 0) { xml_node_new_element("min-links", child, ni_sprint_uint(bond->min_links)); } } if (bond->mode == NI_BOND_MODE_ACTIVE_BACKUP) { if (verbose || bond->primary_reselect) { xml_node_new_element("primary-reselect", child, ni_bonding_primary_reselect_name(bond->primary_reselect)); } if (verbose || bond->fail_over_mac) { xml_node_new_element("fail-over-mac", child, ni_bonding_fail_over_mac_name(bond->fail_over_mac)); } if (verbose || bond->num_grat_arp != 1) { xml_node_new_element("num-grat-arp", child, ni_sprint_uint(bond->num_grat_arp)); } if (verbose || bond->num_unsol_na != 1) { xml_node_new_element("num-unsol-na", child, ni_sprint_uint(bond->num_unsol_na)); } } switch (bond->mode) { case NI_BOND_MODE_ACTIVE_BACKUP: case NI_BOND_MODE_BALANCE_RR: case NI_BOND_MODE_BALANCE_TLB: case NI_BOND_MODE_BALANCE_ALB: if (verbose || bond->resend_igmp != 1) { xml_node_new_element("resend-igmp", child, ni_sprint_uint(bond->resend_igmp)); } default: break; } if (verbose || bond->all_slaves_active) { xml_node_new_element("all-slaves-active", child, (bond->all_slaves_active ? "true" : "false")); } return TRUE; }