示例#1
0
static gboolean
complete_connection (NMDevice *device,
                     NMConnection *connection,
                     const char *specific_object,
                     const GSList *existing_connections,
                     GError **error)
{
	NMSettingBond *s_bond, *tmp;
	guint32 i = 0;
	char *name;
	const GSList *iter;
	gboolean found;

	nm_utils_complete_generic (connection,
	                           NM_SETTING_BOND_SETTING_NAME,
	                           existing_connections,
	                           _("Bond connection %d"),
	                           NULL,
	                           TRUE);

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond) {
		s_bond = (NMSettingBond *) nm_setting_bond_new ();
		nm_connection_add_setting (connection, NM_SETTING (s_bond));
	}

	/* Grab the first name that doesn't exist in either our connections
	 * or a device on the system.
	 */
	while (i < 500 && !nm_setting_bond_get_interface_name (s_bond)) {
		name = g_strdup_printf ("bond%u", i);
		/* check interface names */
		if (!nm_platform_link_exists (name)) {
			/* check existing bond connections */
			for (iter = existing_connections, found = FALSE; iter; iter = g_slist_next (iter)) {
				NMConnection *candidate = iter->data;

				tmp = nm_connection_get_setting_bond (candidate);
				if (tmp && nm_connection_is_type (candidate, NM_SETTING_BOND_SETTING_NAME)) {
					if (g_strcmp0 (nm_setting_bond_get_interface_name (tmp), name) == 0) {
						found = TRUE;
						break;
					}
				}
			}

			if (!found)
				g_object_set (G_OBJECT (s_bond), NM_SETTING_BOND_INTERFACE_NAME, name, NULL);
		}

		g_free (name);
		i++;
	}

	return TRUE;
}
void
bond_connection_new (GtkWindow *parent,
                     const char *detail,
                     NMRemoteSettings *settings,
                     PageNewConnectionResultFunc result_func,
                     gpointer user_data)
{
	NMConnection *connection;
	int bond_num, max_bond_num, num;
	GSList *connections, *iter;
	NMConnection *conn2;
	NMSettingBond *s_bond;
	const char *iface;
	char *my_iface;

	connection = ce_page_new_connection (_("Bond connection %d"),
	                                     NM_SETTING_BOND_SETTING_NAME,
	                                     TRUE,
	                                     settings,
	                                     user_data);
	nm_connection_add_setting (connection, nm_setting_bond_new ());

	/* Find an available interface name */
	bond_num = max_bond_num = 0;
	connections = nm_remote_settings_list_connections (settings);
	for (iter = connections; iter; iter = iter->next) {
		conn2 = iter->data;

		if (!nm_connection_is_type (conn2, NM_SETTING_BOND_SETTING_NAME))
			continue;
		s_bond = nm_connection_get_setting_bond (conn2);
		if (!s_bond)
			continue;
		iface = nm_setting_bond_get_interface_name (s_bond);
		if (!iface || strncmp (iface, "bond", 4) != 0 || !g_ascii_isdigit (iface[4]))
			continue;

		num = atoi (iface + 4);
		if (num > max_bond_num)
			max_bond_num = num;
		if (num == bond_num)
			bond_num = max_bond_num + 1;
	}
	g_slist_free (connections);

	my_iface = g_strdup_printf ("bond%d", bond_num);
	s_bond = nm_connection_get_setting_bond (connection);
	g_object_set (G_OBJECT (s_bond),
	              NM_SETTING_BOND_INTERFACE_NAME, my_iface,
	              NULL);
	g_free (my_iface);

	(*result_func) (connection, FALSE, NULL, user_data);
}
示例#3
0
static gboolean
complete_connection (NMDevice *device,
                     NMConnection *connection,
                     const char *specific_object,
                     const GSList *existing_connections,
                     GError **error)
{
	NMSettingBond *s_bond;

	nm_utils_complete_generic (NM_PLATFORM_GET,
	                           connection,
	                           NM_SETTING_BOND_SETTING_NAME,
	                           existing_connections,
	                           NULL,
	                           _("Bond connection"),
	                           "bond",
	                           TRUE);

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond) {
		s_bond = (NMSettingBond *) nm_setting_bond_new ();
		nm_connection_add_setting (connection, NM_SETTING (s_bond));
	}

	return TRUE;
}
示例#4
0
static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMSettingBond *s_bond = nm_connection_get_setting_bond (connection);
	int ifindex = nm_device_get_ifindex (device);
	const char **options;

	if (!s_bond) {
		s_bond = (NMSettingBond *) nm_setting_bond_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_bond);
	}

	/* Read bond options from sysfs and update the Bond setting to match */
	options = nm_setting_bond_get_valid_options (s_bond);
	while (options && *options) {
		gs_free char *value = nm_platform_sysctl_master_get_option (nm_device_get_platform(device), ifindex, *options);
		const char *defvalue = nm_setting_bond_get_option_default (s_bond, *options);

		if (value && !ignore_if_zero (*options, value) && (g_strcmp0 (value, defvalue) != 0)) {
			/* Replace " " with "," for arp_ip_targets from the kernel */
			if (strcmp (*options, "arp_ip_target") == 0) {
				char *p = value;

				while (p && *p) {
					if (*p == ' ')
						*p = ',';
					p++;
				}
			}

			nm_setting_bond_add_option (s_bond, *options, value);
		}
		options++;
	}
}
示例#5
0
static gboolean
check_connection_compatible (NMDevice *device,
                             NMConnection *connection,
                             GError **error)
{
	const char *iface;
	NMSettingBond *s_bond;

	if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->check_connection_compatible (device, connection, error))
		return FALSE;

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) {
		g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND,
		             "The connection was not a bond connection.");
		return FALSE;
	}

	/* Bond connections must specify the virtual interface name */
	iface = nm_connection_get_virtual_iface_name (connection);
	if (!iface || strcmp (nm_device_get_iface (device), iface)) {
		g_set_error (error, NM_BOND_ERROR, NM_BOND_ERROR_CONNECTION_NOT_BOND,
		             "The bond connection virtual interface name did not match.");
		return FALSE;
	}

	/* FIXME: match bond properties like mode, etc? */

	return TRUE;
}
示例#6
0
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
	NMSettingBond *s_bond;

	if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->check_connection_compatible (device, connection))
		return FALSE;

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
		return FALSE;

	/* FIXME: match bond properties like mode, etc? */

	return TRUE;
}
CEPage *
ce_page_bond_new (NMConnectionEditor *editor,
                  NMConnection *connection,
                  GtkWindow *parent_window,
                  NMClient *client,
                  const char **out_secrets_setting_name,
                  GError **error)
{
	CEPageBond *self;
	CEPageBondPrivate *priv;

	self = CE_PAGE_BOND (ce_page_new (CE_TYPE_PAGE_BOND,
	                                  editor,
	                                  connection,
	                                  parent_window,
	                                  client,
	                                  UIDIR "/ce-page-bond.ui",
	                                  "BondPage",
	                                  _("Bond")));
	if (!self) {
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC,
		                     _("Could not load bond user interface."));
		return NULL;
	}

	bond_private_init (self);
	priv = CE_PAGE_BOND_GET_PRIVATE (self);

	priv->setting = nm_connection_get_setting_bond (connection);
	if (!priv->setting) {
		priv->setting = NM_SETTING_BOND (nm_setting_bond_new ());
		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
	}
	priv->wired = nm_connection_get_setting_wired (connection);

	g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);

	return CE_PAGE (self);
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
	const char *iface;
	NMSettingBond *s_bond;

	if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->check_connection_compatible (device, connection))
		return FALSE;

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME))
		return FALSE;

	/* Bond connections must specify the virtual interface name */
	iface = nm_connection_get_interface_name (connection);
	if (!iface || strcmp (nm_device_get_iface (device), iface))
		return FALSE;

	/* FIXME: match bond properties like mode, etc? */

	return TRUE;
}
示例#9
0
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
	NMSettingConnection *s_con;
	NMSettingBond *s_bond;
	const char *ctype, *dev_iface_name, *bond_iface_name;

	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	s_con = nm_connection_get_setting_connection (connection);
	g_assert (s_con);

	ctype = nm_setting_connection_get_connection_type (s_con);
	if (strcmp (ctype, NM_SETTING_BOND_SETTING_NAME) != 0) {
		g_set_error (error, NM_DEVICE_BOND_ERROR, NM_DEVICE_BOND_ERROR_NOT_BOND_CONNECTION,
		             "The connection was not a bond connection.");
		return FALSE;
	}

	s_bond = nm_connection_get_setting_bond (connection);
	if (!s_bond) {
		g_set_error (error, NM_DEVICE_BOND_ERROR, NM_DEVICE_BOND_ERROR_INVALID_BOND_CONNECTION,
		             "The connection was not a valid bond connection.");
		return FALSE;
	}

	dev_iface_name = nm_device_get_iface (device);
	bond_iface_name = nm_setting_bond_get_interface_name (s_bond);
	if (g_strcmp0 (dev_iface_name, bond_iface_name) != 0) {
		g_set_error (error, NM_DEVICE_BOND_ERROR, NM_DEVICE_BOND_ERROR_INTERFACE_MISMATCH,
		             "The interfaces of the device and the connection didn't match.");
		return FALSE;
	}

	/* FIXME: check slaves? But we can't... */

	return TRUE;
}
示例#10
0
static void
nmt_page_bond_constructed (GObject *object)
{
	NmtPageBond *bond = NMT_PAGE_BOND (object);
	NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (bond);
	NmtEditorSection *section;
	NmtEditorGrid *grid;
	NMSettingBond *s_bond;
	NmtNewtWidget *widget, *label;
	NMConnection *conn;

	conn = nmt_editor_page_get_connection (NMT_EDITOR_PAGE (bond));
	s_bond = nm_connection_get_setting_bond (conn);
	if (!s_bond) {
		nm_connection_add_setting (conn, nm_setting_bond_new ());
		s_bond = nm_connection_get_setting_bond (conn);
	}
	priv->s_bond = s_bond;

	section = nmt_editor_section_new (_("BOND"), NULL, TRUE);
	grid = nmt_editor_section_get_body (section);

	widget = nmt_newt_separator_new ();
	nmt_editor_grid_append (grid, _("Slaves"), widget, NULL);
	nmt_editor_grid_set_row_flags (grid, widget, NMT_EDITOR_GRID_ROW_LABEL_ALIGN_LEFT);

	widget = nmt_slave_list_new (conn, bond_connection_type_filter, bond);
	g_signal_connect (widget, "notify::connections",
	                  G_CALLBACK (slaves_changed), bond);
	nmt_editor_grid_append (grid, NULL, widget, NULL);
	priv->slaves = NMT_SLAVE_LIST (widget);

	widget = nmt_newt_popup_new (bond_mode);
	g_signal_connect (widget, "notify::active-id",
	                  G_CALLBACK (mode_widget_changed), bond);
	nmt_editor_grid_append (grid, _("Mode"), widget, NULL);
	priv->mode = NMT_NEWT_POPUP (widget);

	widget = nmt_newt_entry_new (40, 0);
	g_signal_connect (widget, "notify::text",
	                  G_CALLBACK (primary_widget_changed), bond);
	nmt_editor_grid_append (grid, _("Primary"), widget, NULL);
	priv->primary = NMT_NEWT_ENTRY (widget);

	widget = nmt_newt_popup_new (bond_monitoring);
	g_signal_connect (widget, "notify::active",
	                  G_CALLBACK (monitoring_widget_changed), bond);
	nmt_editor_grid_append (grid, _("Link monitoring"), widget, NULL);
	priv->monitoring = NMT_NEWT_POPUP (widget);

	widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
	g_signal_connect (widget, "notify::text",
	                  G_CALLBACK (miimon_widget_changed), bond);
	label = nmt_newt_label_new (C_("milliseconds", "ms"));
	nmt_editor_grid_append (grid, _("Monitoring frequency"), widget, label);
	priv->miimon = NMT_NEWT_ENTRY (widget);

	widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
	g_signal_connect (widget, "notify::text",
	                  G_CALLBACK (updelay_widget_changed), bond);
	label = nmt_newt_label_new (C_("milliseconds", "ms"));
	nmt_editor_grid_append (grid, _("Link up delay"), widget, label);
	priv->updelay = NMT_NEWT_ENTRY (widget);

	widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
	g_signal_connect (widget, "notify::text",
	                  G_CALLBACK (downdelay_widget_changed), bond);
	label = nmt_newt_label_new (C_("milliseconds", "ms"));
	nmt_editor_grid_append (grid, _("Link down delay"), widget, label);
	priv->downdelay = NMT_NEWT_ENTRY (widget);

	widget = nmt_newt_entry_numeric_new (10, 0, G_MAXINT);
	g_signal_connect (widget, "notify::text",
	                  G_CALLBACK (arp_interval_widget_changed), bond);
	label = nmt_newt_label_new (C_("milliseconds", "ms"));
	nmt_editor_grid_append (grid, _("Monitoring frequency"), widget, label);
	priv->arp_interval = NMT_NEWT_ENTRY (widget);

	widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP4);
	g_signal_connect (widget, "notify::strings",
	                  G_CALLBACK (arp_ip_target_widget_changed), bond);
	nmt_editor_grid_append (grid, _("ARP targets"), widget, NULL);
	priv->arp_ip_target = NMT_ADDRESS_LIST (widget);

	g_signal_connect (s_bond, "notify::" NM_SETTING_BOND_OPTIONS,
	                  G_CALLBACK (bond_options_changed), bond);
	bond_options_changed (G_OBJECT (s_bond), NULL, bond);
	slaves_changed (G_OBJECT (priv->slaves), NULL, bond);

	nmt_editor_page_add_section (NMT_EDITOR_PAGE (bond), section);

	G_OBJECT_CLASS (nmt_page_bond_parent_class)->constructed (object);
}
示例#11
0
static NMActStageReturn
apply_bonding_config (NMDevice *device)
{
	NMConnection *connection;
	NMSettingBond *s_bond;
	int ifindex = nm_device_get_ifindex (device);
	const char *mode, *value;
	char *contents;
	gboolean set_arp_interval = TRUE;

	/* Option restrictions:
	 *
	 * arp_interval conflicts miimon > 0
	 * arp_interval conflicts [ alb, tlb ]
	 * arp_validate needs [ active-backup ]
	 * downdelay needs miimon
	 * updelay needs miimon
	 * primary needs [ active-backup, tlb, alb ]
	 *
	 * clearing miimon requires that arp_interval be 0, but clearing
	 *     arp_interval doesn't require miimon to be 0
	 */

	connection = nm_device_get_applied_connection (device);
	g_assert (connection);
	s_bond = nm_connection_get_setting_bond (connection);
	g_assert (s_bond);

	mode = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MODE);
	if (mode == NULL)
		mode = "balance-rr";

	value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_MIIMON);
	if (value && atoi (value)) {
		/* clear arp interval */
		set_bond_attr (device, "arp_interval", "0");
		set_arp_interval = FALSE;

		set_bond_attr (device, "miimon", value);
		set_simple_option (device, "updelay", s_bond, NM_SETTING_BOND_OPTION_UPDELAY);
		set_simple_option (device, "downdelay", s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY);
	} else if (!value) {
		/* If not given, and arp_interval is not given, default to 100 */
		long int val_int;
		char *end;

		value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
		errno = 0;
		val_int = strtol (value ? value : "0", &end, 10);
		if (!value || (val_int == 0 && errno == 0 && *end == '\0'))
			set_bond_attr (device, "miimon", "100");
	}

	/* The stuff after 'mode' requires the given mode or doesn't care */
	set_bond_attr (device, "mode", mode);

	/* arp_interval not compatible with ALB, TLB */
	if (g_strcmp0 (mode, "balance-alb") == 0 || g_strcmp0 (mode, "balance-tlb") == 0)
		set_arp_interval = FALSE;

	if (set_arp_interval) {
		set_simple_option (device, "arp_interval", s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);

		/* Just let miimon get cleared automatically; even setting miimon to
		 * 0 (disabled) clears arp_interval.
		 */
	}

	value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_VALIDATE);
	/* arp_validate > 0 only valid in active-backup mode */
	if (   value
	    && g_strcmp0 (value, "0") != 0
	    && g_strcmp0 (value, "none") != 0
	    && g_strcmp0 (mode, "active-backup") == 0)
		set_bond_attr (device, "arp_validate", value);
	else
		set_bond_attr (device, "arp_validate", "0");

	if (   g_strcmp0 (mode, "active-backup") == 0
	    || g_strcmp0 (mode, "balance-alb") == 0
	    || g_strcmp0 (mode, "balance-tlb") == 0) {
		value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_PRIMARY);
		set_bond_attr (device, "primary", value ? value : "");
	}

	/* Clear ARP targets */
	contents = nm_platform_sysctl_master_get_option (nm_device_get_platform (device), ifindex, "arp_ip_target");
	set_arp_targets (device, contents, " \n", "-");
	g_free (contents);

	/* Add new ARP targets */
	value = nm_setting_bond_get_option_by_name (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
	set_arp_targets (device, value, ",", "+");

	set_simple_option (device, "primary_reselect", s_bond, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT);
	set_simple_option (device, "fail_over_mac", s_bond, NM_SETTING_BOND_OPTION_FAIL_OVER_MAC);
	set_simple_option (device, "use_carrier", s_bond, NM_SETTING_BOND_OPTION_USE_CARRIER);
	set_simple_option (device, "ad_select", s_bond, NM_SETTING_BOND_OPTION_AD_SELECT);
	set_simple_option (device, "xmit_hash_policy", s_bond, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY);
	set_simple_option (device, "resend_igmp", s_bond, NM_SETTING_BOND_OPTION_RESEND_IGMP);

	if (   g_strcmp0 (mode, "4") == 0
	    || g_strcmp0 (mode, "802.3ad") == 0)
		set_simple_option (device, "lacp_rate", s_bond, NM_SETTING_BOND_OPTION_LACP_RATE);

	return NM_ACT_STAGE_RETURN_SUCCESS;
}