/**
 * nm_device_vxlan_get_l3miss:
 * @device: a #NMDeviceVxlan
 *
 * Returns: wether netlink IP ADDR miss notifications are generated
 *
 * Since: 1.2
 **/
gboolean
nm_device_vxlan_get_l3miss (NMDeviceVxlan *device)
{
	g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), FALSE);

	return NM_DEVICE_VXLAN_GET_PRIVATE (device)->l3miss;
}
/**
 * nm_device_vxlan_get_hw_address:
 * @device: a #NMDeviceVxlan
 *
 * Gets the hardware (MAC) address of the #NMDeviceVxlan
 *
 * Returns: the hardware address. This is the internal string used by the
 * device, and must not be modified.
 *
 * Since: 1.2
 **/
const char *
nm_device_vxlan_get_hw_address (NMDeviceVxlan *device)
{
	g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);

	return nm_str_not_empty (NM_DEVICE_VXLAN_GET_PRIVATE (device)->hw_address);
}
static void
init_dbus (NMObject *object)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
	const NMPropertiesInfo property_info[] = {
		{ NM_DEVICE_VXLAN_HW_ADDRESS,   &priv->hw_address },
		{ NM_DEVICE_VXLAN_CARRIER,      &priv->carrier },
		{ NM_DEVICE_VXLAN_PARENT,       &priv->parent, NULL, NM_TYPE_DEVICE },
		{ NM_DEVICE_VXLAN_ID,           &priv->id },
		{ NM_DEVICE_VXLAN_GROUP,        &priv->group },
		{ NM_DEVICE_VXLAN_LOCAL,        &priv->local },
		{ NM_DEVICE_VXLAN_SRC_PORT_MIN, &priv->src_port_min },
		{ NM_DEVICE_VXLAN_SRC_PORT_MAX, &priv->src_port_max },
		{ NM_DEVICE_VXLAN_DST_PORT,     &priv->dst_port },
		{ NM_DEVICE_VXLAN_TOS,          &priv->tos },
		{ NM_DEVICE_VXLAN_TTL,          &priv->ttl },
		{ NM_DEVICE_VXLAN_LIMIT,        &priv->limit },
		{ NM_DEVICE_VXLAN_LEARNING,     &priv->learning },
		{ NM_DEVICE_VXLAN_AGEING,       &priv->ageing },
		{ NM_DEVICE_VXLAN_PROXY,        &priv->proxy },
		{ NM_DEVICE_VXLAN_RSC,          &priv->rsc },
		{ NM_DEVICE_VXLAN_L2MISS,       &priv->l2miss },
		{ NM_DEVICE_VXLAN_L3MISS,       &priv->l3miss },
		{ NULL },
	};

	NM_OBJECT_CLASS (nm_device_vxlan_parent_class)->init_dbus (object);

	_nm_object_register_properties (object,
	                                NM_DBUS_INTERFACE_DEVICE_VXLAN,
	                                property_info);
}
/**
 * nm_device_vxlan_get_src_port_max:
 * @device: a #NMDeviceVxlan
 *
 * Returns:  the maximum UDP source port
 *
 * Since: 1.2
 **/
guint
nm_device_vxlan_get_src_port_max (NMDeviceVxlan *device)
{
	g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);

	return NM_DEVICE_VXLAN_GET_PRIVATE (device)->src_port_max;
}
/**
 * nm_device_vxlan_get_limit:
 * @device: a #NMDeviceVxlan
 *
 * Returns: the maximum number of entries that can be added to the
 * forwarding table
 *
 * Since: 1.2
 **/
guint
nm_device_vxlan_get_limit (NMDeviceVxlan *device)
{
	g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), 0);

	return NM_DEVICE_VXLAN_GET_PRIVATE (device)->limit;
}
예제 #6
0
static gboolean
match_parent (NMDeviceVxlan *self, const char *parent)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self);

	g_return_val_if_fail (parent != NULL, FALSE);

	if (!priv->parent)
		return FALSE;

	if (nm_utils_is_uuid (parent)) {
		NMActRequest *parent_req;
		NMConnection *parent_connection;

		/* If the parent is a UUID, the connection matches if our parent
		 * device has that connection activated.
		 */
		parent_req = nm_device_get_act_request (priv->parent);
		if (!parent_req)
			return FALSE;

		parent_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (parent_req));
		if (!parent_connection)
			return FALSE;

		if (g_strcmp0 (parent, nm_connection_get_uuid (parent_connection)) != 0)
			return FALSE;
	} else {
		/* interface name */
		if (g_strcmp0 (parent, nm_device_get_ip_iface (priv->parent)) != 0)
			return FALSE;
	}

	return TRUE;
}
/**
 * nm_device_vxlan_get_parent:
 * @device: a #NMDeviceVxlan
 *
 * Returns: (transfer none): the device's parent device
 *
 * Since: 1.2
 **/
NMDevice *
nm_device_vxlan_get_parent (NMDeviceVxlan *device)
{
	g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);

	return NM_DEVICE_VXLAN_GET_PRIVATE (device)->parent;
}
예제 #8
0
static void
dispose (GObject *object)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);

	g_clear_object (&priv->parent);
	G_OBJECT_CLASS (nm_device_vxlan_parent_class)->dispose (object);
}
예제 #9
0
static void
update_properties (NMDevice *device)
{
	NMDeviceVxlan *self = NM_DEVICE_VXLAN (device);
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
	GObject *object = G_OBJECT (device);
	NMPlatformVxlanProperties props;

	if (!nm_platform_vxlan_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) {
		_LOGW (LOGD_HW, "could not read vxlan properties");
		return;
	}

	g_object_freeze_notify (object);

	if (priv->props.parent_ifindex != props.parent_ifindex)
		g_object_notify (object, NM_DEVICE_VXLAN_PARENT);
	if (priv->props.id != props.id)
		g_object_notify (object, NM_DEVICE_VXLAN_ID);
	if (priv->props.group != props.group)
		g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
	if (priv->props.local != props.local)
		g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
	if (memcmp (&priv->props.group6, &props.group6, sizeof (props.group6)) != 0)
		g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
	if (memcmp (&priv->props.local6, &props.local6, sizeof (props.local6)) != 0)
		g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
	if (priv->props.tos != props.tos)
		g_object_notify (object, NM_DEVICE_VXLAN_TOS);
	if (priv->props.ttl != props.ttl)
		g_object_notify (object, NM_DEVICE_VXLAN_TTL);
	if (priv->props.learning != props.learning)
		g_object_notify (object, NM_DEVICE_VXLAN_LEARNING);
	if (priv->props.ageing != props.ageing)
		g_object_notify (object, NM_DEVICE_VXLAN_AGEING);
	if (priv->props.limit != props.limit)
		g_object_notify (object, NM_DEVICE_VXLAN_LIMIT);
	if (priv->props.dst_port != props.dst_port)
		g_object_notify (object, NM_DEVICE_VXLAN_DST_PORT);
	if (priv->props.src_port_min != props.src_port_min)
		g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MIN);
	if (priv->props.src_port_max != props.src_port_max)
		g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MAX);
	if (priv->props.proxy != props.proxy)
		g_object_notify (object, NM_DEVICE_VXLAN_PROXY);
	if (priv->props.rsc != props.rsc)
		g_object_notify (object, NM_DEVICE_VXLAN_RSC);
	if (priv->props.l2miss != props.l2miss)
		g_object_notify (object, NM_DEVICE_VXLAN_L2MISS);
	if (priv->props.l3miss != props.l3miss)
		g_object_notify (object, NM_DEVICE_VXLAN_L3MISS);

	memcpy (&priv->props, &props, sizeof (NMPlatformVxlanProperties));

	g_object_thaw_notify (object);
}
static void
finalize (GObject *object)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);

	g_free (priv->hw_address);
	g_clear_object (&priv->parent);
	g_free (priv->group);
	g_free (priv->local);

	G_OBJECT_CLASS (nm_device_vxlan_parent_class)->finalize (object);
}
예제 #11
0
static void
unrealize_notify (NMDevice *device)
{
	NMDeviceVxlan *self = NM_DEVICE_VXLAN (device);
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (self);
	GParamSpec **properties;
	guint n_properties, i;

	NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->unrealize_notify (device);

	memset (&priv->props, 0, sizeof (NMPlatformLnkVxlan));

	properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_properties);
	for (i = 0; i < n_properties; i++)
		g_object_notify_by_pspec (G_OBJECT (self), properties[i]);
	g_free (properties);
}
예제 #12
0
static void
get_property (GObject *object, guint prop_id,
              GValue *value, GParamSpec *pspec)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
	NMDevice *parent;

	switch (prop_id) {
	case PROP_PARENT:
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex);
		nm_utils_g_value_set_object_path (value, parent);
		break;
	case PROP_ID:
		g_value_set_uint (value, priv->props.id);
		break;
	case PROP_GROUP:
		if (priv->props.group)
			g_value_set_string (value, nm_utils_inet4_ntop (priv->props.group, NULL));
		else if (!IN6_IS_ADDR_UNSPECIFIED (&priv->props.group6))
			g_value_set_string (value, nm_utils_inet6_ntop (&priv->props.group6, NULL));
		break;
	case PROP_LOCAL:
		if (priv->props.local)
			g_value_set_string (value, nm_utils_inet4_ntop (priv->props.local, NULL));
		else if (!IN6_IS_ADDR_UNSPECIFIED (&priv->props.local6))
			g_value_set_string (value, nm_utils_inet6_ntop (&priv->props.local6, NULL));
		break;
	case PROP_TOS:
		g_value_set_uchar (value, priv->props.tos);
		break;
	case PROP_TTL:
		g_value_set_uchar (value, priv->props.ttl);
		break;
	case PROP_LEARNING:
		g_value_set_boolean (value, priv->props.learning);
		break;
	case PROP_AGEING:
		g_value_set_uint (value, priv->props.ageing);
		break;
	case PROP_LIMIT:
		g_value_set_uint (value, priv->props.limit);
		break;
	case PROP_DST_PORT:
		g_value_set_uint (value, priv->props.dst_port);
		break;
	case PROP_SRC_PORT_MIN:
		g_value_set_uint (value, priv->props.src_port_min);
		break;
	case PROP_SRC_PORT_MAX:
		g_value_set_uint (value, priv->props.src_port_max);
		break;
	case PROP_PROXY:
		g_value_set_boolean (value, priv->props.proxy);
		break;
	case PROP_RSC:
		g_value_set_boolean (value, priv->props.rsc);
		break;
	case PROP_L2MISS:
		g_value_set_boolean (value, priv->props.l2miss);
		break;
	case PROP_L3MISS:
		g_value_set_boolean (value, priv->props.l3miss);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
예제 #13
0
static void
update_properties (NMDevice *device)
{
	NMDeviceVxlan *self = NM_DEVICE_VXLAN (device);
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
	GObject *object = G_OBJECT (device);
	const NMPlatformLnkVxlan *props;
	NMDevice *parent;

	props = nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), NULL);
	if (!props) {
		_LOGW (LOGD_HW, "could not get vxlan properties");
		return;
	}

	g_object_freeze_notify (object);

	if (priv->props.parent_ifindex != props->parent_ifindex) {
		g_clear_object (&priv->parent);
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), props->parent_ifindex);
		if (parent)
			priv->parent = g_object_ref (parent);
		g_object_notify (object, NM_DEVICE_VXLAN_PARENT);
	}
	if (priv->props.id != props->id)
		g_object_notify (object, NM_DEVICE_VXLAN_ID);
	if (priv->props.local != props->local)
		g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
	if (memcmp (&priv->props.local6, &props->local6, sizeof (props->local6)) != 0)
		g_object_notify (object, NM_DEVICE_VXLAN_LOCAL);
	if (priv->props.group != props->group)
		g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
	if (memcmp (&priv->props.group6, &props->group6, sizeof (props->group6)) != 0)
		g_object_notify (object, NM_DEVICE_VXLAN_GROUP);
	if (priv->props.tos != props->tos)
		g_object_notify (object, NM_DEVICE_VXLAN_TOS);
	if (priv->props.ttl != props->ttl)
		g_object_notify (object, NM_DEVICE_VXLAN_TTL);
	if (priv->props.learning != props->learning)
		g_object_notify (object, NM_DEVICE_VXLAN_LEARNING);
	if (priv->props.ageing != props->ageing)
		g_object_notify (object, NM_DEVICE_VXLAN_AGEING);
	if (priv->props.limit != props->limit)
		g_object_notify (object, NM_DEVICE_VXLAN_LIMIT);
	if (priv->props.src_port_min != props->src_port_min)
		g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MIN);
	if (priv->props.src_port_max != props->src_port_max)
		g_object_notify (object, NM_DEVICE_VXLAN_SRC_PORT_MAX);
	if (priv->props.dst_port != props->dst_port)
		g_object_notify (object, NM_DEVICE_VXLAN_DST_PORT);
	if (priv->props.proxy != props->proxy)
		g_object_notify (object, NM_DEVICE_VXLAN_PROXY);
	if (priv->props.rsc != props->rsc)
		g_object_notify (object, NM_DEVICE_VXLAN_RSC);
	if (priv->props.l2miss != props->l2miss)
		g_object_notify (object, NM_DEVICE_VXLAN_L2MISS);
	if (priv->props.l3miss != props->l3miss)
		g_object_notify (object, NM_DEVICE_VXLAN_L3MISS);

	priv->props = *props;

	g_object_thaw_notify (object);
}
예제 #14
0
static void
update_connection (NMDevice *device, NMConnection *connection)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
	NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection);
	NMDevice *parent = NULL;
	const char *setting_parent, *new_parent;

	if (!s_vxlan) {
		s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new ();
		nm_connection_add_setting (connection, (NMSetting *) s_vxlan);
	}

	if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL);

	if (priv->props.parent_ifindex != NM_PLATFORM_LINK_OTHER_NETNS)
		parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex);

	/* Update parent in the connection; default to parent's interface name */
	if (parent) {
		new_parent = nm_device_get_iface (parent);
		setting_parent = nm_setting_vxlan_get_parent (s_vxlan);
		if (setting_parent && nm_utils_is_uuid (setting_parent)) {
			NMConnection *parent_connection;

			/* Don't change a parent specified by UUID if it's still valid */
			parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device),
			                                                                         setting_parent);
			if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection))
				new_parent = NULL;
		}
		if (new_parent)
			g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, new_parent, NULL);
	} else
		g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, NULL, NULL);

	if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) {
		if (priv->props.group) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
			              nm_utils_inet4_ntop (priv->props.group, NULL),
			              NULL);
		} else {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_REMOTE,
			              nm_utils_inet6_ntop (&priv->props.group6, NULL),
			              NULL);
		}
	}

	if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) {
		if (priv->props.local) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
			              nm_utils_inet4_ntop (priv->props.local, NULL),
			              NULL);
		} else if (memcmp (&priv->props.local6, &in6addr_any, sizeof (in6addr_any))) {
			g_object_set (s_vxlan, NM_SETTING_VXLAN_LOCAL,
			              nm_utils_inet6_ntop (&priv->props.local6, NULL),
			              NULL);
		}
	}

	if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MIN,
		              priv->props.src_port_min, NULL);
	}

	if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_SOURCE_PORT_MAX,
		              priv->props.src_port_max, NULL);
	}

	if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_DESTINATION_PORT,
		              priv->props.dst_port, NULL);
	}

	if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TOS,
		              priv->props.tos, NULL);
	}

	if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_TTL,
		              priv->props.ttl, NULL);
	}

	if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_LEARNING,
		              priv->props.learning, NULL);
	}

	if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_AGEING,
		              priv->props.ageing, NULL);
	}

	if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_PROXY,
		              priv->props.proxy, NULL);
	}

	if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_RSC,
		              priv->props.rsc, NULL);
	}

	if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L2_MISS,
		              priv->props.l2miss, NULL);
	}

	if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) {
		g_object_set (G_OBJECT (s_vxlan), NM_SETTING_VXLAN_L3_MISS,
		              priv->props.l3miss, NULL);
	}
}
예제 #15
0
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
	NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (device);
	NMSettingVxlan *s_vxlan;
	const char *parent;

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

	s_vxlan = nm_connection_get_setting_vxlan (connection);
	if (!s_vxlan)
		return FALSE;

	if (nm_device_is_real (device)) {
		parent = nm_setting_vxlan_get_parent (s_vxlan);
		if (   parent
		    && !match_parent (NM_DEVICE_VXLAN (device), parent))
			return FALSE;

		if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan))
			return FALSE;

		if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6))
			return FALSE;

		if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6))
			return FALSE;

		if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan))
			return FALSE;

		if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan))
			return FALSE;

		if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan))
			return FALSE;

		if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan))
			return FALSE;

		if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan))
			return FALSE;

		if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan))
			return FALSE;

		if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan))
			return FALSE;

		if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan))
			return FALSE;

		if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan))
			return FALSE;

		if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan))
			return FALSE;

		if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan))
			return FALSE;
	}

	return TRUE;
}