ovs: merge branch 'th/ovs-external-ids' (first part of feature)

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/673
This commit is contained in:
Thomas Haller 2020-11-10 13:50:00 +01:00
commit b55f13406f
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
58 changed files with 2187 additions and 636 deletions

View file

@ -85,6 +85,8 @@ ForEachMacros: ['c_list_for_each',
'c_rbtree_for_each_safe',
'c_rbtree_for_each_safe_postorder',
'c_rbtree_for_each_safe_postorder_unlink',
'json_array_foreach',
'json_object_foreach',
'json_object_foreach_safe',
'ndp_msg_opt_dnssl_for_each_domain',
'ndp_msg_opt_for_each_offset',

View file

@ -954,6 +954,7 @@ libnm_core_lib_h_pub_real = \
libnm-core/nm-setting-olpc-mesh.h \
libnm-core/nm-setting-ovs-bridge.h \
libnm-core/nm-setting-ovs-dpdk.h \
libnm-core/nm-setting-ovs-external-ids.h \
libnm-core/nm-setting-ovs-interface.h \
libnm-core/nm-setting-ovs-patch.h \
libnm-core/nm-setting-ovs-port.h \
@ -1027,6 +1028,7 @@ libnm_core_lib_c_settings_real = \
libnm-core/nm-setting-olpc-mesh.c \
libnm-core/nm-setting-ovs-bridge.c \
libnm-core/nm-setting-ovs-dpdk.c \
libnm-core/nm-setting-ovs-external-ids.c \
libnm-core/nm-setting-ovs-interface.c \
libnm-core/nm-setting-ovs-patch.c \
libnm-core/nm-setting-ovs-port.c \

View file

@ -181,6 +181,7 @@ EXTRA_DIST += \
examples/python/gi/nm-keyfile.py \
examples/python/gi/nm-update2.py \
examples/python/gi/nm-wg-set \
examples/python/gi/ovs-external-ids.py \
examples/python/gi/setting-user-data.py \
examples/python/gi/show-wifi-networks.py \
examples/python/gi/update-ip4-method.py \

View file

@ -784,6 +784,8 @@
<property name="devargs"
description="Open vSwitch DPDK device arguments." />
</setting>
<setting name="ovs-external-ids" >
</setting>
<setting name="ovs-interface" >
<property name="type"
description="The interface type. Either &quot;internal&quot;, &quot;system&quot;, &quot;patch&quot;, &quot;dpdk&quot;, or empty." />

View file

@ -7946,6 +7946,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
#define SETTING_PRETTY_NAME_OLPC_MESH N_("OLPC Mesh connection")
#define SETTING_PRETTY_NAME_OVS_BRIDGE N_("Open vSwitch bridge settings")
#define SETTING_PRETTY_NAME_OVS_DPDK N_("Open vSwitch DPDK interface settings")
#define SETTING_PRETTY_NAME_OVS_EXTERNAL_IDS N_("OVS External IDs")
#define SETTING_PRETTY_NAME_OVS_INTERFACE N_("Open vSwitch interface settings")
#define SETTING_PRETTY_NAME_OVS_PATCH N_("Open vSwitch patch interface settings")
#define SETTING_PRETTY_NAME_OVS_PORT N_("Open vSwitch port settings")
@ -8129,6 +8130,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
),
),
SETTING_INFO (OVS_DPDK),
SETTING_INFO_EMPTY (OVS_EXTERNAL_IDS),
SETTING_INFO (OVS_INTERFACE,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),

View file

@ -294,6 +294,7 @@
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_RSTP_ENABLE N_("Enable or disable RSTP.")
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_STP_ENABLE N_("Enable or disable STP.")
#define DESCRIBE_DOC_NM_SETTING_OVS_DPDK_DEVARGS N_("Open vSwitch DPDK device arguments.")
#define DESCRIBE_DOC_NM_SETTING_OVS_EXTERNAL_IDS_DATA N_("A dictionary of key/value pairs with exernal-ids for OVS.")
#define DESCRIBE_DOC_NM_SETTING_OVS_INTERFACE_TYPE N_("The interface type. Either \"internal\", \"system\", \"patch\", \"dpdk\", or empty.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PATCH_PEER N_("Specifies the name of the interface for the other side of the patch. The patch on the other side must also set this interface as peer.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_DOWNDELAY N_("The time port must be inactive in order to be considered down.")

View file

@ -338,6 +338,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-setting-ovs-dpdk.xml"/>
<xi:include href="xml/nm-setting-ovs-patch.xml"/>
<xi:include href="xml/nm-setting-ovs-port.xml"/>
<xi:include href="xml/nm-setting-ovs-external-ids.xml"/>
<xi:include href="xml/nm-setting-ppp.xml"/>
<xi:include href="xml/nm-setting-pppoe.xml"/>
<xi:include href="xml/nm-setting-proxy.xml"/>

View file

