mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-04 01:40:16 +01:00
libnm: add ovs-port.trunks property
Add a new "ovs-port.trunks" property that indicates which VLANs are trunked by the port. At ovsdb level the property is just an array of integers; on the command line, ovs-vsctl accepts ranges and expands them. In NetworkManager the ovs-port setting stores the trunks directly as a list of ranges.
This commit is contained in:
parent
041e38b151
commit
b64e690db8
12 changed files with 614 additions and 15 deletions
|
|
@ -1898,5 +1898,11 @@ global:
|
|||
nm_setting_loopback_get_type;
|
||||
nm_setting_loopback_new;
|
||||
nm_setting_ovs_interface_get_ofport_request;
|
||||
nm_setting_ovs_port_add_trunk;
|
||||
nm_setting_ovs_port_clear_trunks;
|
||||
nm_setting_ovs_port_get_num_trunks;
|
||||
nm_setting_ovs_port_get_trunk;
|
||||
nm_setting_ovs_port_remove_trunk;
|
||||
nm_setting_ovs_port_remove_trunk_by_value;
|
||||
nm_utils_ensure_gtypes;
|
||||
} libnm_1_40_0;
|
||||
|
|
|
|||
|
|
@ -1898,6 +1898,10 @@
|
|||
dbus-type="u"
|
||||
gprop-type="guint"
|
||||
/>
|
||||
<property name="trunks"
|
||||
dbus-type="aa{sv}"
|
||||
gprop-type="GPtrArray"
|
||||
/>
|
||||
<property name="vlan-mode"
|
||||
dbus-type="s"
|
||||
gprop-type="gchararray"
|
||||
|
|
|
|||
|
|
@ -1597,6 +1597,18 @@ _normalize_bridge_port_vlan_order(NMConnection *self)
|
|||
return _nm_setting_bridge_port_sort_vlans(s_port);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_ovs_port_trunks(NMConnection *self)
|
||||
{
|
||||
NMSettingOvsPort *s_ovs_port;
|
||||
|
||||
s_ovs_port = nm_connection_get_setting_ovs_port(self);
|
||||
if (!s_ovs_port)
|
||||
return FALSE;
|
||||
|
||||
return _nm_setting_ovs_port_sort_trunks(s_ovs_port);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_gsm_auto_config(NMConnection *self)
|
||||
{
|
||||
|
|
@ -1989,6 +2001,7 @@ _connection_normalize(NMConnection *connection,
|
|||
was_modified |= _normalize_bridge_port_vlan_order(connection);
|
||||
was_modified |= _normalize_gsm_auto_config(connection);
|
||||
was_modified |= _normalize_802_1x_empty_strings(connection);
|
||||
was_modified |= _normalize_ovs_port_trunks(connection);
|
||||
|
||||
was_modified = !!was_modified;
|
||||
|
||||
|
|
|
|||
|
|
@ -2007,6 +2007,44 @@ bridge_vlan_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
|||
g_object_set(setting, key, vlans, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
range_list_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *ranges = NULL;
|
||||
gs_free char *value = NULL;
|
||||
gs_free const char **strv = NULL;
|
||||
const char *const *iter;
|
||||
GError *local = NULL;
|
||||
NMRange *range;
|
||||
|
||||
value = nm_keyfile_plugin_kf_get_string(info->keyfile, nm_setting_get_name(setting), key, NULL);
|
||||
if (!value || !value[0])
|
||||
return;
|
||||
|
||||
ranges = g_ptr_array_new_with_free_func((GDestroyNotify) nm_range_unref);
|
||||
|
||||
strv = nm_utils_escaped_tokens_split(value, ",");
|
||||
if (strv) {
|
||||
for (iter = strv; *iter; iter++) {
|
||||
range = nm_range_from_str(*iter, &local);
|
||||
if (!range) {
|
||||
read_handle_warn(info,
|
||||
key,
|
||||
key,
|
||||
NM_KEYFILE_WARN_SEVERITY_WARN,
|
||||
"invalid range: %s",
|
||||
local->message);
|
||||
g_clear_error(&local);
|
||||
continue;
|
||||
}
|
||||
g_ptr_array_add(ranges, range);
|
||||
}
|
||||
}
|
||||
|
||||
if (ranges->len > 0)
|
||||
g_object_set(setting, key, ranges, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
qdisc_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||
{
|
||||
|
|
@ -2344,6 +2382,33 @@ bridge_vlan_writer(KeyfileWriterInfo *info,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
range_list_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const GValue *value)
|
||||
{
|
||||
GPtrArray *ranges;
|
||||
|
||||
ranges = g_value_get_boxed(value);
|
||||
if (ranges && ranges->len > 0) {
|
||||
const guint string_initial_size = ranges->len * 10u;
|
||||
nm_auto_str_buf NMStrBuf string = NM_STR_BUF_INIT(string_initial_size, FALSE);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < ranges->len; i++) {
|
||||
gs_free char *range_str = NULL;
|
||||
|
||||
range_str = nm_range_to_str(ranges->pdata[i]);
|
||||
if (i > 0)
|
||||
nm_str_buf_append_c(&string, ',');
|
||||
nm_utils_escaped_tokens_escape_strbuf_assert(range_str, ",", &string);
|
||||
}
|
||||
|
||||
nm_keyfile_plugin_kf_set_string(info->keyfile,
|
||||
nm_setting_get_name(setting),
|
||||
key,
|
||||
nm_str_buf_get_str(&string));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wired_s390_options_parser_full(KeyfileReaderInfo *info,
|
||||
const NMMetaSettingInfo *setting_info,
|
||||
|
|
@ -2933,6 +2998,12 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
|
|||
.parser_no_check_key = TRUE,
|
||||
.parser = bridge_vlan_parser,
|
||||
.writer = bridge_vlan_writer, ), ), ),
|
||||
PARSE_INFO_SETTING(
|
||||
NM_META_SETTING_TYPE_OVS_PORT,
|
||||
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_OVS_PORT_TRUNKS,
|
||||
.parser_no_check_key = TRUE,
|
||||
.parser = range_list_parser,
|
||||
.writer = range_list_writer, ), ), ),
|
||||
PARSE_INFO_SETTING(
|
||||
NM_META_SETTING_TYPE_BRIDGE_PORT,
|
||||
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_BRIDGE_PORT_VLANS,
|
||||
|
|
|
|||
|
|
@ -21,12 +21,14 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_VLAN_MODE,
|
||||
PROP_TAG,
|
||||
PROP_LACP,
|
||||
PROP_BOND_MODE,
|
||||
PROP_BOND_UPDELAY,
|
||||
PROP_BOND_DOWNDELAY, );
|
||||
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingOvsPort,
|
||||
PROP_VLAN_MODE,
|
||||
PROP_TAG,
|
||||
PROP_TRUNKS,
|
||||
PROP_LACP,
|
||||
PROP_BOND_MODE,
|
||||
PROP_BOND_UPDELAY,
|
||||
PROP_BOND_DOWNDELAY, );
|
||||
|
||||
/**
|
||||
* NMSettingOvsPort:
|
||||
|
|
@ -36,12 +38,13 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_VLAN_MODE,
|
|||
struct _NMSettingOvsPort {
|
||||
NMSetting parent;
|
||||
|
||||
char *vlan_mode;
|
||||
char *lacp;
|
||||
char *bond_mode;
|
||||
guint32 tag;
|
||||
guint32 bond_updelay;
|
||||
guint32 bond_downdelay;
|
||||
GPtrArray *trunks;
|
||||
char *vlan_mode;
|
||||
char *lacp;
|
||||
char *bond_mode;
|
||||
guint32 tag;
|
||||
guint32 bond_updelay;
|
||||
guint32 bond_downdelay;
|
||||
};
|
||||
|
||||
struct _NMSettingOvsPortClass {
|
||||
|
|
@ -84,6 +87,143 @@ nm_setting_ovs_port_get_tag(NMSettingOvsPort *self)
|
|||
return self->tag;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_add_trunk:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
* @trunk: the trunk to add
|
||||
*
|
||||
* Appends a new trunk range to the setting.
|
||||
* This takes a reference to @trunk.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
void
|
||||
nm_setting_ovs_port_add_trunk(NMSettingOvsPort *self, NMRange *trunk)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_OVS_PORT(self));
|
||||
g_return_if_fail(trunk);
|
||||
|
||||
g_ptr_array_add(self->trunks, nm_range_ref(trunk));
|
||||
_notify(self, PROP_TRUNKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_get_num_trunks:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
*
|
||||
* Returns: the number of trunk ranges
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
guint
|
||||
nm_setting_ovs_port_get_num_trunks(NMSettingOvsPort *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), 0);
|
||||
|
||||
return self->trunks->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_get_trunk:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
* @idx: index number of the trunk range to return
|
||||
*
|
||||
* Returns: (transfer none): the trunk range at index @idx
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
NMRange *
|
||||
nm_setting_ovs_port_get_trunk(NMSettingOvsPort *self, guint idx)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), NULL);
|
||||
|
||||
g_return_val_if_fail(idx < self->trunks->len, NULL);
|
||||
|
||||
return self->trunks->pdata[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_remove_trunk:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
* @idx: index number of the trunk range.
|
||||
*
|
||||
* Removes the trunk range at index @idx.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
void
|
||||
nm_setting_ovs_port_remove_trunk(NMSettingOvsPort *self, guint idx)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_OVS_PORT(self));
|
||||
|
||||
g_return_if_fail(idx < self->trunks->len);
|
||||
|
||||
g_ptr_array_remove_index(self->trunks, idx);
|
||||
_notify(self, PROP_TRUNKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_remove_trunk_by_value:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
* @start: the trunk range start index
|
||||
* @end: the trunk range end index
|
||||
*
|
||||
* Remove the trunk range with range @start to @end.
|
||||
*
|
||||
* Returns: %TRUE if the trunk range was found and removed; %FALSE otherwise
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_ovs_port_remove_trunk_by_value(NMSettingOvsPort *self, guint start, guint end)
|
||||
{
|
||||
NMRange *trunk;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), FALSE);
|
||||
|
||||
for (i = 0; i < self->trunks->len; i++) {
|
||||
trunk = (NMRange *) self->trunks->pdata[i];
|
||||
if (trunk->start == start && trunk->end == end) {
|
||||
g_ptr_array_remove_index(self->trunks, i);
|
||||
_notify(self, PROP_TRUNKS);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_clear_trunks:
|
||||
* @setting: the #NMSettingOvsPort
|
||||
*
|
||||
* Removes all configured trunk ranges.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
void
|
||||
nm_setting_ovs_port_clear_trunks(NMSettingOvsPort *self)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING_OVS_PORT(self));
|
||||
|
||||
if (self->trunks->len != 0) {
|
||||
g_ptr_array_set_size(self->trunks, 0);
|
||||
_notify(self, PROP_TRUNKS);
|
||||
}
|
||||
}
|
||||
|
||||
const GPtrArray *
|
||||
_nm_setting_ovs_port_get_trunks_arr(NMSettingOvsPort *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_OVS_PORT(self), NULL);
|
||||
|
||||
return self->trunks;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_get_lacp:
|
||||
* @self: the #NMSettingOvsPort
|
||||
|
|
@ -150,6 +290,107 @@ nm_setting_ovs_port_get_bond_downdelay(NMSettingOvsPort *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
range_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const NMRange *range_a = *(const NMRange **) a;
|
||||
const NMRange *range_b = *(const NMRange **) b;
|
||||
|
||||
return nm_range_cmp(range_a, range_b);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_ovs_port_sort_trunks(NMSettingOvsPort *self)
|
||||
{
|
||||
gboolean need_sort = FALSE;
|
||||
guint i;
|
||||
|
||||
for (i = 1; i < self->trunks->len; i++) {
|
||||
NMRange *range_prev = self->trunks->pdata[i - 1];
|
||||
NMRange *range = self->trunks->pdata[i];
|
||||
|
||||
if (nm_range_cmp(range_prev, range) > 0) {
|
||||
need_sort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_sort) {
|
||||
g_ptr_array_sort(self->trunks, range_cmp);
|
||||
_notify(self, PROP_TRUNKS);
|
||||
}
|
||||
|
||||
return need_sort;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify_trunks(GPtrArray *ranges, GError **error)
|
||||
{
|
||||
gs_unref_hashtable GHashTable *h = NULL;
|
||||
NMRange *range;
|
||||
guint i;
|
||||
guint vlan;
|
||||
|
||||
if (!ranges)
|
||||
return TRUE;
|
||||
|
||||
h = g_hash_table_new(nm_direct_hash, NULL);
|
||||
|
||||
for (i = 0; i < ranges->len; i++) {
|
||||
range = ranges->pdata[i];
|
||||
nm_assert(range->start <= range->end);
|
||||
|
||||
if (range->start > 4095 || range->end > 4095) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("VLANs must be between 0 and 4095"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (vlan = range->start; vlan <= range->end; vlan++) {
|
||||
if (!nm_g_hash_table_add(h, GUINT_TO_POINTER(vlan))) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("duplicate VLAN %u"),
|
||||
vlan);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
verify_trunks_normalizable(GPtrArray *ranges, GError **error)
|
||||
{
|
||||
guint i;
|
||||
|
||||
nm_assert(verify_trunks(ranges, NULL));
|
||||
|
||||
if (!ranges || ranges->len <= 1)
|
||||
return TRUE;
|
||||
|
||||
for (i = 1; i < ranges->len; i++) {
|
||||
NMRange *range_prev = ranges->pdata[i - 1];
|
||||
NMRange *range = ranges->pdata[i];
|
||||
|
||||
if (nm_range_cmp(range_prev, range) > 0) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("VLANs %u and %u are not sorted in ascending order"),
|
||||
(guint) range_prev->start,
|
||||
(guint) range->start);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
|
|
@ -257,14 +498,68 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!verify_trunks(self->trunks, error)) {
|
||||
g_prefix_error(error,
|
||||
"%s.%s: ",
|
||||
NM_SETTING_OVS_PORT_SETTING_NAME,
|
||||
NM_SETTING_OVS_PORT_TRUNKS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!verify_trunks_normalizable(self->trunks, error)) {
|
||||
g_prefix_error(error,
|
||||
"%s.%s: ",
|
||||
NM_SETTING_OVS_PORT_SETTING_NAME,
|
||||
NM_SETTING_OVS_PORT_TRUNKS);
|
||||
return NM_SETTING_VERIFY_NORMALIZABLE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TRUNKS:
|
||||
g_value_take_boxed(value,
|
||||
_nm_utils_copy_array(self->trunks,
|
||||
(NMUtilsCopyFunc) nm_range_ref,
|
||||
(GDestroyNotify) nm_range_unref));
|
||||
break;
|
||||
default:
|
||||
_nm_setting_property_get_property_direct(object, prop_id, value, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TRUNKS:
|
||||
g_ptr_array_unref(self->trunks);
|
||||
self->trunks = _nm_utils_copy_array(g_value_get_boxed(value),
|
||||
(NMUtilsCopyFunc) nm_range_ref,
|
||||
(GDestroyNotify) nm_range_unref);
|
||||
break;
|
||||
default:
|
||||
_nm_setting_property_set_property_direct(object, prop_id, value, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_ovs_port_init(NMSettingOvsPort *self)
|
||||
{}
|
||||
{
|
||||
self->trunks = g_ptr_array_new_with_free_func((GDestroyNotify) nm_range_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_ovs_port_new:
|
||||
|
|
@ -281,6 +576,16 @@ nm_setting_ovs_port_new(void)
|
|||
return g_object_new(NM_TYPE_SETTING_OVS_PORT, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize(GObject *object)
|
||||
{
|
||||
NMSettingOvsPort *self = NM_SETTING_OVS_PORT(object);
|
||||
|
||||
g_ptr_array_unref(self->trunks);
|
||||
|
||||
G_OBJECT_CLASS(nm_setting_ovs_port_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass)
|
||||
{
|
||||
|
|
@ -288,8 +593,9 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass)
|
|||
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
|
||||
GArray *properties_override = _nm_sett_info_property_override_create_array();
|
||||
|
||||
object_class->get_property = _nm_setting_property_get_property_direct;
|
||||
object_class->set_property = _nm_setting_property_set_property_direct;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
setting_class->verify = verify;
|
||||
|
||||
|
|
@ -327,6 +633,31 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass)
|
|||
NMSettingOvsPort,
|
||||
tag);
|
||||
|
||||
/**
|
||||
* NMSettingOvsPort:trunks: (type GPtrArray(NMRange))
|
||||
*
|
||||
* A list of VLAN ranges that this port trunks.
|
||||
*
|
||||
* The property is valid only for ports with mode "trunk",
|
||||
* "native-tagged", or "native-untagged port".
|
||||
* If it is empty, the port trunks all VLANs.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
obj_properties[PROP_TRUNKS] = g_param_spec_boxed(NM_SETTING_OVS_PORT_TRUNKS,
|
||||
"",
|
||||
"",
|
||||
G_TYPE_PTR_ARRAY,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE
|
||||
| G_PARAM_STATIC_STRINGS);
|
||||
_nm_properties_override_gobj(
|
||||
properties_override,
|
||||
obj_properties[PROP_TRUNKS],
|
||||
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("aa{sv}"),
|
||||
.to_dbus_fcn = _nm_utils_ranges_to_dbus,
|
||||
.compare_fcn = _nm_utils_ranges_cmp,
|
||||
.from_dbus_fcn = _nm_utils_ranges_from_dbus));
|
||||
|
||||
/**
|
||||
* NMSettingOvsPort:lacp:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1073,6 +1073,12 @@ gboolean _nm_utils_bridge_vlans_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS
|
|||
|
||||
GVariant *_nm_utils_bridge_vlans_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil);
|
||||
|
||||
gboolean _nm_utils_ranges_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil);
|
||||
|
||||
NMTernary _nm_utils_ranges_cmp(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_nil);
|
||||
|
||||
GVariant *_nm_utils_ranges_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil);
|
||||
|
||||
NMTernary _nm_setting_ip_config_compare_fcn_addresses(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_nil);
|
||||
|
||||
NMTernary _nm_setting_ip_config_compare_fcn_routes(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_nil);
|
||||
|
|
|
|||
|
|
@ -5572,6 +5572,97 @@ _nm_utils_bridge_vlan_verify_list(GPtrArray *vlans,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
_nm_utils_ranges_to_dbus(_NM_SETT_INFO_PROP_TO_DBUS_FCN_ARGS _nm_nil)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *ranges = NULL;
|
||||
GVariantBuilder builder;
|
||||
const char *property_name = property_info->name;
|
||||
guint i;
|
||||
|
||||
nm_assert(property_name);
|
||||
|
||||
g_object_get(setting, property_name, &ranges, NULL);
|
||||
g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
|
||||
|
||||
if (ranges) {
|
||||
for (i = 0; i < ranges->len; i++) {
|
||||
NMRange *range = ranges->pdata[i];
|
||||
GVariantBuilder range_builder;
|
||||
|
||||
g_variant_builder_init(&range_builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add(&range_builder,
|
||||
"{sv}",
|
||||
"start",
|
||||
g_variant_new_uint64(range->start));
|
||||
g_variant_builder_add(&range_builder, "{sv}", "end", g_variant_new_uint64(range->end));
|
||||
|
||||
g_variant_builder_add(&builder, "a{sv}", &range_builder);
|
||||
}
|
||||
}
|
||||
|
||||
return g_variant_builder_end(&builder);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_utils_ranges_from_dbus(_NM_SETT_INFO_PROP_FROM_DBUS_FCN_ARGS _nm_nil)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *ranges = NULL;
|
||||
GVariantIter iter;
|
||||
GVariant *range_var;
|
||||
|
||||
g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), FALSE);
|
||||
|
||||
ranges = g_ptr_array_new_with_free_func((GDestroyNotify) nm_range_unref);
|
||||
g_variant_iter_init(&iter, value);
|
||||
while (g_variant_iter_next(&iter, "@a{sv}", &range_var)) {
|
||||
_nm_unused gs_unref_variant GVariant *var_unref = range_var;
|
||||
gint64 start;
|
||||
gint64 end;
|
||||
|
||||
if (!g_variant_lookup(range_var, "start", "t", &start))
|
||||
continue;
|
||||
if (!g_variant_lookup(range_var, "end", "t", &end))
|
||||
continue;
|
||||
if (start > end)
|
||||
continue;
|
||||
|
||||
g_ptr_array_add(ranges, nm_range_new(start, end));
|
||||
}
|
||||
|
||||
g_object_set(setting, property_info->name, ranges, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMTernary
|
||||
_nm_utils_ranges_cmp(_NM_SETT_INFO_PROP_COMPARE_FCN_ARGS _nm_nil)
|
||||
{
|
||||
const GPtrArray *ranges_a = NULL;
|
||||
const GPtrArray *ranges_b = NULL;
|
||||
guint len;
|
||||
guint i;
|
||||
|
||||
if (nm_streq0(nm_setting_get_name(set_a), NM_SETTING_OVS_PORT_SETTING_NAME)
|
||||
&& nm_streq0(property_info->name, NM_SETTING_OVS_PORT_TRUNKS)) {
|
||||
ranges_a = _nm_setting_ovs_port_get_trunks_arr(NM_SETTING_OVS_PORT(set_a));
|
||||
if (set_b)
|
||||
ranges_b = _nm_setting_ovs_port_get_trunks_arr(NM_SETTING_OVS_PORT(set_b));
|
||||
} else {
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
len = nm_g_ptr_array_len(ranges_a);
|
||||
if (len != nm_g_ptr_array_len(ranges_b))
|
||||
return FALSE;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (nm_range_cmp(ranges_a->pdata[i], ranges_b->pdata[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_utils_iaid_verify(const char *str, gint64 *out_value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ gboolean _nm_utils_dhcp_duid_valid(const char *duid, GBytes **out_duid_bin);
|
|||
gboolean _nm_setting_sriov_sort_vfs(NMSettingSriov *setting);
|
||||
gboolean _nm_setting_bridge_port_sort_vlans(NMSettingBridgePort *setting);
|
||||
gboolean _nm_setting_bridge_sort_vlans(NMSettingBridge *setting);
|
||||
gboolean _nm_setting_ovs_port_sort_trunks(NMSettingOvsPort *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -1067,4 +1068,6 @@ GPtrArray *_nm_setting_ip_config_get_dns_array(NMSettingIPConfig *setting);
|
|||
|
||||
gboolean nm_connection_need_secrets_for_rerequest(NMConnection *connection);
|
||||
|
||||
const GPtrArray *_nm_setting_ovs_port_get_trunks_arr(NMSettingOvsPort *self);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ G_BEGIN_DECLS
|
|||
|
||||
#define NM_SETTING_OVS_PORT_VLAN_MODE "vlan-mode"
|
||||
#define NM_SETTING_OVS_PORT_TAG "tag"
|
||||
#define NM_SETTING_OVS_PORT_TRUNKS "trunks"
|
||||
#define NM_SETTING_OVS_PORT_LACP "lacp"
|
||||
#define NM_SETTING_OVS_PORT_BOND_MODE "bond-mode"
|
||||
#define NM_SETTING_OVS_PORT_BOND_UPDELAY "bond-updelay"
|
||||
|
|
@ -54,6 +55,20 @@ guint nm_setting_ovs_port_get_bond_updelay(NMSettingOvsPort *self);
|
|||
NM_AVAILABLE_IN_1_10
|
||||
guint nm_setting_ovs_port_get_bond_downdelay(NMSettingOvsPort *self);
|
||||
|
||||
NM_AVAILABLE_IN_1_42
|
||||
void nm_setting_ovs_port_add_trunk(NMSettingOvsPort *setting, NMRange *trunk);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
guint nm_setting_ovs_port_get_num_trunks(NMSettingOvsPort *setting);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
NMRange *nm_setting_ovs_port_get_trunk(NMSettingOvsPort *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
void nm_setting_ovs_port_remove_trunk(NMSettingOvsPort *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
gboolean
|
||||
nm_setting_ovs_port_remove_trunk_by_value(NMSettingOvsPort *setting, guint start, guint end);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
void nm_setting_ovs_port_clear_trunks(NMSettingOvsPort *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_OVS_PORT_H__ */
|
||||
|
|
|
|||
|
|
@ -3767,6 +3767,20 @@ _objlist_obj_to_str_fcn_tc_config_qdiscs(NMMetaAccessorGetType get_type,
|
|||
g_string_append(str, s);
|
||||
}
|
||||
|
||||
static void
|
||||
_objlist_obj_to_str_fcn_ovs_port_trunks(NMMetaAccessorGetType get_type,
|
||||
NMSetting *setting,
|
||||
guint idx,
|
||||
GString *str)
|
||||
{
|
||||
gs_free char *s = NULL;
|
||||
NMRange *trunk;
|
||||
|
||||
trunk = nm_setting_ovs_port_get_trunk(NM_SETTING_OVS_PORT(setting), idx);
|
||||
s = nm_range_to_str(trunk);
|
||||
nm_utils_escaped_tokens_escape_gstr_assert(s, ESCAPED_TOKENS_DELIMITERS, str);
|
||||
}
|
||||
|
||||
static void
|
||||
_objlist_obj_to_str_fcn_bridge_vlans(NMMetaAccessorGetType get_type,
|
||||
NMSetting *setting,
|
||||
|
|
@ -3835,6 +3849,37 @@ _objlist_set_fcn_tc_config_qdiscs(NMSetting *setting,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_objlist_set_fcn_ovs_port_trunks(NMSetting *setting,
|
||||
gboolean do_add,
|
||||
const char *value,
|
||||
GError **error)
|
||||
{
|
||||
NMRange *range;
|
||||
gs_free_error GError *local = NULL;
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
|
||||
range = nm_range_from_str(value, &local);
|
||||
if (!range) {
|
||||
nm_utils_error_set(error,
|
||||
NM_UTILS_ERROR_INVALID_ARGUMENT,
|
||||
"%s. %s",
|
||||
local->message,
|
||||
_("The valid syntax is: '<value>' or '<start>-<end>"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (do_add)
|
||||
nm_setting_ovs_port_add_trunk(NM_SETTING_OVS_PORT(setting), range);
|
||||
else {
|
||||
nm_range_get_range(range, &start, &end);
|
||||
nm_setting_ovs_port_remove_trunk_by_value(NM_SETTING_OVS_PORT(setting), start, end);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_objlist_set_fcn_bridge_vlans(NMSetting *setting,
|
||||
gboolean do_add,
|
||||
|
|
@ -6836,6 +6881,17 @@ static const NMMetaPropertyInfo *const property_infos_OVS_PORT[] = {
|
|||
.values_static = NM_MAKE_STRV ("access", "native-tagged", "native-untagged", "trunk"),
|
||||
),
|
||||
),
|
||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_TRUNKS,
|
||||
.property_type = &_pt_objlist,
|
||||
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
|
||||
PROPERTY_TYP_DATA_SUBTYPE (objlist,
|
||||
.get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingOvsPort, nm_setting_ovs_port_get_num_trunks),
|
||||
.clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingOvsPort, nm_setting_ovs_port_clear_trunks),
|
||||
.obj_to_str_fcn = _objlist_obj_to_str_fcn_ovs_port_trunks,
|
||||
.set_fcn = _objlist_set_fcn_ovs_port_trunks,
|
||||
),
|
||||
),
|
||||
),
|
||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_TAG,
|
||||
.property_type = &_pt_gobject_int,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@
|
|||
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_UPDELAY N_("The time port must be active before it starts forwarding traffic.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_LACP N_("LACP mode. One of \"active\", \"off\", or \"passive\".")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_TAG N_("The VLAN tag in the range 0-4095.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_TRUNKS N_("A list of VLAN ranges that this port trunks. The property is valid only for ports with mode \"trunk\", \"native-tagged\", or \"native-untagged port\". If it is empty, the port trunks all VLANs.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_VLAN_MODE N_("The VLAN mode. One of \"access\", \"native-tagged\", \"native-untagged\", \"trunk\" or unset.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_PPP_BAUD N_("If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_PPP_CRTSCTS N_("If TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE.")
|
||||
|
|
|
|||
|
|
@ -849,6 +849,8 @@
|
|||
<setting name="ovs-port" >
|
||||
<property name="vlan-mode"
|
||||
description="The VLAN mode. One of "access", "native-tagged", "native-untagged", "trunk" or unset." />
|
||||
<property name="trunks"
|
||||
description="A list of VLAN ranges that this port trunks. The property is valid only for ports with mode "trunk", "native-tagged", or "native-untagged port". If it is empty, the port trunks all VLANs." />
|
||||
<property name="tag"
|
||||
description="The VLAN tag in the range 0-4095." />
|
||||
<property name="lacp"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue