mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-22 00:00:40 +02:00
ovs: merge branch 'bg/ovs-port-trunks'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1467 https://bugzilla.redhat.com/show_bug.cgi?id=2111959
This commit is contained in:
commit
953628a765
16 changed files with 982 additions and 19 deletions
|
|
@ -865,6 +865,7 @@ _insert_port(json_t *params, NMConnection *port, json_t *new_interfaces)
|
|||
{
|
||||
NMSettingOvsPort *s_ovs_port;
|
||||
const char *vlan_mode = NULL;
|
||||
json_t *trunks = NULL;
|
||||
guint tag = 0;
|
||||
const char *lacp = NULL;
|
||||
const char *bond_mode = NULL;
|
||||
|
|
@ -877,18 +878,34 @@ _insert_port(json_t *params, NMConnection *port, json_t *new_interfaces)
|
|||
row = json_object();
|
||||
|
||||
if (s_ovs_port) {
|
||||
const GPtrArray *ranges;
|
||||
guint i;
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
|
||||
vlan_mode = nm_setting_ovs_port_get_vlan_mode(s_ovs_port);
|
||||
tag = nm_setting_ovs_port_get_tag(s_ovs_port);
|
||||
lacp = nm_setting_ovs_port_get_lacp(s_ovs_port);
|
||||
bond_mode = nm_setting_ovs_port_get_bond_mode(s_ovs_port);
|
||||
bond_updelay = nm_setting_ovs_port_get_bond_updelay(s_ovs_port);
|
||||
bond_downdelay = nm_setting_ovs_port_get_bond_downdelay(s_ovs_port);
|
||||
|
||||
ranges = _nm_setting_ovs_port_get_trunks_arr(s_ovs_port);
|
||||
for (i = 0; i < ranges->len; i++) {
|
||||
if (!trunks)
|
||||
trunks = json_array();
|
||||
nm_range_get_range(ranges->pdata[i], &start, &end);
|
||||
for (; start <= end; start++)
|
||||
json_array_append_new(trunks, json_integer(start));
|
||||
}
|
||||
}
|
||||
|
||||
if (vlan_mode)
|
||||
json_object_set_new(row, "vlan_mode", json_string(vlan_mode));
|
||||
if (tag)
|
||||
json_object_set_new(row, "tag", json_integer(tag));
|
||||
if (trunks)
|
||||
json_object_set_new(row, "trunks", json_pack("[s, o]", "set", trunks));
|
||||
if (lacp)
|
||||
json_object_set_new(row, "lacp", json_string(lacp));
|
||||
if (bond_mode)
|
||||
|
|
|
|||
|
|
@ -1884,11 +1884,25 @@ global:
|
|||
nm_client_wait_shutdown;
|
||||
nm_client_wait_shutdown_finish;
|
||||
nm_device_loopback_get_type;
|
||||
nm_range_cmp;
|
||||
nm_range_from_str;
|
||||
nm_range_get_range;
|
||||
nm_range_get_type;
|
||||
nm_range_new;
|
||||
nm_range_ref;
|
||||
nm_range_to_str;
|
||||
nm_range_unref;
|
||||
nm_setting_ip_config_get_dhcp_iaid;
|
||||
nm_setting_ip_config_get_dhcp_iaid;
|
||||
nm_setting_loopback_get_mtu;
|
||||
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)
|
||||
{
|
||||
|
|
@ -208,6 +449,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
"native-tagged",
|
||||
"native-untagged",
|
||||
"trunk",
|
||||
"dot1q-tunnel",
|
||||
NULL)) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
@ -257,14 +499,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 +577,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 +594,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;
|
||||
|
||||
|
|
@ -297,7 +604,7 @@ nm_setting_ovs_port_class_init(NMSettingOvsPortClass *klass)
|
|||
* NMSettingOvsPort:vlan-mode:
|
||||
*
|
||||
* The VLAN mode. One of "access", "native-tagged", "native-untagged",
|
||||
* "trunk" or unset.
|
||||
* "trunk", "dot1q-tunnel" or unset.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
|
|
@ -327,6 +634,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:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -302,6 +302,14 @@ typedef struct {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NMRange {
|
||||
guint refcount;
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_SETTING_PARAM_NONE 0
|
||||
|
||||
/* The property of the #NMSetting should be considered during comparisons that
|
||||
|
|
@ -1065,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);
|
||||
|
|
|
|||
|
|
@ -4123,6 +4123,233 @@ nm_setting_option_set_uint32(NMSetting *setting, const char *opt_name, guint32 v
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
G_DEFINE_BOXED_TYPE(NMRange, nm_range, nm_range_ref, (GBoxedFreeFunc) nm_range_unref)
|
||||
|
||||
static gboolean
|
||||
NM_IS_RANGE(const NMRange *self)
|
||||
{
|
||||
return self && self->refcount > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_new:
|
||||
* @start: the first element of the range
|
||||
* @end: the last element of the range, must be greater than or equal
|
||||
* to @start.
|
||||
*
|
||||
* Creates a new #NMRange object for the given range. Setting @end
|
||||
* equal to @start creates a single-element range.
|
||||
*
|
||||
* Returns: (transfer full): the new #NMRange object.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
NMRange *
|
||||
nm_range_new(guint64 start, guint64 end)
|
||||
{
|
||||
NMRange *range;
|
||||
|
||||
g_return_val_if_fail(start <= end, NULL);
|
||||
|
||||
range = g_slice_new(NMRange);
|
||||
*range = (NMRange){
|
||||
.refcount = 1,
|
||||
.start = start,
|
||||
.end = end,
|
||||
};
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_ref:
|
||||
* @range: the #NMRange
|
||||
*
|
||||
* Increases the reference count of the object.
|
||||
*
|
||||
* Returns: the input argument @range object.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
NMRange *
|
||||
nm_range_ref(const NMRange *range)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_RANGE(range), NULL);
|
||||
|
||||
nm_assert(range->refcount < G_MAXUINT);
|
||||
|
||||
((NMRange *) range)->refcount++;
|
||||
return (NMRange *) range;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_unref:
|
||||
* @range: the #NMRange
|
||||
*
|
||||
* Decreases the reference count of the object. If the reference count
|
||||
* reaches zero the object will be destroyed.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
void
|
||||
nm_range_unref(const NMRange *range)
|
||||
{
|
||||
g_return_if_fail(NM_IS_RANGE(range));
|
||||
|
||||
nm_assert(range->refcount != 0);
|
||||
|
||||
if (--((NMRange *) range)->refcount == 0)
|
||||
g_slice_free(NMRange, (NMRange *) range);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_cmp:
|
||||
* @a: a #NMRange
|
||||
* @b: another #NMRange
|
||||
*
|
||||
* Compare two ranges.
|
||||
*
|
||||
* Returns: zero if the two instances are equivalent or
|
||||
* a non-zero integer otherwise. This defines a total ordering
|
||||
* over the ranges.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
int
|
||||
nm_range_cmp(const NMRange *a, const NMRange *b)
|
||||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
NM_CMP_FIELD(a, b, start);
|
||||
NM_CMP_FIELD(a, b, end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_get_range:
|
||||
* @range: the #NMRange
|
||||
* @start: (out): location to store the start value
|
||||
* @end: (out): location to store the end value
|
||||
*
|
||||
* Gets the start and end values for the range.
|
||||
*
|
||||
* Returns: %TRUE if the range contains more than one
|
||||
* element, %FALSE otherwise.
|
||||
*
|
||||
* Since: 1.42
|
||||
**/
|
||||
gboolean
|
||||
nm_range_get_range(const NMRange *range, guint64 *start, guint64 *end)
|
||||
{
|
||||
/* with LTO and optimization, the compiler complains that the
|
||||
* output variables are not initialized. In practice, the function
|
||||
* only sets the output on success. But make the compiler happy.
|
||||
*/
|
||||
NM_SET_OUT(start, 0);
|
||||
NM_SET_OUT(end, 0);
|
||||
|
||||
g_return_val_if_fail(NM_IS_RANGE(range), 0);
|
||||
|
||||
NM_SET_OUT(start, range->start);
|
||||
NM_SET_OUT(end, range->end);
|
||||
|
||||
return range->start != range->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_to_str:
|
||||
* @range: the %NMRange
|
||||
*
|
||||
* Convert a %NMRange to a string.
|
||||
*
|
||||
* Returns: (transfer full): a string representing the range.
|
||||
*
|
||||
* Since: 1.42
|
||||
*/
|
||||
char *
|
||||
nm_range_to_str(const NMRange *range)
|
||||
{
|
||||
char buf[200];
|
||||
char *b = buf;
|
||||
gsize l = sizeof(buf);
|
||||
|
||||
g_return_val_if_fail(NM_IS_RANGE(range), NULL);
|
||||
|
||||
nm_strbuf_append(&b, &l, "%" G_GUINT64_FORMAT, range->start);
|
||||
if (range->start != range->end)
|
||||
nm_strbuf_append(&b, &l, "-%" G_GUINT64_FORMAT, range->end);
|
||||
|
||||
nm_assert(l > 0);
|
||||
return nm_memdup_nul(buf, sizeof(buf) - l);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_range_from_str:
|
||||
* @str: the string representation of a range
|
||||
* @error: (out) (allow-none): location to store the error on failure
|
||||
*
|
||||
* Parses the string representation of the range to create a %NMRange
|
||||
* instance.
|
||||
*
|
||||
* Returns: (transfer full): the %NMRange or %NULL
|
||||
*
|
||||
* Since: 1.42
|
||||
*/
|
||||
NMRange *
|
||||
nm_range_from_str(const char *str, GError **error)
|
||||
{
|
||||
gs_free char *str_free = NULL;
|
||||
guint64 start;
|
||||
guint64 end = 0;
|
||||
char *c;
|
||||
|
||||
g_return_val_if_fail(str, NULL);
|
||||
g_return_val_if_fail(!error || !*error, NULL);
|
||||
|
||||
c = strchr(str, '-');
|
||||
if (c) {
|
||||
str = nm_strndup_a(300, str, c - str, &str_free);
|
||||
c++;
|
||||
}
|
||||
|
||||
start = _nm_utils_ascii_str_to_uint64(str, 10, 0, G_MAXUINT64, 0);
|
||||
if (errno != 0) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_FAILED,
|
||||
"invalid range start '%s'",
|
||||
str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (c) {
|
||||
end = _nm_utils_ascii_str_to_uint64(c, 10, 0, G_MAXUINT64, 0);
|
||||
if (errno != 0) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_FAILED,
|
||||
"invalid range end '%s'",
|
||||
c);
|
||||
return NULL;
|
||||
}
|
||||
if (end < start) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_FAILED,
|
||||
"invalid range %" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT
|
||||
", start must be less than or equal to end",
|
||||
start,
|
||||
end);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
end = start;
|
||||
|
||||
return nm_range_new(start, end);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4165,6 +4165,88 @@ test_routing_rule(gconstpointer test_data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_ranges(void)
|
||||
{
|
||||
GError *error = NULL;
|
||||
NMRange *r1;
|
||||
NMRange *r2;
|
||||
guint64 start;
|
||||
guint64 end;
|
||||
char *str = NULL;
|
||||
char *str2 = NULL;
|
||||
|
||||
r1 = nm_range_from_str("99", &error);
|
||||
nmtst_assert_success(r1, error);
|
||||
nm_range_get_range(r1, &start, &end);
|
||||
g_assert_cmpint(start, ==, 99);
|
||||
g_assert_cmpint(end, ==, 99);
|
||||
str = nm_range_to_str(r1);
|
||||
g_assert_cmpstr(str, ==, "99");
|
||||
nm_clear_g_free(&str);
|
||||
nm_range_unref(r1);
|
||||
|
||||
r1 = nm_range_from_str("1000-2000", &error);
|
||||
nmtst_assert_success(r1, error);
|
||||
nm_range_get_range(r1, &start, &end);
|
||||
g_assert_cmpint(start, ==, 1000);
|
||||
g_assert_cmpint(end, ==, 2000);
|
||||
str = nm_range_to_str(r1);
|
||||
g_assert_cmpstr(str, ==, "1000-2000");
|
||||
nm_clear_g_free(&str);
|
||||
nm_range_unref(r1);
|
||||
|
||||
r1 = nm_range_from_str("0", &error);
|
||||
nmtst_assert_success(r1, error);
|
||||
nm_range_unref(r1);
|
||||
|
||||
r1 = nm_range_from_str("-1", &error);
|
||||
nmtst_assert_no_success(r1, error);
|
||||
g_clear_error(&error);
|
||||
|
||||
r1 = nm_range_from_str("foobar", &error);
|
||||
nmtst_assert_no_success(r1, error);
|
||||
g_clear_error(&error);
|
||||
|
||||
r1 = nm_range_from_str("200-100", &error);
|
||||
nmtst_assert_no_success(r1, error);
|
||||
g_clear_error(&error);
|
||||
|
||||
r1 = nm_range_from_str("100-200", &error);
|
||||
nmtst_assert_success(r1, error);
|
||||
r2 = nm_range_from_str("100-200", &error);
|
||||
nmtst_assert_success(r2, error);
|
||||
g_assert_cmpint(nm_range_cmp(r1, r2), ==, 0);
|
||||
nm_range_unref(r1);
|
||||
nm_range_unref(r2);
|
||||
|
||||
r1 = nm_range_from_str("100-200", &error);
|
||||
nmtst_assert_success(r1, error);
|
||||
r2 = nm_range_from_str("1", &error);
|
||||
nmtst_assert_success(r2, error);
|
||||
g_assert_cmpint(nm_range_cmp(r1, r2), ==, 1);
|
||||
nm_range_ref(r1);
|
||||
nm_range_unref(r1);
|
||||
nm_range_unref(r1);
|
||||
nm_range_unref(r2);
|
||||
|
||||
r1 = nm_range_new(G_MAXUINT64 - 1, G_MAXUINT64);
|
||||
g_assert(r1);
|
||||
str = nm_range_to_str(r1);
|
||||
g_assert_cmpstr(str, ==, "18446744073709551614-18446744073709551615");
|
||||
r2 = nm_range_from_str(str, &error);
|
||||
nmtst_assert_success(r2, error);
|
||||
str2 = nm_range_to_str(r2);
|
||||
g_assert_cmpstr(str, ==, str2);
|
||||
g_assert_cmpint(nm_range_cmp(r1, r2), ==, 0);
|
||||
nm_range_unref(r1);
|
||||
nm_range_unref(r2);
|
||||
nm_clear_g_free(&str);
|
||||
nm_clear_g_free(&str2);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_parse_tc_handle(void)
|
||||
{
|
||||
|
|
@ -5316,6 +5398,8 @@ main(int argc, char **argv)
|
|||
|
||||
g_test_add_data_func("/libnm/settings/routing-rule/1", GINT_TO_POINTER(0), test_routing_rule);
|
||||
|
||||
g_test_add_func("/libnm/settings/ranges", test_ranges);
|
||||
|
||||
g_test_add_func("/libnm/parse-tc-handle", test_parse_tc_handle);
|
||||
|
||||
g_test_add_func("/libnm/test_team_setting", test_team_setting);
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -260,6 +260,25 @@ const GVariantType *nm_setting_get_dbus_property_type(NMSetting *setting,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMRange NMRange;
|
||||
|
||||
NM_AVAILABLE_IN_1_42
|
||||
GType nm_range_get_type(void);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
NMRange *nm_range_new(guint64 start, guint64 end);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
NMRange *nm_range_ref(const NMRange *range);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
void nm_range_unref(const NMRange *range);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
int nm_range_cmp(const NMRange *a, const NMRange *b);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
gboolean nm_range_get_range(const NMRange *range, guint64 *start, guint64 *end);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
char *nm_range_to_str(const NMRange *range);
|
||||
NM_AVAILABLE_IN_1_42
|
||||
NMRange *nm_range_from_str(const char *str, GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_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,
|
||||
|
|
@ -6833,7 +6878,18 @@ static const NMMetaPropertyInfo *const property_infos_OVS_PORT[] = {
|
|||
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_VLAN_MODE,
|
||||
.property_type = &_pt_gobject_string,
|
||||
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
|
||||
.values_static = NM_MAKE_STRV ("access", "native-tagged", "native-untagged", "trunk"),
|
||||
.values_static = NM_MAKE_STRV ("access", "native-tagged", "native-untagged", "trunk", "dot1q-tunnel"),
|
||||
),
|
||||
),
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -260,7 +260,8 @@
|
|||
#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_VLAN_MODE N_("The VLAN mode. One of \"access\", \"native-tagged\", \"native-untagged\", \"trunk\" or unset.")
|
||||
#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\", \"dot1q-tunnel\" 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.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_PPP_LCP_ECHO_FAILURE N_("If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The \"lcp-echo-interval\" property must also be set to a non-zero value if this property is used.")
|
||||
|
|
|
|||
|
|
@ -848,7 +848,9 @@
|
|||
</setting>
|
||||
<setting name="ovs-port" >
|
||||
<property name="vlan-mode"
|
||||
description="The VLAN mode. One of "access", "native-tagged", "native-untagged", "trunk" or unset." />
|
||||
description="The VLAN mode. One of "access", "native-tagged", "native-untagged", "trunk", "dot1q-tunnel" 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