@ -0,0 +1,425 @@
#!/usr/bin/env python
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2017, 2020 Red Hat, Inc.
#
#
# set and show OVS external-ids for a connection:
#
import sys
import os
import re
import pprint
import gi
gi.require_version("NM", "1.0")
from gi.repository import GLib, NM
MODE_GET = "get"
MODE_SET = "set"
def pr(v):
pprint.pprint(v, indent=4, depth=5, width=60)
HAS_LIBNM_DEBUG = os.getenv("LIBNM_CLIENT_DEBUG") is not None
def _print(msg=""):
if HAS_LIBNM_DEBUG:
# we want to use the same logging mechanism as libnm's debug
# logging with "LIBNM_CLIENT_DEBUG=trace,stdout".
NM.utils_print(0, msg + "\n")
return
print(msg)
def mainloop_run(timeout_msec=0, mainloop=None):
if mainloop is None:
mainloop = GLib.MainLoop()
timeout_id = None
timeout_reached = []
if timeout_msec > 0:
def _timeout_cb(unused):
# it can happen that the caller already quit the mainloop
# otherwise. In that case, we don't want to signal a timeout.
if mainloop.is_running():
timeout_reached.append(1)
mainloop.quit()
return True
timeout_id = GLib.timeout_add(timeout_msec, _timeout_cb, None)
mainloop.run()
if timeout_id:
GLib.source_remove(timeout_id)
return not timeout_reached
def usage():
_print("%s g[et] PROFILE [ GETTER ]" % (sys.argv[0]))
_print("%s s[et] [--test] PROFILE SETTER" % (sys.argv[0]))
_print(
" PROFILE := [id | uuid | type] STRING | [ ~id | ~type ] REGEX_STRING | STRING"
)
_print(" GETTER := ( KEY | ~REGEX_KEY ) [... GETTER]")
_print(" SETTER := ( + | - | -KEY | [+]KEY VALUE ) [... SETTER]")
def die(msg, show_usage=False):
_print("FAILED: %s" % (msg))
if show_usage:
usage()
sys.exit(1)
def die_usage(msg):
die(msg, show_usage=True)
def parse_args(argv):
had_dash_dash = False
args = {
"mode": MODE_GET,
"profile_arg": None,
"ids_arg": [],
"do_test": False,
}
i = 1
while i < len(argv):
a = argv[i]
if i == 1:
if a in ["s", "set"]:
args["mode"] = MODE_SET
elif a in ["g", "get"]:
args["mode"] = MODE_GET
else:
die_usage("unexpected mode argument '%s'" % (a))
i += 1
continue
if a == "--test":
args["do_test"] = True
i += 1
continue
if args["profile_arg"] is None:
if a in ["id", "~id", "uuid", "type", "~type"]:
if i + 1 >= len(argv):
die_usage("'%s' requires an argument'" % (a))
args["profile_arg"] = (a, argv[i + 1])
i += 2
continue
if a == "*":
a = None
args["profile_arg"] = ("*", a)
i += 1
continue
if args["mode"] == MODE_GET:
args["ids_arg"].append(a)
i += 1
continue
if not a:
die_usage("argument should specify a external-id but is empty string")
if a[0] == "-":
v = (a, None)
i += 1
elif a == "+":
v = (a, None)
i += 1
else:
if a[0] != "+":
a = "+" + a
if i + 1 >= len(argv):
die_usage("'%s' requires an argument'" % (a))
v = (a, argv[i + 1])
i += 2
args["ids_arg"].append(v)
if args["mode"] == MODE_SET:
if not args["ids_arg"]:
die_usage("Requires one or more external-ids to set or delete")
return args
def connection_to_str(connection, show_type=False):
if show_type:
return "%s (%s, %s)" % (
connection.get_id(),
connection.get_uuid(),
connection.get_connection_type(),
)
return "%s (%s)" % (connection.get_id(), connection.get_uuid())
def connections_filter(connections, profile_arg):
connections = list(sorted(connections, key=connection_to_str))
if not profile_arg:
return connections
# we preserve the order of the selected connections. And
# if connections are selected multiple times, we return
# them multiple times.
l = []
f = profile_arg
for c in connections:
if f[0] == "id":
if f[1] == c.get_id():
l.append(c)
elif f[0] == "~id":
if re.match(f[1], c.get_id()):
l.append(c)
elif f[0] == "uuid":
if f[1] == c.get_uuid():
l.append(c)
elif f[0] == "type":
if f[1] == c.get_connection_type():
l.append(c)
elif f[0] == "~type":
if re.match(f[1], c.get_connection_type()):
l.append(c)
else:
assert f[0] == "*"
if f[1] is None:
l.append(c)
else:
if f[1] in [c.get_uuid(), c.get_id()]:
l.append(c)
return l
def ids_select(ids, mode, ids_arg):
ids = list(ids)
if not ids_arg:
return (ids, [])
keys = set()
requested = []
for d in ids_arg:
if mode == MODE_GET:
if d[0] == "~":
r = re.compile(d[1:])
keys.update([k for k in ids if r.match(k)])
else:
keys.update([k for k in ids if k == d])
if d not in requested:
requested.append(d)
else:
d2 = d[0]
assert d2[0] in ["-", "+"]
d3 = d2[1:]
if d3 in ids:
keys.add(d3)
return (list([k for k in ids if k in keys]), requested)
def connection_print(connection, mode, ids_arg, dbus_path, prefix=""):
sett = connection.get_setting(NM.SettingOvsExternalIDs)
if sett is not None:
all_ids = list(sett.get_data_keys())
keys, requested = ids_select(all_ids, mode, ids_arg)
num_str = "%s" % (len(all_ids))
else:
keys = []
requested = []
num_str = "none"
_print(
"%s%s [%s]" % (prefix, connection_to_str(connection, show_type=True), num_str)
)
_print("%s %s" % (prefix, dbus_path))
if sett is not None:
dd = sett.get_property(NM.SETTING_OVS_EXTERNAL_IDS_DATA)
else:
dd = {}
for k in keys:
v = sett.get_data(k)
assert v is not None
assert v == dd.get(k, None)
_print('%s "%s" = "%s"' % (prefix, k, v))
for k in requested:
_print('%s "%s" = <unset>' % (prefix, k))
def do_get(connections, ids_arg):
first_line = True
for c in connections:
if first_line:
first_line = False
else:
_print()
connection_print(c, MODE_GET, ids_arg, dbus_path=c.get_path())
def do_set(nmc, connection, ids_arg, do_test):
remote_connection = connection
connection = NM.SimpleConnection.new_clone(remote_connection)
connection_print(
connection, MODE_SET, [], remote_connection.get_path(), prefix="BEFORE: "
)
_print()
sett = connection.get_setting(NM.SettingOvsExternalIDs)
for d in ids_arg:
op = d[0][0]
key = d[0][1:]
val = d[1]
oldval = None
if sett is not None:
oldval = sett.get_data(key)
if op == "-":
assert val is None
if key == "":
if sett is None:
_print(" DEL: setting (ovs-external-ids group was not present)")
else:
connection.remove_setting(NM.SettingOvsExternalIDs)
sett = None
_print(" DEL: setting")
continue
if sett is None:
_print(' DEL: "%s" (ovs-external-ids group was not present)' % (key))
continue
if oldval is None:
_print(' DEL: "%s" (id was unset)' % (key))
continue
_print(' DEL: "%s" (id was set to"%s")' % (key, oldval))
sett.set_data(key, None)
continue
if key == "":
assert val is None
if sett is None:
sett = NM.SettingOvsExternalIDs.new()
connection.add_setting(sett)
_print(" SET: setting (external-ids group was added)")
continue
_print(" SET: setting (external-ids group was present)")
continue
assert val is not None
if sett is None:
sett = NM.SettingOvsExternalIDs.new()
connection.add_setting(sett)
_print(
' SET: "%s" = "%s" (external-ids group was not present)' % (key, val)
)
elif oldval is None:
_print(' SET: "%s" = "%s" (new)' % (key, val))
elif oldval != val:
_print(' SET: "%s" = "%s" (was "%s")' % (key, val, oldval))
else:
_print(' SET: "%s" = "%s" (unchanged)' % (key, val))
sett.set_data(key, val)
if do_test:
_print()
_print("Only show. Run without --test to set")
return
mainloop = GLib.MainLoop()
result_error = []
def callback(c, result):
try:
c.update2_finish(result)
except Exception as e:
result_error.append(e)
mainloop.quit()
remote_connection.update2(
connection.to_dbus(NM.ConnectionSerializationFlags.ALL),
NM.SettingsUpdate2Flags.NO_REAPPLY,
None,
None,
callback,
)
mainloop_run(mainloop=mainloop)
if result_error:
_print()
_print("FAILURE to commit connection: %s" % (result_error[0]))
return
# NMClient received the completion of Update2() call. It also received
# a property changed signal that the profile changed, and it is about
# to fetch the new value. However, that value is not yet here.
#
# libnm should provide a better API for this. For example, not signal
# completion of update2() until the profile was refetched. Or, indicate
# that the settings are dirty, so we would know how long to wait.
#
# Add an ugly workaround here and wait a bit.
_print()
_print("WORKAROUND: wait for connection to change")
mainloop_run(timeout_msec=500)
if remote_connection is not nmc.get_object_by_path(remote_connection.get_path()):
_print()
_print(
"Connection %s no longer exists after commit"
% (remote_connection.get_path())
)
return
_print()
connection_print(
remote_connection, MODE_SET, [], remote_connection.get_path(), prefix="AFTER: "
)
_print()
if remote_connection.compare(connection, NM.SettingCompareFlags.EXACT):
_print("resulting connection is as expected")
else:
_print("WARNING: resulting connection is not as expected")
###############################################################################
if __name__ == "__main__":
args = parse_args(sys.argv)
nmc = NM.Client.new(None)
connections = connections_filter(nmc.get_connections(), args["profile_arg"])
if args["mode"] == MODE_SET:
if len(connections) != 1:
_print(
"To set the external-ids of a connection, exactly one connection must be selected via id|uuid. Instead, %s connection matched ([%s])"
% (
len(connections),
", ".join([connection_to_str(c) for c in connections]),
)
)
die_usage("Select unique connection to set")
do_set(nmc, connections[0], args["ids_arg"], do_test=args["do_test"])
else:
if len(connections) < 1:
_print("No connection selected for printing the external ids")
die_usage("Select connection to get")
do_get(connections, args["ids_arg"])

View file

@ -43,8 +43,9 @@ libnm_core_headers = files(
'nm-setting-match.h',
'nm-setting-olpc-mesh.h',
'nm-setting-ovs-bridge.h',
'nm-setting-ovs-interface.h',
'nm-setting-ovs-dpdk.h',
'nm-setting-ovs-external-ids.h',
'nm-setting-ovs-interface.h',
'nm-setting-ovs-patch.h',
'nm-setting-ovs-port.h',
'nm-setting-ppp.h',
@ -143,8 +144,9 @@ libnm_core_settings_sources = files(
'nm-setting-match.c',
'nm-setting-olpc-mesh.c',
'nm-setting-ovs-bridge.c',
'nm-setting-ovs-interface.c',
'nm-setting-ovs-dpdk.c',
'nm-setting-ovs-external-ids.c',
'nm-setting-ovs-interface.c',
'nm-setting-ovs-patch.c',
'nm-setting-ovs-port.c',
'nm-setting-ppp.c',

View file

@ -476,6 +476,10 @@ GSList *_nm_vpn_plugin_info_list_load_dir(const char * dirname,
/*****************************************************************************/
GHashTable *_nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *self);
/*****************************************************************************/
typedef struct {
const char *name;
gboolean numeric;

View file

@ -39,6 +39,7 @@ typedef struct _NMSettingMatch NMSettingMatch;
typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh;
typedef struct _NMSettingOvsBridge NMSettingOvsBridge;
typedef struct _NMSettingOvsDpdk NMSettingOvsDpdk;
typedef struct _NMSettingOvsExternalIDs NMSettingOvsExternalIDs;
typedef struct _NMSettingOvsInterface NMSettingOvsInterface;
typedef struct _NMSettingOvsPatch NMSettingOvsPatch;
typedef struct _NMSettingOvsPort NMSettingOvsPort;

View file

@ -24,9 +24,14 @@
#include "nm-core-internal.h"
#include "nm-keyfile.h"
#include "nm-setting-user.h"
#include "nm-setting-ovs-external-ids.h"
#include "nm-keyfile-utils.h"
#define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options"
#define OVS_EXTERNAL_IDS_DATA_PREFIX "data."
/*****************************************************************************/
typedef struct _ParseInfoProperty ParseInfoProperty;
@ -989,6 +994,44 @@ ip_routing_rule_parser_full(KeyfileReaderInfo * info,
}
}
static void
_parser_full_ovs_external_ids_data(KeyfileReaderInfo * info,
const NMMetaSettingInfo * setting_info,
const NMSettInfoProperty *property_info,
const ParseInfoProperty * pip,
NMSetting * setting)
{
const char * setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME;
gs_strfreev char **keys = NULL;
gsize n_keys;
gsize i;
nm_assert(NM_IS_SETTING_OVS_EXTERNAL_IDS(setting));
nm_assert(nm_streq(property_info->name, NM_SETTING_OVS_EXTERNAL_IDS_DATA));
nm_assert(nm_streq(setting_name, setting_info->setting_name));
nm_assert(nm_streq(setting_name, nm_setting_get_name(setting)));
keys = nm_keyfile_plugin_kf_get_keys(info->keyfile, setting_name, &n_keys, NULL);
for (i = 0; i < n_keys; i++) {
const char * key = keys[i];
gs_free char *name_to_free = NULL;
gs_free char *value = NULL;
const char * name;
if (!NM_STR_HAS_PREFIX(key, OVS_EXTERNAL_IDS_DATA_PREFIX))
continue;
value = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL);
if (!value)
continue;
name = &key[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)];
name = nm_keyfile_key_decode(name, &name_to_free);
nm_setting_ovs_external_ids_set_data(NM_SETTING_OVS_EXTERNAL_IDS(setting), name, value);
}
}
static void
ip_dns_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key)
{
@ -2214,8 +2257,6 @@ bridge_vlan_writer(KeyfileWriterInfo *info,
}
}
#define ETHERNET_S390_OPTIONS_GROUP_NAME "ethernet-s390-options"
static void
wired_s390_options_parser_full(KeyfileReaderInfo * info,
const NMMetaSettingInfo * setting_info,
@ -2360,6 +2401,60 @@ tfilter_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, con
}
}
static void
_writer_full_ovs_external_ids_data(KeyfileWriterInfo * info,
const NMMetaSettingInfo * setting_info,
const NMSettInfoProperty *property_info,
const ParseInfoProperty * pip,
NMSetting * setting)
{
GHashTable * hash;
NMUtilsNamedValue data_static[300u / sizeof(NMUtilsNamedValue)];
gs_free NMUtilsNamedValue *data_free = NULL;
const NMUtilsNamedValue * data;
guint data_len;
char full_key_static[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX) + 300u];
guint i;
nm_assert(NM_IS_SETTING_OVS_EXTERNAL_IDS(setting));
nm_assert(nm_streq(property_info->name, NM_SETTING_OVS_EXTERNAL_IDS_DATA));
hash = _nm_setting_ovs_external_ids_get_data(NM_SETTING_OVS_EXTERNAL_IDS(setting));
if (!hash)
return;
data = nm_utils_named_values_from_strdict(hash, &data_len, data_static, &data_free);
if (data_len == 0)
return;
memcpy(full_key_static, OVS_EXTERNAL_IDS_DATA_PREFIX, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX));
for (i = 0; i < data_len; i++) {
const char * key = data[i].name;
const char * val = data[i].value_str;
gs_free char *escaped_key_to_free = NULL;
const char * escaped_key;
gsize len;
gs_free char *full_key_free = NULL;
char * full_key = full_key_static;
escaped_key = nm_keyfile_key_encode(key, &escaped_key_to_free);
len = strlen(escaped_key) + 1u;
if (len >= G_N_ELEMENTS(full_key_static) - NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)) {
full_key_free = g_new(char, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX) + len);
full_key = full_key_free;
memcpy(full_key, OVS_EXTERNAL_IDS_DATA_PREFIX, NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX));
}
memcpy(&full_key[NM_STRLEN(OVS_EXTERNAL_IDS_DATA_PREFIX)], escaped_key, len);
nm_keyfile_plugin_kf_set_string(info->keyfile,
NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME,
full_key,
val);
}
}
static void
write_hash_of_string(GKeyFile *file, NMSetting *setting, const char *key, const GValue *value)
{
@ -2799,6 +2894,14 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
.writer_full = ip_routing_rule_writer_full,
.has_parser_full = TRUE,
.has_writer_full = TRUE, ), ), ),
PARSE_INFO_SETTING(
NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_OVS_EXTERNAL_IDS_DATA,
.parser_no_check_key = TRUE,
.parser_full = _parser_full_ovs_external_ids_data,
.writer_full = _writer_full_ovs_external_ids_data,
.has_parser_full = TRUE,
.has_writer_full = TRUE, ), ), ),
PARSE_INFO_SETTING(NM_META_SETTING_TYPE_SERIAL,
PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_SERIAL_PARITY,
.parser = parity_parser, ), ), ),

View file

@ -98,6 +98,11 @@ gboolean nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type,
/*****************************************************************************/
#define NM_OVS_EXTERNAL_ID_NM_PREFIX "NM."
#define NM_OVS_EXTERNAL_ID_NM_CONNECTION_UUID "NM.connection.uuid"
/*****************************************************************************/
static inline int
nm_setting_ip_config_get_addr_family(NMSettingIPConfig *s_ip)
{

View file

@ -0,0 +1,536 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
/*
* Copyright (C) 2017 - 2020 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ovs-external-ids.h"
#include "nm-setting-private.h"
#include "nm-utils-private.h"
#include "nm-connection-private.h"
#define MAX_NUM_KEYS 256
/*****************************************************************************/
/**
* SECTION:nm-setting-ovs-external-ids
* @short_description: External-IDs for OVS database
*
* The #NMSettingOvsExternalIDs object is a #NMSetting subclass that allow to
* configure external ids for OVS.
**/
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingOvsExternalIDs, PROP_DATA, );
typedef struct {
GHashTable * data;
const char **data_keys;
} NMSettingOvsExternalIDsPrivate;
/**
* NMSettingOvsExternalIDs:
*
* OVS External IDs Settings
*/
struct _NMSettingOvsExternalIDs {
NMSetting parent;
NMSettingOvsExternalIDsPrivate _priv;
};
struct _NMSettingOvsExternalIDsClass {
NMSettingClass parent;
};
G_DEFINE_TYPE(NMSettingOvsExternalIDs, nm_setting_ovs_external_ids, NM_TYPE_SETTING)
#define NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMSettingOvsExternalIDs, NM_IS_SETTING_OVS_EXTERNAL_IDS)
/*****************************************************************************/
static gboolean
_exid_key_char_is_regular(char ch)
{
/* allow words of printable characters, plus some
* special characters, for example to support base64 encoding. */
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')
|| NM_IN_SET(ch, '-', '_', '+', '/', '=', '.');
}
/**
* nm_setting_ovs_external_ids_check_key:
* @key: (allow-none): the key to check
* @error: a #GError, %NULL to ignore.
*
* Checks whether @key is a valid key for OVS' external-ids.
* This means, the key cannot be %NULL, not too large and valid ASCII.
* Also, only digits and numbers are allowed with a few special
* characters. They key must also not start with "NM.".
*
* Since: 1.30
*
* Returns: %TRUE if @key is a valid user data key.
*/
gboolean
nm_setting_ovs_external_ids_check_key(const char *key, GError **error)
{
gsize len;
g_return_val_if_fail(!error || !*error, FALSE);
if (!key || !key[0]) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("missing key"));
return FALSE;
}
len = strlen(key);
if (len > 255u) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("key is too long"));
return FALSE;
}
if (!g_utf8_validate(key, len, NULL)) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("key must be UTF8"));
return FALSE;
}
if (!NM_STRCHAR_ALL(key, ch, _exid_key_char_is_regular(ch))) {
/* Probably OVS is more forgiving about what makes a valid key for
* an external-id. However, we are strict (at least, for now). */
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("key contains invalid characters"));
return FALSE;
}
if (NM_STR_HAS_PREFIX(key, NM_OVS_EXTERNAL_ID_NM_PREFIX)) {
/* these keys are reserved. */
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("key cannot start with \"NM.\""));
return FALSE;
}
return TRUE;
}
/**
* nm_setting_ovs_external_ids_check_val:
* @val: (allow-none): the value to check
* @error: a #GError, %NULL to ignore.
*
* Checks whether @val is a valid user data value. This means,
* value is not %NULL, not too large and valid UTF-8.
*
* Since: 1.30
*
* Returns: %TRUE if @val is a valid user data value.
*/
gboolean
nm_setting_ovs_external_ids_check_val(const char *val, GError **error)
{
gsize len;
g_return_val_if_fail(!error || !*error, FALSE);
if (!val) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("value is missing"));
return FALSE;
}
len = strlen(val);
if (len > (8u * 1024u)) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("value is too large"));
return FALSE;
}
if (!g_utf8_validate(val, len, NULL)) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("value is not valid UTF8"));
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static GHashTable *
_create_data_hash(void)
{
return g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
}
GHashTable *
_nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *self)
{
return NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self)->data;
}
/**
* nm_setting_ovs_external_ids_get_data_keys:
* @setting: the #NMSettingOvsExternalIDs
* @out_len: (out): the length of the returned array
*
* Returns: (array length=out_len) (transfer none): a
* %NULL-terminated array containing each key from the table.
**/
const char *const *
nm_setting_ovs_external_ids_get_data_keys(NMSettingOvsExternalIDs *setting, guint *out_len)
{
NMSettingOvsExternalIDs * self = setting;
NMSettingOvsExternalIDsPrivate *priv;
g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL);
priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
if (priv->data_keys) {
NM_SET_OUT(out_len, g_hash_table_size(priv->data));
return priv->data_keys;
}
priv->data_keys = nm_utils_strdict_get_keys(priv->data, TRUE, out_len);
/* don't return %NULL, but hijack the @data_keys fields as a pseudo
* empty strv array. */
return priv->data_keys ?: ((const char **) &priv->data_keys);
}
/*****************************************************************************/
/**
* nm_setting_ovs_external_ids_get_data:
* @setting: the #NMSettingOvsExternalIDs instance
* @key: the external-id to lookup
*
* Since: 1.30
*
* Returns: (transfer none): the value associated with @key or %NULL if no such
* value exists.
*/
const char *
nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *setting, const char *key)
{
NMSettingOvsExternalIDs * self = setting;
NMSettingOvsExternalIDsPrivate *priv;
g_return_val_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self), NULL);
g_return_val_if_fail(key, NULL);
priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
if (!priv->data)
return NULL;
return g_hash_table_lookup(priv->data, key);
}
/**
* nm_setting_ovs_external_ids_set_data:
* @setting: the #NMSettingOvsExternalIDs instance
* @key: the key to set
* @val: (allow-none): the value to set or %NULL to clear a key.
*
* Since: 1.30
*/
void
nm_setting_ovs_external_ids_set_data(NMSettingOvsExternalIDs *setting,
const char * key,
const char * val)
{
NMSettingOvsExternalIDs * self = setting;
NMSettingOvsExternalIDsPrivate *priv;
g_return_if_fail(NM_IS_SETTING_OVS_EXTERNAL_IDS(self));
priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
if (!val) {
if (priv->data && g_hash_table_remove(priv->data, key))
goto out_changed;
return;
}
if (priv->data) {
const char *val2;
if (g_hash_table_lookup_extended(priv->data, key, NULL, (gpointer *) &val2)) {
if (nm_streq(val, val2))
return;
}
} else
priv->data = _create_data_hash();
g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val));
out_changed:
nm_clear_g_free(&priv->data_keys);
_notify(self, PROP_DATA);
}
/*****************************************************************************/
static gboolean
verify(NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(setting);
NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
if (priv->data) {
gs_free_error GError *local = NULL;
GHashTableIter iter;
const char * key;
const char * val;
g_hash_table_iter_init(&iter, priv->data);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) {
if (!nm_setting_ovs_external_ids_check_key(key, &local)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_FAILED,
_("invalid key \"%s\": %s"),
key,
local->message);
} else if (!nm_setting_ovs_external_ids_check_val(val, &local)) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_FAILED,
_("invalid value for \"%s\": %s"),
key,
local->message);
} else
continue;
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME,
NM_SETTING_OVS_EXTERNAL_IDS_DATA);
return FALSE;
}
}
if (priv->data && g_hash_table_size(priv->data) > MAX_NUM_KEYS) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("maximum number of user data entries reached (%u instead of %u)"),
g_hash_table_size(priv->data),
(unsigned) MAX_NUM_KEYS);
g_prefix_error(error,
"%s.%s: ",
NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME,
NM_SETTING_OVS_EXTERNAL_IDS_DATA);
return FALSE;
}
if (connection) {
const char *type;
type = nm_connection_get_connection_type(connection);
if (!type) {
NMSetting *s_base;
s_base = _nm_connection_find_base_type_setting(connection);
if (s_base)
type = nm_setting_get_name(s_base);
}
if (!NM_IN_STRSET(type,
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
g_set_error_literal(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("OVS external IDs can only be added to a profile of type OVS "
"bridge/port/interface"));
return FALSE;
}
}
return TRUE;
}
static NMTernary
compare_property(const NMSettInfoSetting *sett_info,
guint property_idx,
NMConnection * con_a,
NMSetting * set_a,
NMConnection * con_b,
NMSetting * set_b,
NMSettingCompareFlags flags)
{
NMSettingOvsExternalIDsPrivate *priv;
NMSettingOvsExternalIDsPrivate *pri2;
if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_OVS_EXTERNAL_IDS_DATA)) {
if (NM_FLAGS_HAS(flags, NM_SETTING_COMPARE_FLAG_INFERRABLE))
return NM_TERNARY_DEFAULT;
if (!set_b)
return TRUE;
priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_a));
pri2 = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(NM_SETTING_OVS_EXTERNAL_IDS(set_b));
return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal);
}
return NM_SETTING_CLASS(nm_setting_ovs_external_ids_parent_class)
->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags);
}
/*****************************************************************************/
static void
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object);
NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
GHashTableIter iter;
GHashTable * data;
const char * key;
const char * val;
switch (prop_id) {
case PROP_DATA:
data = _create_data_hash();
if (priv->data) {
g_hash_table_iter_init(&iter, priv->data);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val))
g_hash_table_insert(data, g_strdup(key), g_strdup(val));
}
g_value_take_boxed(value, data);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object);
NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
switch (prop_id) {
case PROP_DATA:
{
gs_unref_hashtable GHashTable *old = NULL;
GHashTableIter iter;
GHashTable * data;
const char * key;
const char * val;
nm_clear_g_free(&priv->data_keys);
old = g_steal_pointer(&priv->data);
data = g_value_get_boxed(value);
if (nm_g_hash_table_size(data) <= 0)
return;
priv->data = _create_data_hash();
g_hash_table_iter_init(&iter, data);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val))
g_hash_table_insert(priv->data, g_strdup(key), g_strdup(val));
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_setting_ovs_external_ids_init(NMSettingOvsExternalIDs *self)
{}
/**
* nm_setting_ovs_external_ids_new:
*
* Creates a new #NMSettingOvsExternalIDs object with default values.
*
* Returns: (transfer full) (type NMSettingOvsExternalIDs): the new empty
* #NMSettingOvsExternalIDs object
*
* Since: 1.30
*/
gpointer
nm_setting_ovs_external_ids_new(void)
{
return g_object_new(NM_TYPE_SETTING_OVS_EXTERNAL_IDS, NULL);
}
static void
finalize(GObject *object)
{
NMSettingOvsExternalIDs * self = NM_SETTING_OVS_EXTERNAL_IDS(object);
NMSettingOvsExternalIDsPrivate *priv = NM_SETTING_OVS_EXTERNAL_IDS_GET_PRIVATE(self);
g_free(priv->data_keys);
if (priv->data)
g_hash_table_unref(priv->data);
G_OBJECT_CLASS(nm_setting_ovs_external_ids_parent_class)->finalize(object);
}
static void
nm_setting_ovs_external_ids_class_init(NMSettingOvsExternalIDsClass *klass)
{
GObjectClass * object_class = G_OBJECT_CLASS(klass);
NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
GArray * properties_override = _nm_sett_info_property_override_create_array();
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->finalize = finalize;
setting_class->compare_property = compare_property;
setting_class->verify = verify;
/**
* NMSettingOvsExternalIDs:data: (type GHashTable(utf8,utf8))
*
* A dictionary of key/value pairs with exernal-ids for OVS.
*
* Since: 1.30
**/
obj_properties[PROP_DATA] = g_param_spec_boxed(NM_SETTING_OVS_EXTERNAL_IDS_DATA,
"",
"",
G_TYPE_HASH_TABLE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
_nm_properties_override_gobj(properties_override,
obj_properties[PROP_DATA],
&nm_sett_info_propert_type_strdict);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit_full(setting_class,
NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
NULL,
properties_override);
}

View file

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
/*
* Copyright (C) 2017 - 2020 Red Hat, Inc.
*/
#ifndef __NM_SETTING_OVS_EXTERNAL_IDS_H__
#define __NM_SETTING_OVS_EXTERNAL_IDS_H__
#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_OVS_EXTERNAL_IDS (nm_setting_ovs_external_ids_get_type())
#define NM_SETTING_OVS_EXTERNAL_IDS(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_OVS_EXTERNAL_IDS, NMSettingOvsExternalIDs))
#define NM_SETTING_OVS_EXTERNAL_IDS_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), \
NM_TYPE_SETTING_OVS_EXTERNAL_IDS, \
NMSettingOvsExternalIDsClass))
#define NM_IS_SETTING_OVS_EXTERNAL_IDS(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_OVS_EXTERNAL_IDS))
#define NM_IS_SETTING_OVS_EXTERNAL_IDS_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_OVS_EXTERNAL_IDS))
#define NM_SETTING_OVS_EXTERNAL_IDS_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), \
NM_TYPE_SETTING_OVS_EXTERNAL_IDS, \
NMSettingOvsExternalIDsClass))
#define NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME "ovs-external-ids"
#define NM_SETTING_OVS_EXTERNAL_IDS_DATA "data"
typedef struct _NMSettingOvsExternalIDsClass NMSettingOvsExternalIDsClass;
NM_AVAILABLE_IN_1_30
GType nm_setting_ovs_external_ids_get_type(void);
NM_AVAILABLE_IN_1_30
void *nm_setting_ovs_external_ids_new(void);
/*****************************************************************************/
NM_AVAILABLE_IN_1_30
const char *const *nm_setting_ovs_external_ids_get_data_keys(NMSettingOvsExternalIDs *setting,
guint * out_len);
NM_AVAILABLE_IN_1_30
const char *nm_setting_ovs_external_ids_get_data(NMSettingOvsExternalIDs *setting, const char *key);
NM_AVAILABLE_IN_1_30
void nm_setting_ovs_external_ids_set_data(NMSettingOvsExternalIDs *setting,
const char * key,
const char * val);
/*****************************************************************************/
NM_AVAILABLE_IN_1_30
gboolean nm_setting_ovs_external_ids_check_key(const char *key, GError **error);
NM_AVAILABLE_IN_1_30
gboolean nm_setting_ovs_external_ids_check_val(const char *val, GError **error);
G_END_DECLS
#endif /* __NM_SETTING_OVS_EXTERNAL_IDS_H__ */

View file

@ -288,7 +288,7 @@ nm_setting_user_set_data(NMSettingUser *setting, const char *key, const char *va
NMSettingUserPrivate *priv;
gboolean changed = FALSE;
g_return_val_if_fail(NM_IS_SETTING(self), FALSE);
g_return_val_if_fail(NM_IS_SETTING_USER(self), FALSE);
g_return_val_if_fail(!error || !*error, FALSE);
if (!nm_setting_user_check_key(key, error))
@ -416,11 +416,11 @@ compare_property(const NMSettInfoSetting *sett_info,
priv = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_a));
pri2 = NM_SETTING_USER_GET_PRIVATE(NM_SETTING_USER(set_b));
return nm_utils_hash_table_equal(priv->data, pri2->data, TRUE, g_str_equal)
&& nm_utils_hash_table_equal(priv->data_invalid,
pri2->data_invalid,
TRUE,
g_str_equal);
return nm_utils_hashtable_equal(priv->data, pri2->data, TRUE, g_str_equal)
&& nm_utils_hashtable_equal(priv->data_invalid,
pri2->data_invalid,
TRUE,
g_str_equal);
}
return NM_SETTING_CLASS(nm_setting_user_parent_class)

View file

@ -1481,10 +1481,10 @@ _nm_setting_compare(NMConnection * con_a,
GenData *a_gendata = _gendata_hash(a, FALSE);
GenData *b_gendata = _gendata_hash(b, FALSE);
return nm_utils_hash_table_equal(a_gendata ? a_gendata->hash : NULL,
b_gendata ? b_gendata->hash : NULL,
TRUE,
g_variant_equal);
return nm_utils_hashtable_equal(a_gendata ? a_gendata->hash : NULL,
b_gendata ? b_gendata->hash : NULL,
TRUE,
g_variant_equal);
}
for (i = 0; i < sett_info->property_infos_len; i++) {

View file

@ -1766,4 +1766,12 @@ global:
nm_keyfile_read;
nm_keyfile_warn_severity_get_type;
nm_keyfile_write;
nm_setting_ovs_external_ids_check_key;
nm_setting_ovs_external_ids_check_val;
nm_setting_ovs_external_ids_get_data;
nm_setting_ovs_external_ids_get_data_keys;
nm_setting_ovs_external_ids_get_type;
nm_setting_ovs_external_ids_new;
nm_setting_ovs_external_ids_set_data;
nm_utils_print;
} libnm_1_28_0;

View file

@ -480,6 +480,11 @@ void nm_client_dbus_set_property(NMClient * client,
NM_AVAILABLE_IN_1_24
gboolean nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *result, GError **error);
/*****************************************************************************/
NM_AVAILABLE_IN_1_30
void nm_utils_print(int output_mode, const char *msg);
G_END_DECLS
#endif /* __NM_CLIENT_H__ */

View file

@ -869,3 +869,42 @@ nm_utils_g_param_spec_is_default(const GParamSpec *pspec)
* strictly asserts and only support argument types that we expect. */
g_return_val_if_reached(FALSE);
}
/*****************************************************************************/
/**
* nm_utils_print:
* @output_mode: if 1 it uses g_print(). If 2, it uses g_printerr().
* If 0, it uses either g_print() or g_printerr(), depending
* on LIBNM_CLIENT_DEBUG (and the "stdout" flag).
* @msg: the message to print. The function does not append
* a trailing newline.
*
* The only purpose of this function is to give access to g_print()
* or g_printerr() from pygobject. libnm can do debug logging by
* setting LIBNM_CLIENT_DEBUG and uses thereby g_printerr() or
* g_print(). A plain "print()" function in python is not in sync
* with these functions (it implements additional buffering). By
* using nm_utils_print(), the same logging mechanisms can be used.
*
* Since: 1.30
*/
void
nm_utils_print(int output_mode, const char *msg)
{
gboolean use_stdout;
g_return_if_fail(msg);
if (output_mode == 0) {
nml_dbus_log_enabled_full(NML_DBUS_LOG_LEVEL_ANY, &use_stdout);
output_mode = use_stdout ? 1 : 2;
}
if (output_mode == 1)
g_print("%s", msg);
else if (output_mode == 2)
g_printerr("%s", msg);
else
g_return_if_reached();
}

View file

@ -82,6 +82,7 @@ libnm-core/nm-setting-macvlan.c
libnm-core/nm-setting-match.c
libnm-core/nm-setting-olpc-mesh.c
libnm-core/nm-setting-ovs-bridge.c
libnm-core/nm-setting-ovs-external-ids.c
libnm-core/nm-setting-ovs-interface.c
libnm-core/nm-setting-ovs-patch.c
libnm-core/nm-setting-ovs-port.c

View file

@ -434,6 +434,24 @@ nm_g_variant_singleton_u_0(void)
/*****************************************************************************/
GHashTable *
nm_utils_strdict_clone(GHashTable *src)
{
GHashTable * dst;
GHashTableIter iter;
const char * key;
const char * val;
if (!src)
return NULL;
dst = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
g_hash_table_iter_init(&iter, src);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val))
g_hash_table_insert(dst, g_strdup(key), g_strdup(val));
return dst;
}
/* Convert a hash table with "char *" keys and values to an "a{ss}" GVariant.
* The keys will be sorted asciibetically.
* Returns a floating reference.
@ -3066,6 +3084,18 @@ nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_poll)
/*****************************************************************************/
void
nm_utils_named_value_clear_with_g_free(NMUtilsNamedValue *val)
{
if (val) {
gs_free gpointer x_name = NULL;
gs_free gpointer x_value = NULL;
x_name = (gpointer) g_steal_pointer(&val->name);
x_value = g_steal_pointer(&val->value_ptr);
}
}
G_STATIC_ASSERT(G_STRUCT_OFFSET(NMUtilsNamedValue, name) == 0);
NMUtilsNamedValue *
@ -3262,6 +3292,62 @@ nm_utils_hash_values_to_array(GHashTable * hash,
return arr;
}
/*****************************************************************************/
/**
* nm_utils_hashtable_equal:
* @a: one #GHashTable
* @b: other #GHashTable
* @treat_null_as_empty: if %TRUE, when either @a or @b is %NULL, it is
* treated like an empty hash. It means, a %NULL hash will compare equal
* to an empty hash.
* @equal_func: the equality function, for comparing the values.
* If %NULL, the values are not compared. In that case, the function
* only checks, if both dictionaries have the same keys -- according
* to @b's key equality function.
* Note that the values of @a will be passed as first argument
* to @equal_func.
*
* Compares two hash tables, whether they have equal content.
* This only makes sense, if @a and @b have the same key types and
* the same key compare-function.
*
* Returns: %TRUE, if both dictionaries have the same content.
*/
gboolean
nm_utils_hashtable_equal(const GHashTable *a,
const GHashTable *b,
gboolean treat_null_as_empty,
GEqualFunc equal_func)
{
guint n;
GHashTableIter iter;
gconstpointer key, v_a, v_b;
if (a == b)
return TRUE;
if (!treat_null_as_empty) {
if (!a || !b)
return FALSE;
}
n = a ? g_hash_table_size((GHashTable *) a) : 0;
if (n != (b ? g_hash_table_size((GHashTable *) b) : 0))
return FALSE;
if (n > 0) {
g_hash_table_iter_init(&iter, (GHashTable *) a);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &v_a)) {
if (!g_hash_table_lookup_extended((GHashTable *) b, key, NULL, (gpointer *) &v_b))
return FALSE;
if (equal_func && !equal_func(v_a, v_b))
return FALSE;
}
}
return TRUE;
}
static gboolean
_utils_hashtable_equal(GHashTable * hash_a,
GHashTable * hash_b,
@ -3301,7 +3387,7 @@ _utils_hashtable_equal(GHashTable * hash_a,
}
/**
* nm_utils_hashtable_equal:
* nm_utils_hashtable_cmp_equal:
* @a: (allow-none): the hash table or %NULL
* @b: (allow-none): the other hash table or %NULL
* @cmp_values: (allow-none): if %NULL, only the keys
@ -3316,10 +3402,10 @@ _utils_hashtable_equal(GHashTable * hash_a,
* @cmp_values is given) all values are the same.
*/
gboolean
nm_utils_hashtable_equal(const GHashTable *a,
const GHashTable *b,
GCompareDataFunc cmp_values,
gpointer user_data)
nm_utils_hashtable_cmp_equal(const GHashTable *a,
const GHashTable *b,
GCompareDataFunc cmp_values,
gpointer user_data)
{
GHashTable *hash_a = (GHashTable *) a;
GHashTable *hash_b = (GHashTable *) b;
@ -3374,7 +3460,7 @@ _hashtable_cmp_func(gconstpointer a, gconstpointer b, gpointer user_data)
* @a: (allow-none): the hash to compare. May be %NULL.
* @b: (allow-none): the other hash to compare. May be %NULL.
* @do_fast_precheck: if %TRUE, assume that the hashes are equal
* and that it is worth calling nm_utils_hashtable_equal() first.
* and that it is worth calling nm_utils_hashtable_cmp_equal() first.
* That requires, that both hashes have the same equals function
* which is compatible with the @cmp_keys function.
* @cmp_keys: the compare function for keys. Usually, the hash/equal function
@ -3826,62 +3912,6 @@ nm_utils_array_find_binary_search(gconstpointer list,
/*****************************************************************************/
/**
* nm_utils_hash_table_equal:
* @a: one #GHashTable
* @b: other #GHashTable
* @treat_null_as_empty: if %TRUE, when either @a or @b is %NULL, it is
* treated like an empty hash. It means, a %NULL hash will compare equal
* to an empty hash.
* @equal_func: the equality function, for comparing the values.
* If %NULL, the values are not compared. In that case, the function
* only checks, if both dictionaries have the same keys -- according
* to @b's key equality function.
* Note that the values of @a will be passed as first argument
* to @equal_func.
*
* Compares two hash tables, whether they have equal content.
* This only makes sense, if @a and @b have the same key types and
* the same key compare-function.
*
* Returns: %TRUE, if both dictionaries have the same content.
*/
gboolean
nm_utils_hash_table_equal(const GHashTable * a,
const GHashTable * b,
gboolean treat_null_as_empty,
NMUtilsHashTableEqualFunc equal_func)
{
guint n;
GHashTableIter iter;
gconstpointer key, v_a, v_b;
if (a == b)
return TRUE;
if (!treat_null_as_empty) {
if (!a || !b)
return FALSE;
}
n = a ? g_hash_table_size((GHashTable *) a) : 0;
if (n != (b ? g_hash_table_size((GHashTable *) b) : 0))
return FALSE;
if (n > 0) {
g_hash_table_iter_init(&iter, (GHashTable *) a);
while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &v_a)) {
if (!g_hash_table_lookup_extended((GHashTable *) b, key, NULL, (gpointer *) &v_b))
return FALSE;
if (equal_func && !equal_func(v_a, v_b))
return FALSE;
}
}
return TRUE;
}
/*****************************************************************************/
/**
* nm_utils_get_start_time_for_pid:
* @pid: the process identifier

View file

@ -320,6 +320,8 @@ gboolean nm_utils_gbytes_equal_mem(GBytes *bytes, gconstpointer mem_data, gsize
GVariant *nm_utils_gbytes_to_variant_ay(GBytes *bytes);
GHashTable *nm_utils_strdict_clone(GHashTable *src);
GVariant *nm_utils_strdict_to_variant_ass(GHashTable *strdict);
GVariant *nm_utils_strdict_to_variant_asv(GHashTable *strdict);
@ -1460,6 +1462,8 @@ void nm_utils_named_value_list_sort(NMUtilsNamedValue *arr,
GCompareDataFunc compare_func,
gpointer user_data);
void nm_utils_named_value_clear_with_g_free(NMUtilsNamedValue *val);
/*****************************************************************************/
gpointer *nm_utils_hash_keys_to_array(GHashTable * hash,
@ -1483,13 +1487,18 @@ nm_utils_strdict_get_keys(const GHashTable *hash, gboolean sorted, guint *out_le
gboolean nm_utils_hashtable_equal(const GHashTable *a,
const GHashTable *b,
GCompareDataFunc cmp_values,
gpointer user_data);
gboolean treat_null_as_empty,
GEqualFunc equal_func);
gboolean nm_utils_hashtable_cmp_equal(const GHashTable *a,
const GHashTable *b,
GCompareDataFunc cmp_values,
gpointer user_data);
static inline gboolean
nm_utils_hashtable_same_keys(const GHashTable *a, const GHashTable *b)
{
return nm_utils_hashtable_equal(a, b, NULL, NULL);
return nm_utils_hashtable_cmp_equal(a, b, NULL, NULL);
}
int nm_utils_hashtable_cmp(const GHashTable *a,
@ -1534,6 +1543,13 @@ nm_g_array_len(const GArray *arr)
return arr ? arr->len : 0u;
}
static inline void
nm_g_array_unref(GArray *arr)
{
if (arr)
g_array_unref(arr);
}
#define nm_g_array_append_new(arr, type) \
({ \
GArray *const _arr = (arr); \
@ -1689,15 +1705,6 @@ gssize nm_utils_array_find_binary_search(gconstpointer list,
/*****************************************************************************/
typedef gboolean (*NMUtilsHashTableEqualFunc)(gconstpointer a, gconstpointer b);
gboolean nm_utils_hash_table_equal(const GHashTable * a,
const GHashTable * b,
gboolean treat_null_as_empty,
NMUtilsHashTableEqualFunc equal_func);
/*****************************************************************************/
void _nm_utils_strv_sort(const char **strv, gssize len);
#define nm_utils_strv_sort(strv, len) _nm_utils_strv_sort(NM_CAST_STRV_MC(strv), len)
@ -2204,6 +2211,25 @@ nm_utils_strdup_reset(char **dst, const char *src)
return TRUE;
}
static inline gboolean
nm_utils_strdup_reset_take(char **dst, char *src)
{
char *old;
nm_assert(dst);
nm_assert(src != *dst);
if (nm_streq0(*dst, src)) {
if (src)
g_free(src);
return FALSE;
}
old = *dst;
*dst = src;
g_free(old);
return TRUE;
}
void nm_indirect_g_free(gpointer arg);
/*****************************************************************************/

View file

@ -31,7 +31,7 @@ typedef struct _NMStrBuf {
/*****************************************************************************/
static inline void
_nm_str_buf_assert(NMStrBuf *strbuf)
_nm_str_buf_assert(const NMStrBuf *strbuf)
{
nm_assert(strbuf);
nm_assert((!!strbuf->_priv_str) == (strbuf->_priv_allocated > 0));
@ -361,6 +361,31 @@ nm_str_buf_get_str_unsafe(NMStrBuf *strbuf)
return strbuf->_priv_str;
}
static inline char *
nm_str_buf_get_str_at_unsafe(NMStrBuf *strbuf, gsize index)
{
_nm_str_buf_assert(strbuf);
/* it is acceptable to ask for a pointer at the end of the buffer -- even
* if there is no data there. The caller is anyway required to take care
* of the length (that's the "unsafe" part), and in that case, the length
* is merely zero. */
nm_assert(index <= strbuf->allocated);
if (!strbuf->_priv_str)
return NULL;
return &strbuf->_priv_str[index];
}
static inline char
nm_str_buf_get_char(const NMStrBuf *strbuf, gsize index)
{
_nm_str_buf_assert(strbuf);
nm_assert(index < strbuf->allocated);
return strbuf->_priv_str[index];
}
/**
* nm_str_buf_finalize:
* @strbuf: an initilized #NMStrBuf

View file

@ -1190,8 +1190,8 @@ test_utils_hashtable_cmp(void)
}
g_assert(nm_utils_hashtable_same_keys(h1, h2));
g_assert(nm_utils_hashtable_equal(h1, h2, NULL, NULL));
g_assert(nm_utils_hashtable_equal(h1, h2, func_val_cmp, NULL));
g_assert(nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL));
g_assert(nm_utils_hashtable_cmp_equal(h1, h2, func_val_cmp, NULL));
g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) == 0);
g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) == 0);
g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, func_val_cmp, NULL) == 0);
@ -1221,16 +1221,16 @@ again:
if (has_same_keys) {
g_assert(nm_utils_hashtable_same_keys(h1, h2));
g_assert(nm_utils_hashtable_equal(h1, h2, NULL, NULL));
g_assert(nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL));
g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) == 0);
g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) == 0);
} else {
g_assert(!nm_utils_hashtable_same_keys(h1, h2));
g_assert(!nm_utils_hashtable_equal(h1, h2, NULL, NULL));
g_assert(!nm_utils_hashtable_cmp_equal(h1, h2, NULL, NULL));
g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, NULL, NULL) != 0);
g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, NULL, NULL) != 0);
}
g_assert(!nm_utils_hashtable_equal(h1, h2, func_val_cmp, NULL));
g_assert(!nm_utils_hashtable_cmp_equal(h1, h2, func_val_cmp, NULL));
g_assert(nm_utils_hashtable_cmp(h1, h2, FALSE, func_key_cmp, func_val_cmp, NULL) != 0);
g_assert(nm_utils_hashtable_cmp(h1, h2, TRUE, func_key_cmp, func_val_cmp, NULL) != 0);
}

View file

@ -33,6 +33,7 @@
#include "nm-setting-ovs-bridge.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-dpdk.h"
#include "nm-setting-ovs-external-ids.h"
#include "nm-setting-ovs-patch.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ppp.h"
@ -312,6 +313,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_OVS_DPDK_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_dpdk_get_type,
},
[NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS] =
{
.meta_type = NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
.setting_priority = NM_SETTING_PRIORITY_AUX,
.setting_name = NM_SETTING_OVS_EXTERNAL_IDS_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_external_ids_get_type,
},
[NM_META_SETTING_TYPE_OVS_INTERFACE] =
{
.meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE,

View file

@ -128,6 +128,7 @@ typedef enum {
NM_META_SETTING_TYPE_MATCH,
NM_META_SETTING_TYPE_OVS_BRIDGE,
NM_META_SETTING_TYPE_OVS_DPDK,
NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
NM_META_SETTING_TYPE_OVS_INTERFACE,
NM_META_SETTING_TYPE_OVS_PATCH,
NM_META_SETTING_TYPE_OVS_PORT,

View file

@ -23,8 +23,8 @@
#include "nm-setting-adsl.h"
#include "nm-utils.h"
#define _NMLOG_DEVICE_TYPE NMDeviceAdsl
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceAdsl);
/*****************************************************************************/

View file

@ -30,8 +30,8 @@
#include "devices/wwan/nm-modem-manager.h"
#include "devices/wwan/nm-modem.h"
#define _NMLOG_DEVICE_TYPE NMDeviceBt
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceBt);
/*****************************************************************************/

View file

@ -14,8 +14,8 @@
#include "nm-setting-6lowpan.h"
#include "nm-utils.h"
#define _NMLOG_DEVICE_TYPE NMDevice6Lowpan
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDevice6Lowpan);
/*****************************************************************************/

View file

@ -17,8 +17,8 @@
#include "nm-core-internal.h"
#include "nm-ip4-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceBond
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceBond);
/*****************************************************************************/

View file

@ -15,8 +15,8 @@
#include "nm-device-factory.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceBridge
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceBridge);
/*****************************************************************************/

View file

@ -18,8 +18,8 @@
#include "nm-setting-dummy.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceDummy
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceDummy);
/*****************************************************************************/

View file

@ -35,8 +35,8 @@
#include "NetworkManagerUtils.h"
#include "nm-udev-aux/nm-udev-utils.h"
#define _NMLOG_DEVICE_TYPE NMDeviceEthernet
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceEthernet);
/*****************************************************************************/

View file

@ -22,8 +22,8 @@
#include "nm-act-request.h"
#include "nm-ip4-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceIPTunnel
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceIPTunnel);
/*****************************************************************************/

View file

@ -8,36 +8,40 @@
#include "nm-device.h"
#define _LOG_DECLARE_SELF(t) \
_nm_unused static inline NMDevice *_nm_device_log_self_to_device(t *self) \
{ \
return (NMDevice *) self; \
}
#if !_NM_CC_SUPPORT_GENERIC
#define _NM_DEVICE_CAST(self) ((NMDevice *) (self))
#elif !defined(_NMLOG_DEVICE_TYPE)
#define _NM_DEVICE_CAST(self) _NM_ENSURE_TYPE(NMDevice *, self)
#else
#define _NM_DEVICE_CAST(self) \
_Generic((self), _NMLOG_DEVICE_TYPE * \
: ((NMDevice *) (self)), NMDevice * \
: ((NMDevice *) (self)))
#endif
#undef _NMLOG_ENABLED
#define _NMLOG_ENABLED(level, domain) (nm_logging_enabled((level), (domain)))
#define _NMLOG(level, domain, ...) \
G_STMT_START \
{ \
const NMLogLevel _level = (level); \
const NMLogDomain _domain = (domain); \
\
if (nm_logging_enabled(_level, _domain)) { \
typeof(*self) *const _self = (self); \
const char *const _ifname = \
_nm_device_get_iface(_nm_device_log_self_to_device(_self)); \
\
nm_log_obj(_level, \
_domain, \
_ifname, \
NULL, \
_self, \
"device", \
"%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
NM_PRINT_FMT_QUOTED(_ifname, "(", _ifname, ")", "[null]") \
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} \
} \
#define _NMLOG(level, domain, ...) \
G_STMT_START \
{ \
const NMLogLevel _level = (level); \
const NMLogDomain _domain = (domain); \
\
if (nm_logging_enabled(_level, _domain)) { \
typeof(*self) *const _self = (self); \
const char *const _ifname = _nm_device_get_iface(_NM_DEVICE_CAST(_self)); \
\
nm_log_obj(_level, \
_domain, \
_ifname, \
NULL, \
_self, \
"device", \
"%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
NM_PRINT_FMT_QUOTED(_ifname, "(", _ifname, ")", "[null]") \
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} \
} \
G_STMT_END
#endif /* __NETWORKMANAGER_DEVICE_LOGGING_H__ */

View file

@ -18,8 +18,8 @@
#include "supplicant/nm-supplicant-interface.h"
#include "supplicant/nm-supplicant-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceMacsec
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceMacsec);
/*****************************************************************************/

View file

@ -21,8 +21,8 @@
#include "nm-ip4-config.h"
#include "nm-utils.h"
#define _NMLOG_DEVICE_TYPE NMDeviceMacvlan
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceMacvlan);
/*****************************************************************************/

View file

@ -18,8 +18,8 @@
#include "ppp/nm-ppp-manager-call.h"
#include "ppp/nm-ppp-status.h"
#define _NMLOG_DEVICE_TYPE NMDevicePpp
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDevicePpp);
/*****************************************************************************/

View file

@ -19,8 +19,8 @@
#include "nm-setting-tun.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceTun
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceTun);
/*****************************************************************************/

View file

@ -13,8 +13,8 @@
#include "platform/nm-platform.h"
#include "nm-device-factory.h"
#define _NMLOG_DEVICE_TYPE NMDeviceVeth
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceVeth);
/*****************************************************************************/

View file

@ -22,8 +22,8 @@
#include "nm-core-internal.h"
#include "platform/nmp-object.h"
#define _NMLOG_DEVICE_TYPE NMDeviceVlan
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceVlan);
/*****************************************************************************/

View file

@ -12,8 +12,8 @@
#include "platform/nm-platform.h"
#include "settings/nm-settings.h"
#define _NMLOG_DEVICE_TYPE NMDeviceVrf
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceVrf);
/*****************************************************************************/

View file

@ -19,8 +19,8 @@
#include "nm-ip4-config.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceVxlan
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceVxlan);
/*****************************************************************************/

View file

@ -22,8 +22,8 @@
#include "nm-act-request.h"
#include "dns/nm-dns-manager.h"
#define _NMLOG_DEVICE_TYPE NMDeviceWireGuard
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceWireGuard);
/*****************************************************************************/

View file

@ -20,8 +20,8 @@
#include "nm-setting-wpan.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceWpan
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceWpan);
/*****************************************************************************/

View file

@ -74,7 +74,6 @@
#include "nm-device-wireguard.h"
#include "nm-device-logging.h"
_LOG_DECLARE_SELF(NMDevice);
/*****************************************************************************/
@ -12388,28 +12387,34 @@ can_reapply_change(NMDevice * self,
NM_SETTING_CONNECTION_LLDP,
NM_SETTING_CONNECTION_MDNS,
NM_SETTING_CONNECTION_LLMNR);
} else if (NM_IN_STRSET(setting_name,
NM_SETTING_USER_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME)) {
return TRUE;
} else if (nm_streq(setting_name, NM_SETTING_WIRED_SETTING_NAME)
&& NM_IN_SET(NM_DEVICE_GET_CLASS(self)->get_configured_mtu,
nm_device_get_configured_mtu_wired_parent,
nm_device_get_configured_mtu_for_wired)) {
return nm_device_hash_check_invalid_keys(diffs,
NM_SETTING_WIRED_SETTING_NAME,
error,
NM_SETTING_WIRED_MTU);
} else {
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply any changes to '%s' setting",
setting_name);
return FALSE;
}
if (NM_IN_STRSET(setting_name,
NM_SETTING_USER_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME))
return TRUE;
if (nm_streq(setting_name, NM_SETTING_WIRED_SETTING_NAME)) {
if (NM_IN_SET(NM_DEVICE_GET_CLASS(self)->get_configured_mtu,
nm_device_get_configured_mtu_wired_parent,
nm_device_get_configured_mtu_for_wired)) {
return nm_device_hash_check_invalid_keys(diffs,
NM_SETTING_WIRED_SETTING_NAME,
error,
NM_SETTING_WIRED_MTU);
}
goto out_fail;
}
out_fail:
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
"Can't reapply any changes to '%s' setting",
setting_name);
return FALSE;
}
static void
@ -12552,6 +12557,8 @@ check_and_reapply_connection(NMDevice * self,
con_old = applied_clone = nm_simple_connection_new_clone(applied);
con_new = applied;
/* FIXME(applied-connection-immutable): we should not modify the applied
* connection but replace it with a new (immutable) instance. */
nm_connection_replace_settings_from_connection(applied, connection_clean);
nm_connection_clear_secrets(applied);
} else

View file

@ -14,8 +14,8 @@
#include "nm-setting-connection.h"
#include "nm-setting-ovs-bridge.h"
#define _NMLOG_DEVICE_TYPE NMDeviceOvsBridge
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsBridge);
/*****************************************************************************/

View file

@ -14,8 +14,8 @@
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-port.h"
#define _NMLOG_DEVICE_TYPE NMDeviceOvsInterface
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsInterface);
/*****************************************************************************/

View file

@ -15,8 +15,8 @@
#include "nm-setting-ovs-port.h"
#include "nm-setting-ovs-port.h"
#define _NMLOG_DEVICE_TYPE NMDeviceOvsPort
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsPort);
/*****************************************************************************/

View file

@ -106,12 +106,10 @@ new_device_from_type(const char *name, NMDeviceType device_type)
}
static void
ovsdb_device_added(NMOvsdb * ovsdb,
const char * name,
NMDeviceType device_type,
NMDeviceFactory *self)
ovsdb_device_added(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self)
{
NMDevice *device = NULL;
const NMDeviceType device_type = device_type_i;
NMDevice * device;
device = new_device_from_type(name, device_type);
if (!device)
@ -122,13 +120,11 @@ ovsdb_device_added(NMOvsdb * ovsdb,
}
static void
ovsdb_device_removed(NMOvsdb * ovsdb,
const char * name,
NMDeviceType device_type,
NMDeviceFactory *self)
ovsdb_device_removed(NMOvsdb *ovsdb, const char *name, guint device_type_i, NMDeviceFactory *self)
{
NMDevice * device;
NMDeviceState device_state;
const NMDeviceType device_type = device_type_i;
NMDevice * device;
NMDeviceState device_state;
device = nm_manager_get_device(NM_MANAGER_GET, name, device_type);
if (!device)

File diff suppressed because it is too large Load diff

View file

@ -25,8 +25,8 @@
#include "nm-ip4-config.h"
#include "nm-std-aux/nm-dbus-compat.h"
#define _NMLOG_DEVICE_TYPE NMDeviceTeam
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceTeam);
/*****************************************************************************/

View file

@ -28,8 +28,8 @@
#include "settings/nm-settings.h"
#include "supplicant/nm-supplicant-types.h"
#define _NMLOG_DEVICE_TYPE NMDeviceIwd
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceIwd);
/*****************************************************************************/

View file

@ -30,8 +30,8 @@
#include "nm-manager.h"
#include "platform/nm-platform.h"
#define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOlpcMesh);
/*****************************************************************************/

View file

@ -27,8 +27,8 @@
#include "platform/nmp-object.h"
#include "settings/nm-settings.h"
#define _NMLOG_DEVICE_TYPE NMDeviceWifiP2P
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceWifiP2P);
/*****************************************************************************/

View file

@ -41,8 +41,8 @@
#include "nm-core-internal.h"
#include "nm-config.h"
#define _NMLOG_DEVICE_TYPE NMDeviceWifi
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceWifi);
#define SCAN_INTERVAL_SEC_MIN 3
#define SCAN_INTERVAL_SEC_STEP 20

View file

@ -16,8 +16,8 @@
#include "NetworkManagerUtils.h"
#include "nm-core-internal.h"
#define _NMLOG_DEVICE_TYPE NMDeviceModem
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceModem);
/*****************************************************************************/