release: bump version to 1.11.1-dev after 1.10.0 release

After 1.10.0 is released, merge it back into master so that
1.10.0 is part of the history of master. That means,
  $ git log --first-parent master
will also traverse 1.10.0 and 1.10-rc*.

Also bump the micro version to 1.11.1-dev to indicate that this is
after 1.10.0 is out.
This commit is contained in:
Thomas Haller 2017-05-10 15:11:57 +02:00
commit 75e79b2976
137 changed files with 118007 additions and 137501 deletions

3
.gitignore vendored
View file

@ -6,7 +6,7 @@
*.gcno
*.gcda
*.la
*.gir
*-*.gir
*.typelib
**.stamp
.dirstamp
@ -177,6 +177,7 @@ test-*.trs
/libnm-util/tests/test-setting-8021x
/libnm-util/tests/test-setting-dcb
/libnm/fake-typelib/typelibs.c
/libnm/nm-settings-ifcfg-rh-docs.xml
/libnm/nm-property-docs.xml
/libnm/nm-settings-docs.xml

View file

@ -26,7 +26,7 @@ addons:
coverity_scan:
project:
name: NetworkManager/NetworkManager
build_command_prepend: sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no
build_command_prepend: sh autogen.sh --with-systemd-logind=no --enable-more-warnings=no --disable-ovs
build_command: make -j4
branch_pattern: .*coverity.*

View file

@ -737,6 +737,7 @@ libnm_lib_h_pub_real = \
libnm/NetworkManager.h \
libnm/nm-access-point.h \
libnm/nm-active-connection.h \
libnm/nm-checkpoint.h \
libnm/nm-client.h \
libnm/nm-device-adsl.h \
libnm/nm-device-bond.h \
@ -792,6 +793,7 @@ libnm_lib_h_priv = \
libnm_lib_c_real = \
libnm/nm-access-point.c \
libnm/nm-active-connection.c \
libnm/nm-checkpoint.c \
libnm/nm-client.c \
libnm/nm-dbus-helpers.c \
libnm/nm-device-adsl.c \
@ -858,6 +860,7 @@ nodist_libnminclude_HEADERS += \
noinst_LTLIBRARIES += libnm/libnm-utils.la
libnm_libnm_utils_la_CPPFLAGS = \
$(INTROSPECTION_CFLAGS) \
$(libnm_lib_cppflags)
libnm_libnm_utils_la_SOURCES = \
@ -956,8 +959,34 @@ libnm/libnm.typelib: libnm/libnm.gir
$(INTROSPECTION_COMPILER) --includedir=$(srcdir)/libnm-core --includedir=$(builddir)/libnm-core --includedir=$(srcdir)/libnm --includedir=$(builddir)/libnm $< -o $@
INTROSPECTION_GIRS += libnm/NM-1.0.gir
if WITH_FAKE_TYPELIBS
libnm/fake-typelib/NetworkManager.typelib: libnm/fake-typelib/NetworkManager.gir libnm/fake-typelib/.dirstamp
$(AM_V_GEN) $(INTROSPECTION_COMPILER) $< -o $@
libnm/fake-typelib/NMClient.typelib: libnm/fake-typelib/NMClient.gir libnm/fake-typelib/.dirstamp
$(AM_V_GEN) $(INTROSPECTION_COMPILER) $< -o $@
libnm/fake-typelib/typelibs.c: libnm/fake-typelib/typelibs.gresource.xml libnm/fake-typelib/NetworkManager.typelib libnm/fake-typelib/NMClient.typelib
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< --target=$@ --sourcedir=$(builddir)/libnm/fake-typelib --generate-source --manual-register
nodist_libnm_libnm_utils_la_SOURCES = \
libnm/fake-typelib/typelibs.c
CLEANFILES += \
libnm/fake-typelib/typelibs.c \
libnm/fake-typelib/NMClient.typelib \
libnm/fake-typelib/NetworkManager.typelib
endif
endif
EXTRA_DIST += \
libnm/fake-typelib/NetworkManager.gir \
libnm/fake-typelib/NMClient.gir \
libnm/fake-typelib/typelibs.gresource.xml
if HAVE_INTROSPECTION
libnm_noinst_data = \
@ -2075,6 +2104,7 @@ EXTRA_DIST += \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_LEAP.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wifi_WEP_104_ASCII.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Vlan_test-vlan-interface.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-dcb-test.cexpected \
@ -4537,6 +4567,7 @@ EXTRA_DIST += \
shared/nm-utils/c-list-util.h \
shared/nm-utils/gsystem-local-alloc.h \
shared/nm-utils/nm-glib.h \
shared/nm-utils/nm-jansson.h \
shared/nm-utils/nm-obj.h \
shared/nm-utils/nm-macros-internal.h \
shared/nm-utils/nm-shared-utils.c \

View file

@ -133,6 +133,8 @@ EXTRA_DIST += \
examples/dispatcher/10-ifcfg-rh-routes.sh \
examples/dispatcher/70-wifi-wired-exclusive.sh \
\
examples/js/get_ips.js \
\
examples/lua/lgi/add-connection.lua \
examples/lua/lgi/list-connections.lua \
examples/lua/lgi/list-devices.lua \

View file

@ -399,9 +399,11 @@ nmc_device_reason_to_string (NMDeviceStateReason reason)
return _("The device's parent changed");
case NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED:
return _("The device parent's management changed");
case NM_DEVICE_STATE_REASON_OVSDB_FAILED:
return _("OpenVSwitch database connection failed");
case NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE:
return _("A duplicate IP address was detected");
}
/* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */

View file

@ -461,6 +461,7 @@ _get_text_hidden (NMMetaAccessorGetType get_type)
return NM_META_TEXT_HIDDEN;
}
/*****************************************************************************/
G_GNUC_PRINTF (4, 5)
@ -3642,6 +3643,60 @@ _validate_fcn_team_config (const char *value, char **out_to_free, GError **error
RETURN_STR_TO_FREE (json);
}
static gboolean
_is_valid_team_runner_tx_hash_element (const char *tx_hash_element)
{
const char *valid_tx_hashes[] = { "eth", "vlan", "ipv4", "ipv6", "ip",
"l3", "tcp", "udp", "sctp", "l4", NULL };
if (nmc_string_is_valid (tx_hash_element, valid_tx_hashes, NULL))
return TRUE;
return FALSE;
}
static gboolean
_set_fcn_team_runner_tx_hash (ARGS_SET_FCN)
{
char **strv = NULL;
guint i = 0;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
strv = _nm_utils_strv_cleanup (g_strsplit_set (value, " \t,", 0),
TRUE, TRUE, TRUE);
if (!verify_string_list (strv, property_info->property_name,
_is_valid_team_runner_tx_hash_element,
error)) {
g_strfreev (strv);
return FALSE;
}
while (strv && strv[i])
nm_setting_team_add_runner_tx_hash (NM_SETTING_TEAM (setting), strv[i++]);
g_strfreev (strv);
return TRUE;
}
static gboolean
_validate_and_remove_team_runner_tx_hash (NMSettingTeam *setting,
const char *tx_hash,
GError **error)
{
if (!nm_setting_team_remove_runner_tx_hash_by_value (setting, tx_hash)) {
g_set_error (error, 1, 0,
_("the property doesn't contain string '%s'"),
tx_hash);
return FALSE;
}
return TRUE;
}
DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_team_runner_tx_hash,
NM_SETTING_TEAM,
nm_setting_team_get_num_runner_tx_hash,
nm_setting_team_remove_runner_tx_hash,
_validate_and_remove_team_runner_tx_hash)
static gconstpointer
_get_fcn_vlan_flags (ARGS_GET_FCN)
{
@ -6000,6 +6055,130 @@ static const NMMetaPropertyInfo *const property_infos_TEAM[] = {
.validate_fcn = _validate_fcn_team_config,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "disabled",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_COUNT,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "disabled",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_BROADCAST,
NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
NM_SETTING_TEAM_RUNNER_LOADBALANCE,
NM_SETTING_TEAM_RUNNER_LACP),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL,
NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE,
NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_HASH,
.property_type = DEFINE_PROPERTY_TYPE (
.get_fcn = _get_fcn_gobject,
.set_fcn = _set_fcn_team_runner_tx_hash,
.remove_fcn = _remove_fcn_team_runner_tx_hash,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("basic"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 50,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_ACTIVE,
.property_type = & _pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_FAST_RATE,
.property_type = & _pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_SYS_PRIO,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 255,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_MIN_PORTS,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO,
NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE,
NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH,
NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT,
NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG),
),
),
NULL
};
@ -6016,6 +6195,53 @@ static const NMMetaPropertyInfo *const property_infos_TEAM_PORT[] = {
.validate_fcn = _validate_fcn_team_config,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_QUEUE_ID,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = -1,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_PRIO,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_STICKY,
.property_type = &_pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_PRIO,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 255,
.nick = "default",
}
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_TEAM_PORT_LACP_KEY,
.property_type = &_pt_gobject_int,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int,
.value_infos = INT_VALUE_INFOS (
{
.value = 0,
.nick = "default",
}
),
),
),
NULL
};

View file

@ -316,9 +316,28 @@
#define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.")
#define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_CONFIG N_("The JSON configuration for the team network interface. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_COUNT N_("Corresponds to the teamd mcast_rejoin.count.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL N_("Corresponds to the teamd mcast_rejoin.interval.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".")
#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_COUNT N_("Corresponds to the teamd notify_peers.count.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL N_("Corresponds to the teamd notify_peers.interval.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER N_("Corresponds to the teamd runner.name. Permitted values are: \"roundrobin\", \"broadcast\", \"activebackup\", \"loadbalance\", \"lacp\".")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_ACTIVE N_("Corresponds to the teamd runner.active.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY N_("Corresponds to the teamd runner.agg_select_policy.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_FAST_RATE N_("Corresponds to the teamd runner.fast_rate.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_HWADDR_POLICY N_("Corresponds to the teamd runner.hwaddr_policy.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_MIN_PORTS N_("Corresponds to the teamd runner.min_ports.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_SYS_PRIO N_("Corresponds to the teamd runner.sys_prio.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER N_("Corresponds to the teamd runner.tx_balancer.name.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL N_("Corresponds to the teamd runner.tx_balancer.interval.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_RUNNER_TX_HASH N_("Corresponds to the teamd runner.tx_hash.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_CONFIG N_("The JSON configuration for the team port. The property should contain raw JSON configuration data suitable for teamd, because the value is passed directly to teamd. If not specified, the default configuration is used. See man teamd.conf for the format details.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_KEY N_("Corresponds to the teamd ports.PORTIFNAME.lacp_key.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_LACP_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.lacp_prio.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_NAME N_("The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example \"ppp\" or \"wireless\" or \"wired\".")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_PRIO N_("Corresponds to the teamd ports.PORTIFNAME.prio.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_QUEUE_ID N_("Corresponds to the teamd ports.PORTIFNAME.queue_id. When set to -1 means the parameter is skipped from the json config.")
#define DESCRIBE_DOC_NM_SETTING_TEAM_PORT_STICKY N_("Corresponds to the teamd ports.PORTIFNAME.sticky.")
#define DESCRIBE_DOC_NM_SETTING_TUN_GROUP N_("The group ID which will own the device. If set to NULL everyone will be able to use the device.")
#define DESCRIBE_DOC_NM_SETTING_TUN_MODE N_("The operating mode of the virtual device. Allowed values are NM_SETTING_TUN_MODE_TUN (1) to create a layer 3 device and NM_SETTING_TUN_MODE_TAP (2) to create an Ethernet-like layer 2 one.")
#define DESCRIBE_DOC_NM_SETTING_TUN_MULTI_QUEUE N_("If the property is set to TRUE, the interface will support multiple file descriptors (queues) to parallelize packet sending or receiving. Otherwise, the interface will only support a single queue.")

View file

@ -2,8 +2,8 @@ AC_PREREQ([2.63])
dnl The NM version number
m4_define([nm_major_version], [1])
m4_define([nm_minor_version], [10])
m4_define([nm_micro_version], [0])
m4_define([nm_minor_version], [11])
m4_define([nm_micro_version], [1])
m4_define([nm_version],
[nm_major_version.nm_minor_version.nm_micro_version])
@ -322,9 +322,12 @@ GLIB_CFLAGS="$GLIB_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32 -DGLIB_V
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
GOBJECT_INTROSPECTION_CHECK([0.9.6])
AC_ARG_WITH(libnm-glib,
AS_HELP_STRING([--without-libnm-glib],
[don't build legacy libraries]))
[don"'"t build legacy libraries]))
fake_typelibs=no
if test "$with_libnm_glib" != "no"; then
PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.1 dbus-glib-1 >= 0.94, :,
[AC_MSG_FAILURE([$DBUS_PKG_ERRORS
@ -333,13 +336,24 @@ Configure with --without-libnm-glib if you do not need the legacy libraries])
])
with_libnm_glib=yes
if test "${found_introspection}" = "yes"; then
AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
if ! test x"$GLIB_COMPILE_RESOURCES" = x""; then
fake_typelibs=yes
fi
fi
fi
AM_CONDITIONAL(WITH_LEGACY_LIBRARIES, test "$with_libnm_glib" != "no")
if test "$fake_typelibs" = "yes"; then
AC_DEFINE(WITH_FAKE_TYPELIBS, 1, [Define for libnm to prevent GIR from loading libnm-glib])
else
AC_DEFINE(WITH_FAKE_TYPELIBS, 0, [Define for libnm to prevent GIR from loading libnm-glib])
fi
AM_CONDITIONAL(WITH_FAKE_TYPELIBS, test "${fake_typelibs}" = "yes")
PKG_CHECK_MODULES([LIBUDEV], [libudev >= 175])
GOBJECT_INTROSPECTION_CHECK([0.9.6])
# Qt4
PKG_CHECK_MODULES(QT, [QtCore >= 4 QtDBus QtNetwork], [have_qt=yes],[have_qt=no])
AC_ARG_ENABLE(qt,
@ -1213,6 +1227,22 @@ fi
AC_SUBST(SANITIZERS, [$sanitizers])
AC_MSG_CHECKING([CC support C11 _Generic()])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; int b = _Generic (a, int: 4); return b + a; }]],
[[foo();]])],
[cc_support_generic=1],
[cc_support_generic=0])
AC_MSG_RESULT($cc_support_generic)
AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_GENERIC, $cc_support_generic, [Define whether the compiler supports C11 _Generic()])
AC_MSG_CHECKING([CC support gcc __auto_type])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(void); int foo() { int a = 0; __auto_type b = a; return b + a; }]],
[[foo();]])],
[cc_support_auto_type=1],
[cc_support_auto_type=0])
AC_MSG_RESULT($cc_support_auto_type)
AC_DEFINE_UNQUOTED(_NM_CC_SUPPORT_AUTO_TYPE, $cc_support_auto_type, [Define whether the compiler support gcc __auto_type])
dnl -------------------------
dnl Vala bindings
dnl -------------------------

184
examples/js/get_ips.js Executable file
View file

@ -0,0 +1,184 @@
#!/usr/bin/env gjs
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright 2014,2017 Red Hat, Inc.
*/
const System = imports.system;
const NM = imports.gi.NM;
const GLib = imports.gi.GLib;
/*
* This example shows how to get addresses, routes and DNS information
* from NMIP4Config and NMIP6Config (got out of NMDevice)
*/
function show_addresses (dev, family)
{
let ip_cfg;
if (family == GLib.SYSDEF_AF_INET)
ip_cfg = dev.get_ip4_config ();
else
ip_cfg = dev.get_ip6_config ();
if (ip_cfg == null) {
print ("None");
return;
}
let nm_addresses = ip_cfg.get_addresses ();
if (nm_addresses.length == 0) {
print ("None");
return;
}
for (let nm_address of nm_addresses) {
let addr = nm_address.get_address ();
let prefix = nm_address.get_prefix ();
print (addr + "/" + prefix);
}
}
function show_gateway (dev, family)
{
let ip_cfg;
if ((family == GLib.SYSDEF_AF_INET))
ip_cfg = dev.get_ip4_config ();
else
ip_cfg = dev.get_ip6_config ();
let gw;
if (ip_cfg == null)
gw = "None"
else {
gw = ip_cfg.get_gateway ();
if (gw == '')
gw = "None"
}
print (gw);
}
function show_routes (dev, family)
{
let ip_cfg;
if ((family == GLib.SYSDEF_AF_INET))
ip_cfg = dev.get_ip4_config ();
else
ip_cfg = dev.get_ip6_config ();
if (ip_cfg == null) {
print ("None");
return;
}
let nm_routes = ip_cfg.get_routes ();
if (nm_routes.length == 0) {
print ("None");
return;
}
for (let nm_route of nm_routes) {
let dest = nm_route.get_dest ();
let prefix = nm_route.get_prefix ();
let next_hop = nm_route.get_next_hop ();
let metric = nm_route.get_metric ();
print (dest + "/" + prefix + " " + next_hop + " " + metric);
}
}
function show_dns (dev, family)
{
let ip_cfg;
if ((family == GLib.SYSDEF_AF_INET))
ip_cfg = dev.get_ip4_config ();
else
ip_cfg = dev.get_ip6_config ();
if (ip_cfg == null) {
print ("None");
return;
}
print ("Nameservers: " + ip_cfg.get_nameservers ());
print ("Domains: " + ip_cfg.get_domains ());
print ("Searches: " + ip_cfg.get_searches ());
if ((family == GLib.SYSDEF_AF_INET))
print ("WINS: " + ip_cfg.get_wins_servers ());
}
if (ARGV.length != 1) {
print ("Usage: get_ips.js <interface>");
System.exit (1);
}
let dev_iface = ARGV[0];
let c = NM.Client.new (null);
let dev = c.get_device_by_iface (dev_iface);
if (dev == null) {
print ("Device '%s' not found " + dev_iface);
System.exit (1);
}
print ("Device: " + dev_iface + " - " + dev.get_type_description ());
print ("---------------------------------------");
print ();
print ("IPv4 addresses:");
print ("---------------");
show_addresses (dev, GLib.SYSDEF_AF_INET);
print ();
print ("IPv4 gateway:");
print ("-------------");
show_gateway (dev, GLib.SYSDEF_AF_INET);
print ();
print ("IPv4 routes:");
print ("------------");
show_routes (dev, GLib.SYSDEF_AF_INET);
print ();
print ("IPv6 addresses:");
print ("---------------");
show_addresses (dev, GLib.SYSDEF_AF_INET6);
print ();
print ("IPv6 gateway:");
print ("-------------");
show_gateway (dev, GLib.SYSDEF_AF_INET6);
print ();
print ("IPv6 routes:");
print ("------------");
show_routes (dev, GLib.SYSDEF_AF_INET6);
print ();
print ("IPv4 DNS:");
print ("------------");
show_dns (dev, GLib.SYSDEF_AF_INET);
print ();
print ("IPv6 DNS:");
print ("------------");
show_dns (dev, GLib.SYSDEF_AF_INET6);
print ();

View file

@ -0,0 +1,130 @@
#!/usr/bin/env python
# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# vim: ft=python ts=4 sts=4 sw=4 et ai
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright 2017 Red Hat, Inc.
import sys
import gi
gi.require_version('NM', '1.0')
from gi.repository import GLib, NM
def usage():
print "Usage: %s [COMMAND [ARG]...]" % sys.argv[0]
print ""
print " COMMANDS: show"
print " create TIMEOUT [DEV]..."
print " destroy PATH|NUMBER"
print " rollback PATH|NUMBER"
print
sys.exit(1)
def create_cb(client, result, data):
try:
checkpoint = client.checkpoint_create_finish(result)
print("%s" % checkpoint.get_path())
except Exception, e:
sys.stderr.write("Failed: %s\n" % e.message)
main_loop.quit()
def do_create(client):
if len(sys.argv) < 3:
sys.exit("Failed: %s\n" % e.message)
timeout = int(sys.argv[2])
devices = []
for arg in sys.argv[3:]:
d = client.get_device_by_iface(arg)
if d is None:
sys.exit("Unknown device %s" % arg)
devices.append(d)
client.checkpoint_create_async(devices, timeout, 0, None, create_cb, None)
def destroy_cb(client, result, data):
try:
if client.checkpoint_destroy_finish(result) == True:
print "Success"
except Exception, e:
sys.stderr.write("Failed: %s\n" % e.message)
main_loop.quit()
def find_checkpoint(client, arg):
try:
num = int(arg)
path = "/org/freedesktop/NetworkManager/Checkpoint/%u" % num
except Exception, e:
path = arg
for c in client.get_checkpoints():
if c.get_path() == path:
return c
return None
def do_destroy(client):
if len(sys.argv) < 3:
sys.exit("Missing checkpoint path")
checkpoint = find_checkpoint(client, sys.argv[2])
if checkpoint is None:
sys.exit("Uknown checkpoint %s" % sys.argv[2])
client.checkpoint_destroy_async(checkpoint, None, destroy_cb, None)
def rollback_cb(client, result, data):
try:
res = client.checkpoint_rollback_finish(result)
for path in res:
d = client.get_device_by_path(path)
if d is None:
iface = path
else:
iface = d.get_iface()
print "%s => %s" % (iface, "OK" if res[path] == 0 else "ERROR")
except Exception, e:
sys.stderr.write("Failed: %s\n" % e.message)
main_loop.quit()
def do_rollback(client):
if len(sys.argv) < 3:
sys.exit("Missing checkpoint path")
checkpoint = find_checkpoint(client, sys.argv[2])
if checkpoint is None:
sys.exit("Uknown checkpoint %s" % sys.argv[2])
client.checkpoint_rollback_async(checkpoint, None, rollback_cb, None)
def do_show(client):
for c in client.get_checkpoints():
print "%s:" % c.get_path()
print " created: %u" % c.get_created()
print " timeout: %u seconds" % c.get_rollback_timeout()
print " devices:", ' '.join(sorted(map(lambda x: x.get_iface(), c.get_devices())))
if __name__ == '__main__':
nm_client = NM.Client.new(None)
main_loop = GLib.MainLoop()
if len(sys.argv) < 2 or sys.argv[1] == 'show':
do_show(nm_client)
sys.exit(0)
elif sys.argv[1] == 'create':
do_create(nm_client)
elif sys.argv[1] == 'destroy':
do_destroy(nm_client)
elif sys.argv[1] == 'rollback':
do_rollback(nm_client)
else:
usage()
main_loop.run()

View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- Mode: Python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# vim: ft=python ts=4 sts=4 sw=4 et ai
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright 2014 Red Hat, Inc.
#
#
# This example imports a VPN connection, by loading the glib based
# VPN plugin.
import gi
gi.require_version('NM', '1.0')
from gi.repository import GLib, NM
import sys
if len(sys.argv) != 2:
print("Expects one argument: the filename")
sys.exit(1)
filename = sys.argv[1]
connection = None
for vpn_info in NM.VpnPluginInfo.list_load():
print("TRY: plugin %s" % (vpn_info.get_filename()))
try:
vpn_plugin = vpn_info.load_editor_plugin()
except Exception as e:
print("SKIP: cannot load plugin: %s" % (e))
continue
try:
connection = vpn_plugin.import_(filename)
except Exception as e:
print("SKIP: failure to import %s" % (e))
continue
break
if connection is None:
print("None of the VPN plugins was able to import \"%s\"" % (filename))
sys.exit(1)
connection.normalize()
print("connection imported from \"%s\" using plugin \"%s\" (\"%s\", %s)" % (filename, vpn_info.get_filename(), connection.get_id(), connection.get_uuid()))
client = NM.Client.new(None)
main_loop = GLib.MainLoop()
def added_cb(client, result, data):
try:
client.add_connection_finish(result)
print("The connection profile has been succesfully added to NetworkManager.")
except Exception, e:
print("ERROR: failed to add connection: %s\n" % e)
main_loop.quit()
client.add_connection_async(connection, True, None, added_cb, None)
main_loop.run()

View file

@ -269,6 +269,13 @@
-->
<property name="AllDevices" type="ao" access="read"/>
<!--
Checkpoints:
The list of active checkpoints.
-->
<property name="Checkpoints" type="ao" access="read"/>
<!--
NetworkingEnabled:

View file

@ -429,11 +429,24 @@ NMSettingBluetooth *_nm_connection_get_setting_bluetooth_for_nap (NMConnection *
/*****************************************************************************/
const char *nm_utils_inet_ntop (int addr_family, gconstpointer addr, char *dst);
gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
/*****************************************************************************/
gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
GValue *_nm_utils_team_config_get (const char *conf,
const char *key,
const char *key2,
const char *key3,
gboolean port_config);
gboolean _nm_utils_team_config_set (char **conf,
const char *key,
const char *key2,
const char *key3,
const GValue *value);
/*****************************************************************************/

View file

@ -76,6 +76,7 @@
#define NM_DBUS_INTERFACE_DEVICE_GRE NM_DBUS_INTERFACE_DEVICE ".Gre"
#define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel"
#define NM_DBUS_INTERFACE_DEVICE_STATISTICS NM_DBUS_INTERFACE_DEVICE ".Statistics"
#define NM_DBUS_INTERFACE_CHECKPOINT NM_DBUS_INTERFACE ".Checkpoint"
#define NM_DBUS_INTERFACE_SETTINGS "org.freedesktop.NetworkManager.Settings"
#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings"
@ -551,6 +552,7 @@ typedef enum {
* @NM_DEVICE_STATE_REASON_PARENT_CHANGED: the device's parent changed
* @NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED: the device parent's management changed
* @NM_DEVICE_STATE_REASON_OVSDB_FAILED: problem communicating with OpenVSwitch database
* @NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE: a duplicate IP address was detected
*
* Device state change reason codes
*/
@ -619,6 +621,7 @@ typedef enum {
NM_DEVICE_STATE_REASON_PARENT_CHANGED = 61,
NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED = 62,
NM_DEVICE_STATE_REASON_OVSDB_FAILED = 63,
NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE = 64,
} NMDeviceStateReason;
/**

View file

@ -1245,6 +1245,7 @@ static const NMVariantAttributeSpec * const ip_route_attribute_spec[] = {
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, TRUE, TRUE, 'a'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_FROM, G_VARIANT_TYPE_STRING, FALSE, TRUE, 'p'),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, TRUE, FALSE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_ONLINK, G_VARIANT_TYPE_BOOLEAN, TRUE, FALSE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_CWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),
ATTR_SPEC_PTR (NM_IP_ROUTE_ATTRIBUTE_INITCWND, G_VARIANT_TYPE_UINT32, TRUE, TRUE, 0 ),

View file

@ -146,6 +146,7 @@ gboolean nm_ip_route_attribute_validate (const char *name,
#define NM_IP_ROUTE_ATTRIBUTE_SRC "src"
#define NM_IP_ROUTE_ATTRIBUTE_FROM "from"
#define NM_IP_ROUTE_ATTRIBUTE_TOS "tos"
#define NM_IP_ROUTE_ATTRIBUTE_ONLINK "onlink"
#define NM_IP_ROUTE_ATTRIBUTE_WINDOW "window"
#define NM_IP_ROUTE_ATTRIBUTE_CWND "cwnd"
#define NM_IP_ROUTE_ATTRIBUTE_INITCWND "initcwnd"

View file

@ -47,14 +47,37 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM_PORT)
typedef struct {
char *config;
int queue_id;
int prio;
gboolean sticky;
int lacp_prio;
int lacp_key;
} NMSettingTeamPortPrivate;
/* Keep aligned with _prop_to_keys[] */
enum {
PROP_0,
PROP_CONFIG,
PROP_QUEUE_ID,
PROP_PRIO,
PROP_STICKY,
PROP_LACP_PRIO,
PROP_LACP_KEY,
LAST_PROP
};
/* Keep aligned with team-port properties enum */
static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = {
[PROP_0] = { NULL, NULL, NULL, 0 },
[PROP_CONFIG] = { NULL, NULL, NULL, 0 },
[PROP_QUEUE_ID] = { "queue_id", NULL, NULL, NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT },
[PROP_PRIO] = { "prio", NULL, NULL, 0 },
[PROP_STICKY] = { "sticky", NULL, NULL, 0 },
[PROP_LACP_PRIO] = { "lacp_prio", NULL, NULL, NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT },
[PROP_LACP_KEY] = { "lacp_key", NULL, NULL, 0 },
};
/**
* nm_setting_team_port_new:
*
@ -82,6 +105,86 @@ nm_setting_team_port_get_config (NMSettingTeamPort *setting)
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->config;
}
/**
* nm_setting_team_port_get_queue_id:
* @setting: the #NMSettingTeamPort
*
* Returns: the #NMSettingTeamPort:queue_id property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_port_get_queue_id (NMSettingTeamPort *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), -1);
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->queue_id;
}
/**
* nm_setting_team_port_get_prio:
* @setting: the #NMSettingTeamPort
*
* Returns: the #NMSettingTeamPort:prio property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_port_get_prio (NMSettingTeamPort *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0);
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->prio;
}
/**
* nm_setting_team_port_get_sticky:
* @setting: the #NMSettingTeamPort
*
* Returns: the #NMSettingTeamPort:sticky property of the setting
*
* Since: 1.12
**/
gboolean
nm_setting_team_port_get_sticky (NMSettingTeamPort *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), FALSE);
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->sticky;
}
/**
* nm_setting_team_port_get_lacp_prio:
* @setting: the #NMSettingTeamPort
*
* Returns: the #NMSettingTeamPort:lacp-prio property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_port_get_lacp_prio (NMSettingTeamPort *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0);
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->lacp_prio;
}
/**
* nm_setting_team_port_get_lacp_key:
* @setting: the #NMSettingTeamPort
*
* Returns: the #NMSettingTeamPort:lacp-key property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_port_get_lacp_key (NMSettingTeamPort *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM_PORT (setting), 0);
return NM_SETTING_TEAM_PORT_GET_PRIVATE (setting)->lacp_key;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@ -171,23 +274,79 @@ compare_property (NMSetting *setting,
static void
nm_setting_team_port_init (NMSettingTeamPort *setting)
{
NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
priv->queue_id = NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT;
priv->lacp_prio = NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT;
}
#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id], TRUE)
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (object);
const GValue *align_value = NULL;
gboolean align_config = FALSE;
switch (prop_id) {
case PROP_CONFIG:
g_free (priv->config);
priv->config = g_value_dup_string (value);
priv->queue_id = JSON_TO_VAL (int, PROP_QUEUE_ID);
priv->prio = JSON_TO_VAL (int, PROP_PRIO);
priv->sticky = JSON_TO_VAL (boolean, PROP_STICKY);
priv->lacp_prio = JSON_TO_VAL (int, PROP_LACP_PRIO);
priv->lacp_key = JSON_TO_VAL (int, PROP_LACP_KEY);
break;
case PROP_QUEUE_ID:
if (priv->queue_id == g_value_get_int (value))
break;
priv->queue_id = g_value_get_int (value);
if (priv->queue_id != NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT)
align_value = value;
align_config = TRUE;
break;
case PROP_PRIO:
if (priv->prio == g_value_get_int (value))
break;
priv->prio = g_value_get_int (value);
if (priv->prio)
align_value = value;
align_config = TRUE;
break;
case PROP_STICKY:
if (priv->sticky == g_value_get_boolean (value))
break;
priv->sticky = g_value_get_boolean (value);
if (priv->sticky)
align_value = value;
align_config = TRUE;
break;
case PROP_LACP_PRIO:
if (priv->lacp_prio == g_value_get_int (value))
break;
priv->lacp_prio = g_value_get_int (value);
/* from libteam sources: lacp_prio default value is 0xff */
if (priv->lacp_prio != NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT)
align_value = value;
align_config = TRUE;
break;
case PROP_LACP_KEY:
if (priv->lacp_key == g_value_get_int (value))
break;
priv->lacp_key = g_value_get_int (value);
if (priv->lacp_key)
align_value = value;
align_config = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
if (align_config)
_nm_utils_json_append_gvalue (&priv->config, _prop_to_keys[prop_id], align_value);
}
static void
@ -195,11 +354,27 @@ get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingTeamPort *setting = NM_SETTING_TEAM_PORT (object);
NMSettingTeamPortPrivate *priv = NM_SETTING_TEAM_PORT_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_CONFIG:
g_value_set_string (value, nm_setting_team_port_get_config (setting));
break;
case PROP_QUEUE_ID:
g_value_set_int (value, priv->queue_id);
break;
case PROP_PRIO:
g_value_set_int (value, priv->prio);
break;
case PROP_STICKY:
g_value_set_boolean (value, priv->sticky);
break;
case PROP_LACP_PRIO:
g_value_set_int (value, priv->lacp_prio);
break;
case PROP_LACP_KEY:
g_value_set_int (value, priv->lacp_key);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -253,4 +428,77 @@ nm_setting_team_port_class_init (NMSettingTeamPortClass *setting_class)
G_PARAM_READWRITE |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeamPort:queue-id:
*
* Corresponds to the teamd ports.PORTIFNAME.queue_id.
* When set to -1 means the parameter is skipped from the json config.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_QUEUE_ID,
g_param_spec_int (NM_SETTING_TEAM_PORT_QUEUE_ID, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeamPort:prio:
*
* Corresponds to the teamd ports.PORTIFNAME.prio.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_PRIO,
g_param_spec_int (NM_SETTING_TEAM_PORT_PRIO, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeamPort:sticky:
*
* Corresponds to the teamd ports.PORTIFNAME.sticky.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_STICKY,
g_param_spec_boolean (NM_SETTING_TEAM_PORT_STICKY, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeamPort:lacp-prio:
*
* Corresponds to the teamd ports.PORTIFNAME.lacp_prio.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_LACP_PRIO,
g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_PRIO, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeamPort:lacp-key:
*
* Corresponds to the teamd ports.PORTIFNAME.lacp_key.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_LACP_KEY,
g_param_spec_int (NM_SETTING_TEAM_PORT_LACP_KEY, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -39,6 +39,14 @@ G_BEGIN_DECLS
#define NM_SETTING_TEAM_PORT_SETTING_NAME "team-port"
#define NM_SETTING_TEAM_PORT_CONFIG "config"
#define NM_SETTING_TEAM_PORT_QUEUE_ID "queue-id"
#define NM_SETTING_TEAM_PORT_PRIO "prio"
#define NM_SETTING_TEAM_PORT_STICKY "sticky"
#define NM_SETTING_TEAM_PORT_LACP_PRIO "lacp-prio"
#define NM_SETTING_TEAM_PORT_LACP_KEY "lacp-key"
#define NM_SETTING_TEAM_PORT_QUEUE_ID_DEFAULT -1
#define NM_SETTING_TEAM_PORT_LACP_PRIO_DEFAULT 255
/**
* NMSettingTeamPort:
@ -61,6 +69,16 @@ GType nm_setting_team_port_get_type (void);
NMSetting * nm_setting_team_port_new (void);
const char * nm_setting_team_port_get_config (NMSettingTeamPort *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_port_get_queue_id (NMSettingTeamPort *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_port_get_prio (NMSettingTeamPort *setting);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_team_port_get_sticky (NMSettingTeamPort *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_port_get_lacp_prio (NMSettingTeamPort *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_port_get_lacp_key (NMSettingTeamPort *setting);
G_END_DECLS

View file

@ -44,14 +44,67 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM)
typedef struct {
char *config;
gint notify_peers_count;
gint notify_peers_interval;
gint mcast_rejoin_count;
gint mcast_rejoin_interval;
char *runner;
char *runner_hwaddr_policy;
GPtrArray *runner_tx_hash;
char *runner_tx_balancer;
gint runner_tx_balancer_interval;
gboolean runner_active;
gboolean runner_fast_rate;
gint runner_sys_prio;
gint runner_min_ports;
char *runner_agg_select_policy;
} NMSettingTeamPrivate;
/* Keep aligned with _prop_to_keys[] */
enum {
PROP_0,
PROP_CONFIG,
PROP_NOTIFY_PEERS_COUNT,
PROP_NOTIFY_PEERS_INTERVAL,
PROP_MCAST_REJOIN_COUNT,
PROP_MCAST_REJOIN_INTERVAL,
PROP_RUNNER,
PROP_RUNNER_HWADDR_POLICY,
PROP_RUNNER_TX_HASH,
PROP_RUNNER_TX_BALANCER,
PROP_RUNNER_TX_BALANCER_INTERVAL,
PROP_RUNNER_ACTIVE,
PROP_RUNNER_FAST_RATE,
PROP_RUNNER_SYS_PRIO,
PROP_RUNNER_MIN_PORTS,
PROP_RUNNER_AGG_SELECT_POLICY,
LAST_PROP
};
/* Keep aligned with team properties enum */
static const _NMUtilsTeamPropertyKeys _prop_to_keys[LAST_PROP] = {
[PROP_0] = { NULL, NULL, NULL, 0 },
[PROP_CONFIG] = { NULL, NULL, NULL, 0 },
[PROP_NOTIFY_PEERS_COUNT] = { "notify_peers", "count", NULL, 0 },
[PROP_NOTIFY_PEERS_INTERVAL] = { "notify_peers", "interval", NULL, 0 },
[PROP_MCAST_REJOIN_COUNT] = { "mcast_rejoin", "count", NULL, 0 },
[PROP_MCAST_REJOIN_INTERVAL] = { "mcast_rejoin", "interval", NULL, 0 },
[PROP_RUNNER] = { "runner", "name", NULL,
{.default_str = NM_SETTING_TEAM_RUNNER_DEFAULT} },
[PROP_RUNNER_HWADDR_POLICY] = { "runner", "hwaddr_policy", NULL, 0 },
[PROP_RUNNER_TX_HASH] = { "runner", "tx_hash", NULL, 0 },
[PROP_RUNNER_TX_BALANCER] = { "runner", "tx_balancer", "name", 0 },
[PROP_RUNNER_TX_BALANCER_INTERVAL] = { "runner", "tx_balancer", "interval",
NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT },
[PROP_RUNNER_ACTIVE] = { "runner", "active", NULL, 0 },
[PROP_RUNNER_FAST_RATE] = { "runner", "fast_rate", NULL, 0 },
[PROP_RUNNER_SYS_PRIO] = { "runner", "sys_prio", NULL,
NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT },
[PROP_RUNNER_MIN_PORTS] = { "runner", "min_ports", NULL, 0 },
[PROP_RUNNER_AGG_SELECT_POLICY] = { "runner", "agg_select_policy", NULL,
{.default_str = NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT} },
};
/**
* nm_setting_team_new:
*
@ -79,6 +132,339 @@ nm_setting_team_get_config (NMSettingTeam *setting)
return NM_SETTING_TEAM_GET_PRIVATE (setting)->config;
}
/**
* nm_setting_team_get_notify_peers_count:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:notify-peers-count property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_notify_peers_count (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->notify_peers_count;
}
/**
* nm_setting_team_get_notify_peers_interval:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:notify-peers-interval property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_notify_peers_interval (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->notify_peers_interval;
}
/**
* nm_setting_team_get_mcast_rejoin_count:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:mcast-rejoin-count property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_mcast_rejoin_count (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->mcast_rejoin_count;
}
/**
* nm_setting_team_get_mcast_rejoin_interval:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:mcast-rejoin-interval property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_mcast_rejoin_interval (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->mcast_rejoin_interval;
}
/**
* nm_setting_team_get_runner:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner property of the setting
*
* Since: 1.12
**/
const char *
nm_setting_team_get_runner (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner;
}
/**
* nm_setting_team_get_runner_hwaddr_policy:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-hwaddr-policy property of the setting
*
* Since: 1.12
**/
const char *
nm_setting_team_get_runner_hwaddr_policy (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_hwaddr_policy;
}
/**
* nm_setting_team_get_runner_tx_balancer:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-tx-balancer property of the setting
*
* Since: 1.12
**/
const char *
nm_setting_team_get_runner_tx_balancer (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_tx_balancer;
}
/**
* nm_setting_team_get_runner_tx_balancer_interval:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-tx-balancer_interval property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_runner_tx_balancer_interval (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_tx_balancer_interval;
}
/**
* nm_setting_team_get_runner_active:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner_active property of the setting
*
* Since: 1.12
**/
gboolean
nm_setting_team_get_runner_active (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_active;
}
/**
* nm_setting_team_get_runner_fast_rate:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-fast-rate property of the setting
*
* Since: 1.12
**/
gboolean
nm_setting_team_get_runner_fast_rate (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_fast_rate;
}
/**
* nm_setting_team_get_runner_sys_prio:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-sys-prio property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_runner_sys_prio (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_sys_prio;
}
/**
* nm_setting_team_get_runner_min_ports:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-min-ports property of the setting
*
* Since: 1.12
**/
gint
nm_setting_team_get_runner_min_ports (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_min_ports;
}
/**
* nm_setting_team_get_runner_agg_select_policy:
* @setting: the #NMSettingTeam
*
* Returns: the ##NMSettingTeam:runner-agg-select-policy property of the setting
*
* Since: 1.12
**/
const char *
nm_setting_team_get_runner_agg_select_policy (NMSettingTeam *setting)
{
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
return NM_SETTING_TEAM_GET_PRIVATE (setting)->runner_agg_select_policy;
}
/**
* nm_setting_team_remove_runner_tx_hash_by_value:
* @setting: the #NMSetetingTeam
* @txhash: the txhash element to remove
*
* Removes the txhash element #txhash
*
* Returns: %TRUE if the txhash element was found and removed; %FALSE if it was not.
*
* Since: 1.12
**/
gboolean
nm_setting_team_remove_runner_tx_hash_by_value (NMSettingTeam *setting,
const char *txhash)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
guint i;
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE);
g_return_val_if_fail (txhash != NULL, FALSE);
g_return_val_if_fail (txhash[0] != '\0', FALSE);
for (i = 0; i < priv->runner_tx_hash->len; i++) {
if (nm_streq (txhash, priv->runner_tx_hash->pdata[i])) {
g_ptr_array_remove_index (priv->runner_tx_hash, i);
g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH);
return TRUE;
}
}
return FALSE;
}
/**
* nm_setting_team_get_num_runner_tx_hash:
* @setting: the #NMSettingTeam
*
* Returns: the number of elements in txhash
*
* Since: 1.12
**/
guint
nm_setting_team_get_num_runner_tx_hash (NMSettingTeam *setting)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), 0);
return priv->runner_tx_hash ? priv->runner_tx_hash->len : 0;
}
/**
* nm_setting_team_get_runner_tx_hash
* @setting: the #NMSettingTeam
* @idx: index number of the txhash element to return
*
* Returns: the txhash element at index @idx
*
* Since: 1.12
**/
const char *
nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, int idx)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), NULL);
g_return_val_if_fail (idx >= 0 && idx < priv->runner_tx_hash->len, NULL);
return priv->runner_tx_hash->pdata[idx];
}
/**
* nm_setting_team_remove_runner_tx_hash:
* @setting: the #NMSettingTeam
* @idx: index number of the element to remove from txhash
*
* Removes the txhash element at index @idx.
*
* Since: 1.12
**/
void
nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, int idx)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
g_return_if_fail (NM_IS_SETTING_TEAM (setting));
g_return_if_fail (idx >= 0 && idx < priv->runner_tx_hash->len);
g_ptr_array_remove_index (priv->runner_tx_hash, idx);
g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH);
}
/**
* nm_setting_team_add_runner_tx_hash:
* @setting: the #NMSettingTeam
* @txhash: the element to add to txhash
*
* Adds a new txhash element to the setting.
*
* Returns: %TRUE if the txhash element was added; %FALSE if the element
* was already knnown.
*
* Since: 1.12
**/
gboolean
nm_setting_team_add_runner_tx_hash (NMSettingTeam *setting, const char *txhash)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
guint i;
g_return_val_if_fail (NM_IS_SETTING_TEAM (setting), FALSE);
g_return_val_if_fail (txhash != NULL, FALSE);
g_return_val_if_fail (txhash[0] != '\0', FALSE);
if (!priv->runner_tx_hash)
priv->runner_tx_hash = g_ptr_array_new_with_free_func (g_free);
for (i = 0; i < priv->runner_tx_hash->len; i++) {
if (nm_streq (txhash, priv->runner_tx_hash->pdata[i]))
return FALSE;
}
g_ptr_array_add (priv->runner_tx_hash, g_strdup (txhash));
g_object_notify (G_OBJECT (setting), NM_SETTING_TEAM_RUNNER_TX_HASH);
return TRUE;
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
@ -108,6 +494,19 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if ( priv->runner
&& g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_BROADCAST)
&& g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_ROUNDROBIN)
&& g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)
&& g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE)
&& g_ascii_strcasecmp (priv->runner, NM_SETTING_TEAM_RUNNER_LACP)) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
_("invalid runner \"%s\""), priv->runner);
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_TEAM_RUNNER);
return FALSE;
}
/* NOTE: normalizable/normalizable-errors must appear at the end with decreasing severity.
* Take care to properly order statements with priv->config above. */
@ -142,6 +541,11 @@ compare_property (NMSetting *setting,
static void
nm_setting_team_init (NMSettingTeam *setting)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
priv->runner = g_strdup (NM_SETTING_TEAM_RUNNER_ROUNDROBIN);
priv->runner_sys_prio = NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT;
priv->runner_tx_balancer_interval = NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT;
}
static void
@ -150,25 +554,200 @@ finalize (GObject *object)
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object);
g_free (priv->config);
g_free (priv->runner);
g_free (priv->runner_hwaddr_policy);
g_free (priv->runner_tx_balancer);
g_free (priv->runner_agg_select_policy);
if (priv->runner_tx_hash)
g_ptr_array_unref (priv->runner_tx_hash);
G_OBJECT_CLASS (nm_setting_team_parent_class)->finalize (object);
}
#define JSON_TO_VAL(typ, id) _nm_utils_json_extract_##typ (priv->config, _prop_to_keys[id], FALSE)
static void
_align_team_properties (NMSettingTeam *setting)
{
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
char **strv;
int i;
priv->notify_peers_count = JSON_TO_VAL (int, PROP_NOTIFY_PEERS_COUNT);
priv->notify_peers_interval = JSON_TO_VAL (int, PROP_NOTIFY_PEERS_INTERVAL);
priv->mcast_rejoin_count = JSON_TO_VAL (int, PROP_MCAST_REJOIN_COUNT);
priv->mcast_rejoin_interval = JSON_TO_VAL (int, PROP_MCAST_REJOIN_INTERVAL);
priv->runner_tx_balancer_interval = JSON_TO_VAL (int, PROP_RUNNER_TX_BALANCER_INTERVAL);
priv->runner_sys_prio = JSON_TO_VAL (int, PROP_RUNNER_SYS_PRIO);
priv->runner_min_ports = JSON_TO_VAL (int, PROP_RUNNER_MIN_PORTS);
priv->runner_active = JSON_TO_VAL (boolean, PROP_RUNNER_ACTIVE);
priv->runner_fast_rate = JSON_TO_VAL (boolean, PROP_RUNNER_FAST_RATE);
g_free (priv->runner);
g_free (priv->runner_hwaddr_policy);
g_free (priv->runner_tx_balancer);
g_free (priv->runner_agg_select_policy);
priv->runner = JSON_TO_VAL (string, PROP_RUNNER);
priv->runner_hwaddr_policy = JSON_TO_VAL (string, PROP_RUNNER_HWADDR_POLICY);
priv->runner_tx_balancer = JSON_TO_VAL (string, PROP_RUNNER_TX_BALANCER);
priv->runner_agg_select_policy = JSON_TO_VAL (string, PROP_RUNNER_AGG_SELECT_POLICY);
if (priv->runner_tx_hash) {
g_ptr_array_unref (priv->runner_tx_hash);
priv->runner_tx_hash = NULL;
}
strv = JSON_TO_VAL (strv, PROP_RUNNER_TX_HASH);
if (strv) {
for (i = 0; strv[i]; i++)
nm_setting_team_add_runner_tx_hash (setting, strv[i]);
g_strfreev (strv);
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingTeam *setting = NM_SETTING_TEAM (object);
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (object);
const GValue *align_value = NULL;
gboolean align_config = FALSE;
char **strv;
switch (prop_id) {
case PROP_CONFIG:
g_free (priv->config);
priv->config = g_value_dup_string (value);
_align_team_properties (setting);
break;
case PROP_NOTIFY_PEERS_COUNT:
if (priv->notify_peers_count == g_value_get_int (value))
break;
priv->notify_peers_count = g_value_get_int (value);
if (priv->notify_peers_count)
align_value = value;
align_config = TRUE;
break;
case PROP_NOTIFY_PEERS_INTERVAL:
if (priv->notify_peers_interval == g_value_get_int (value))
break;
priv->notify_peers_interval = g_value_get_int (value);
if (priv->notify_peers_interval)
align_value = value;
align_config = TRUE;
break;
case PROP_MCAST_REJOIN_COUNT:
if (priv->mcast_rejoin_count == g_value_get_int (value))
break;
priv->mcast_rejoin_count = g_value_get_int (value);
if (priv->mcast_rejoin_count)
align_value = value;
align_config = TRUE;
break;
case PROP_MCAST_REJOIN_INTERVAL:
if (priv->mcast_rejoin_interval == g_value_get_int (value))
break;
priv->mcast_rejoin_interval = g_value_get_int (value);
if (priv->mcast_rejoin_interval)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER:
g_free (priv->runner);
priv->runner = g_value_dup_string (value);
if ( priv->runner
&& !nm_streq (priv->runner,
NM_SETTING_TEAM_RUNNER_DEFAULT))
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_HWADDR_POLICY:
g_free (priv->runner_hwaddr_policy);
priv->runner_hwaddr_policy = g_value_dup_string (value);
if ( priv->runner_hwaddr_policy
&& !nm_streq (priv->runner_hwaddr_policy,
NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL)) {
align_value = value;
}
align_config = TRUE;
break;
case PROP_RUNNER_TX_HASH:
if (priv->runner_tx_hash)
g_ptr_array_unref (priv->runner_tx_hash);
strv = g_value_get_boxed (value);
if (strv && strv[0]) {
priv->runner_tx_hash = _nm_utils_strv_to_ptrarray (strv);
align_value = value;
} else
priv->runner_tx_hash = NULL;
align_config = TRUE;
break;
case PROP_RUNNER_TX_BALANCER:
g_free (priv->runner_tx_balancer);
priv->runner_tx_balancer = g_value_dup_string (value);
if (priv->runner_tx_balancer)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_TX_BALANCER_INTERVAL:
if (priv->runner_tx_balancer_interval == g_value_get_int (value))
break;
priv->runner_tx_balancer_interval = g_value_get_int (value);
if (priv->runner_tx_balancer_interval !=
NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_ACTIVE:
if (priv->runner_active == g_value_get_boolean (value))
break;
priv->runner_active = g_value_get_boolean (value);
if (priv->runner_active)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_FAST_RATE:
if (priv->runner_fast_rate == g_value_get_boolean (value))
break;
priv->runner_fast_rate = g_value_get_boolean (value);
if (priv->runner_fast_rate)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_SYS_PRIO:
if (priv->runner_sys_prio == g_value_get_int (value))
break;
priv->runner_sys_prio = g_value_get_int (value);
if (priv->runner_sys_prio != NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_MIN_PORTS:
if (priv->runner_min_ports == g_value_get_int (value))
break;
priv->runner_min_ports = g_value_get_int (value);
if (priv->runner_min_ports)
align_value = value;
align_config = TRUE;
break;
case PROP_RUNNER_AGG_SELECT_POLICY:
g_free (priv->runner_agg_select_policy);
priv->runner_agg_select_policy = g_value_dup_string (value);
if ( priv->runner_agg_select_policy
&& !nm_streq (priv->runner_agg_select_policy,
NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO))
align_value = value;
align_config = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
if (align_config)
_nm_utils_json_append_gvalue (&priv->config, _prop_to_keys[prop_id], align_value);
}
static void
@ -176,11 +755,55 @@ get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingTeam *setting = NM_SETTING_TEAM (object);
NMSettingTeamPrivate *priv = NM_SETTING_TEAM_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_CONFIG:
g_value_set_string (value, nm_setting_team_get_config (setting));
break;
case PROP_NOTIFY_PEERS_COUNT:
g_value_set_int (value, priv->notify_peers_count);
break;
case PROP_NOTIFY_PEERS_INTERVAL:
g_value_set_int (value, priv->notify_peers_interval);
break;
case PROP_MCAST_REJOIN_COUNT:
g_value_set_int (value, priv->mcast_rejoin_count);
break;
case PROP_MCAST_REJOIN_INTERVAL:
g_value_set_int (value, priv->mcast_rejoin_interval);
break;
case PROP_RUNNER:
g_value_set_string (value, nm_setting_team_get_runner (setting));
break;
case PROP_RUNNER_HWADDR_POLICY:
g_value_set_string (value, nm_setting_team_get_runner_hwaddr_policy (setting));
break;
case PROP_RUNNER_TX_HASH:
g_value_take_boxed (value, priv->runner_tx_hash ?
_nm_utils_ptrarray_to_strv (priv->runner_tx_hash): NULL);
break;
case PROP_RUNNER_TX_BALANCER:
g_value_set_string (value, nm_setting_team_get_runner_tx_balancer (setting));
break;
case PROP_RUNNER_TX_BALANCER_INTERVAL:
g_value_set_int (value, priv->runner_tx_balancer_interval);
break;
case PROP_RUNNER_ACTIVE:
g_value_set_boolean (value, nm_setting_team_get_runner_active (setting));
break;
case PROP_RUNNER_FAST_RATE:
g_value_set_boolean (value, nm_setting_team_get_runner_fast_rate (setting));
break;
case PROP_RUNNER_SYS_PRIO:
g_value_set_int (value, priv->runner_sys_prio);
break;
case PROP_RUNNER_MIN_PORTS:
g_value_set_int (value, priv->runner_min_ports);
break;
case PROP_RUNNER_AGG_SELECT_POLICY:
g_value_set_string (value, nm_setting_team_get_runner_agg_select_policy (setting));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -225,6 +848,205 @@ nm_setting_team_class_init (NMSettingTeamClass *setting_class)
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:notify-peers-count:
*
* Corresponds to the teamd notify_peers.count.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_NOTIFY_PEERS_COUNT,
g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:notify-peers-interval:
*
* Corresponds to the teamd notify_peers.interval.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_NOTIFY_PEERS_INTERVAL,
g_param_spec_int (NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:mcast-rejoin-count:
*
* Corresponds to the teamd mcast_rejoin.count.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_MCAST_REJOIN_COUNT,
g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_COUNT, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:mcast-rejoin-interval:
*
* Corresponds to the teamd mcast_rejoin.interval.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_MCAST_REJOIN_INTERVAL,
g_param_spec_int (NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner:
*
* Corresponds to the teamd runner.name.
* Permitted values are: "roundrobin", "broadcast", "activebackup",
* "loadbalance", "lacp".
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER,
g_param_spec_string (NM_SETTING_TEAM_RUNNER, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-hwaddr-policy:
*
* Corresponds to the teamd runner.hwaddr_policy.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_HWADDR_POLICY,
g_param_spec_string (NM_SETTING_TEAM_RUNNER_HWADDR_POLICY, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-tx-hash:
*
* Corresponds to the teamd runner.tx_hash.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_TX_HASH,
g_param_spec_boxed (NM_SETTING_TEAM_RUNNER_TX_HASH, "", "",
G_TYPE_STRV,
G_PARAM_READWRITE |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-tx-balancer:
*
* Corresponds to the teamd runner.tx_balancer.name.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_TX_BALANCER,
g_param_spec_string (NM_SETTING_TEAM_RUNNER_TX_BALANCER, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-tx-balancer-interval:
*
* Corresponds to the teamd runner.tx_balancer.interval.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_TX_BALANCER_INTERVAL,
g_param_spec_int (NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-active:
*
* Corresponds to the teamd runner.active.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_ACTIVE,
g_param_spec_boolean (NM_SETTING_TEAM_RUNNER_ACTIVE, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-fast-rate:
*
* Corresponds to the teamd runner.fast_rate.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_FAST_RATE,
g_param_spec_boolean (NM_SETTING_TEAM_RUNNER_FAST_RATE, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-sys-prio:
*
* Corresponds to the teamd runner.sys_prio.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_SYS_PRIO,
g_param_spec_int (NM_SETTING_TEAM_RUNNER_SYS_PRIO, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-min-ports:
*
* Corresponds to the teamd runner.min_ports.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_MIN_PORTS,
g_param_spec_int (NM_SETTING_TEAM_RUNNER_MIN_PORTS, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingTeam:runner-agg-select-policy:
*
* Corresponds to the teamd runner.agg_select_policy.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_RUNNER_AGG_SELECT_POLICY,
g_param_spec_string (NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/* ---dbus---
* property: interface-name
* format: string

View file

@ -38,7 +38,45 @@ G_BEGIN_DECLS
#define NM_SETTING_TEAM_SETTING_NAME "team"
#define NM_SETTING_TEAM_CONFIG "config"
#define NM_SETTING_TEAM_CONFIG "config"
#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT "notify-peers-count"
#define NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL "notify-peers-interval"
#define NM_SETTING_TEAM_MCAST_REJOIN_COUNT "mcast-rejoin-count"
#define NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL "mcast-rejoin-interval"
#define NM_SETTING_TEAM_RUNNER "runner"
#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY "runner-hwaddr-policy"
#define NM_SETTING_TEAM_RUNNER_TX_HASH "runner-tx-hash"
#define NM_SETTING_TEAM_RUNNER_TX_BALANCER "runner-tx-balancer"
#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL "runner-tx-balancer-interval"
#define NM_SETTING_TEAM_RUNNER_ACTIVE "runner-active"
#define NM_SETTING_TEAM_RUNNER_FAST_RATE "runner-fast-rate"
#define NM_SETTING_TEAM_RUNNER_SYS_PRIO "runner-sys-prio"
#define NM_SETTING_TEAM_RUNNER_MIN_PORTS "runner-min-ports"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY "runner-agg-select-policy"
#define NM_SETTING_TEAM_RUNNER_BROADCAST "broadcast"
#define NM_SETTING_TEAM_RUNNER_ROUNDROBIN "roundrobin"
#define NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP "activebackup"
#define NM_SETTING_TEAM_RUNNER_LOADBALANCE "loadbalance"
#define NM_SETTING_TEAM_RUNNER_LACP "lacp"
#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL "same_all"
#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE "by_active"
#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE "only_active"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO "lacp_prio"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO_STABLE "lacp_prio_stable"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_BANDWIDTH "bandwidth"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_COUNT "count"
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_PORT_CONFIG "port_config"
#define NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT 1
#define NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT 1
#define NM_SETTING_TEAM_RUNNER_DEFAULT NM_SETTING_TEAM_RUNNER_ROUNDROBIN
#define NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_DEFAULT NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL
#define NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL_DEFAULT 50
#define NM_SETTING_TEAM_RUNNER_SYS_PRIO_DEFAULT 255
#define NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_DEFAULT NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY_LACP_PRIO
/**
* NMSettingTeam:
@ -61,7 +99,42 @@ GType nm_setting_team_get_type (void);
NMSetting * nm_setting_team_new (void);
const char * nm_setting_team_get_config (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_notify_peers_count (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_notify_peers_interval (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_mcast_rejoin_count (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_mcast_rejoin_interval (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
const char * nm_setting_team_get_runner (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
const char * nm_setting_team_get_runner_hwaddr_policy (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
const char * nm_setting_team_get_runner_tx_balancer (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_runner_tx_balancer_interval (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_team_get_runner_active (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_team_get_runner_fast_rate (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_runner_sys_prio (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gint nm_setting_team_get_runner_min_ports (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
const char * nm_setting_team_get_runner_agg_select_policy (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_team_remove_runner_tx_hash_by_value (NMSettingTeam *setting, const char *txhash);
NM_AVAILABLE_IN_1_12
guint nm_setting_team_get_num_runner_tx_hash (NMSettingTeam *setting);
NM_AVAILABLE_IN_1_12
const char *nm_setting_team_get_runner_tx_hash (NMSettingTeam *setting, int idx);
NM_AVAILABLE_IN_1_12
void nm_setting_team_remove_runner_tx_hash (NMSettingTeam *setting, int idx);
NM_AVAILABLE_IN_1_12
gboolean nm_setting_team_add_runner_tx_hash (NMSettingTeam *setting, const char *txhash);
G_END_DECLS
#endif /* __NM_SETTING_TEAM_H__ */

View file

@ -78,4 +78,94 @@ void _nm_utils_bytes_from_dbus (GVariant *dbus_value,
char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length);
/* JSON to GValue conversion macros */
typedef struct {
const char *key1;
const char *key2;
const char *key3;
union {
int default_int;
gboolean default_bool;
const char *default_str;
};
} _NMUtilsTeamPropertyKeys;
static inline int
_nm_utils_json_extract_int (char *conf,
_NMUtilsTeamPropertyKeys key,
gboolean is_port)
{
gs_free GValue *t_value = NULL;
int ret;
t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port);
if (!t_value)
return key.default_int;
ret = g_value_get_int (t_value);
g_value_unset (t_value);
return ret;
}
static inline gboolean
_nm_utils_json_extract_boolean (char *conf,
_NMUtilsTeamPropertyKeys key,
gboolean is_port)
{
gs_free GValue *t_value = NULL;
gboolean ret;
t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port);
if (!t_value)
return key.default_bool;
ret = g_value_get_boolean (t_value);
g_value_unset (t_value);
return ret;
}
static inline char *
_nm_utils_json_extract_string (char *conf,
_NMUtilsTeamPropertyKeys key,
gboolean is_port)
{
gs_free GValue *t_value = NULL;
char *ret;
t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port);
if (!t_value)
return g_strdup (key.default_str);
ret = g_value_dup_string (t_value);
g_value_unset (t_value);
return ret;
}
static inline char **
_nm_utils_json_extract_strv (char *conf,
_NMUtilsTeamPropertyKeys key,
gboolean is_port)
{
gs_free GValue *t_value = NULL;
char **ret;
t_value = _nm_utils_team_config_get (conf, key.key1, key.key2, key.key3, is_port);
if (!t_value)
return NULL;
ret = g_strdupv (g_value_get_boxed (t_value));
g_value_unset (t_value);
return ret;
}
static inline void
_nm_utils_json_append_gvalue (char **conf,
_NMUtilsTeamPropertyKeys key,
const GValue *val)
{
_nm_utils_team_config_set (conf, key.key1, key.key2, key.key3, val);
}
#endif

View file

@ -34,10 +34,7 @@
#include <sys/stat.h>
#include <net/if.h>
#if WITH_JANSSON
#include <jansson.h>
#endif
#include "nm-utils/nm-jansson.h"
#include "nm-utils/nm-enum-utils.h"
#include "nm-utils/nm-hash-utils.h"
#include "nm-common-macros.h"
@ -3762,6 +3759,22 @@ nm_utils_is_uuid (const char *str)
static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN];
const char *
nm_utils_inet_ntop (int addr_family, gconstpointer addr, char *dst)
{
const char *s;
nm_assert_addr_family (addr_family);
nm_assert (addr);
s = inet_ntop (addr_family,
addr,
dst ? dst : _nm_utils_inet_ntop_buffer,
addr_family == AF_INET6 ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN);
nm_assert (s);
return s;
}
/**
* nm_utils_inet4_ntop: (skip)
* @inaddr: the address that should be converted to string.
@ -4345,15 +4358,6 @@ nm_utils_is_json_object (const char *str, GError **error)
return TRUE;
}
/* json_object_foreach_safe() is only available since Jansson 2.8,
* reimplement it */
#define _json_object_foreach_safe(object, n, key, value) \
for (key = json_object_iter_key (json_object_iter (object)), \
n = json_object_iter_next (object, json_object_iter_at (object, key)); \
key && (value = json_object_iter_value (json_object_iter_at (object, key))); \
key = json_object_iter_key (n), \
n = json_object_iter_next (object, json_object_iter_at (object, key)))
gboolean
_nm_utils_team_config_equal (const char *conf1,
const char *conf2,
@ -4417,7 +4421,7 @@ _nm_utils_team_config_equal (const char *conf1,
/* Only consider a given subset of nodes, others can change depending on
* current state */
for (i = 0, json = json1; i < 2; i++, json = json2) {
_json_object_foreach_safe (json, tmp, key, value) {
json_object_foreach_safe (json, tmp, key, value) {
if (!NM_IN_STRSET (key, "runner", "link_watch"))
json_object_del (json, key);
}
@ -4437,6 +4441,280 @@ out:
return ret;
}
static void
_json_add_object (json_t *json,
const char *key1,
const char *key2,
const char *key3,
json_t *value)
{
json_t *json_element, *json_link;
json_element = json_object_get (json, key1);
if (!json_element) {
json_element = value;
if (key2) {
if (key3) {
json_element = json_object ();
json_object_set_new (json_element, key3, value);
}
json_link = json_object ();
json_object_set_new (json_link, key2, json_element);
json_element = json_link;
}
json_object_set_new (json, key1, json_element);
return;
}
if (!key2)
goto key_already_there;
json_link = json_element;
json_element = json_object_get (json_element, key2);
if (!json_element) {
json_element = value;
if (key3) {
json_element = json_object ();
json_object_set_new (json_element, key3, value);
}
json_object_set_new (json_link, key2, json_element);
return;
}
if (!key3)
goto key_already_there;
json_link = json_element;
json_element = json_object_get (json_element, key3);
if (!json_element) {
json_object_set_new (json_link, key3, value);
return;
}
key_already_there:
json_decref (value);
}
GValue *
_nm_utils_team_config_get (const char *conf,
const char *key,
const char *key2,
const char *key3,
gboolean port_config)
{
json_t *json;
json_t *json_element;
GValue *value = NULL;
json_error_t jerror;
const char *runner = NULL;
if (!key)
return NULL;
json = json_loads (conf ?: "{}", JSON_REJECT_DUPLICATES, &jerror);
/* Invalid json in conf */
if (!json)
return NULL;
/* Some properties are added by teamd when missing from the initial
* configuration. Add them with the default value if necessary, depending
* on the configuration type.
*/
if (port_config) {
_json_add_object (json, "link_watch", "name", NULL, json_string ("ethtool"));
} else {
/* Retrieve runner or add default one */
json_element = json_object_get (json, "runner");
if (json_element) {
runner = json_string_value (json_object_get (json_element, "name"));
} else {
json_element = json_object ();
json_object_set_new (json, "runner", json_element);
}
if (!runner) {
runner = NM_SETTING_TEAM_RUNNER_DEFAULT;
json_object_set_new (json_element, "name", json_string (runner));
}
if (nm_streq (runner, NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP)) {
_json_add_object (json, "notify_peers", "count", NULL,
json_integer (NM_SETTING_TEAM_NOTIFY_PEERS_COUNT_ACTIVEBACKUP_DEFAULT));
_json_add_object (json, "mcast_rejoin", "count", NULL,
json_integer (NM_SETTING_TEAM_NOTIFY_MCAST_COUNT_ACTIVEBACKUP_DEFAULT));
} else if ( nm_streq (runner, NM_SETTING_TEAM_RUNNER_LOADBALANCE)
|| nm_streq (runner, NM_SETTING_TEAM_RUNNER_LACP)) {
json_element = json_array ();
json_array_append_new (json_element, json_string ("eth"));
json_array_append_new (json_element, json_string ("ipv4"));
json_array_append_new (json_element, json_string ("ipv6"));
_json_add_object (json, "runner", "tx_hash", NULL, json_element);
}
}
json_element = json_object_get (json, key);
if (json_element && key2)
json_element = json_object_get (json_element, key2);
if (json_element && key3)
json_element = json_object_get (json_element, key3);
if (json_element) {
value = g_new0 (GValue, 1);
if (json_is_string (json_element)) {
g_value_init (value, G_TYPE_STRING);
g_value_set_string (value, json_string_value (json_element));
} else if (json_is_integer (json_element)) {
g_value_init (value, G_TYPE_INT);
g_value_set_int (value, json_integer_value (json_element));
} else if (json_is_boolean (json_element)) {
g_value_init (value, G_TYPE_BOOLEAN);
g_value_set_boolean (value, json_boolean_value (json_element));
} else if (json_is_array (json_element)) {
GPtrArray *data = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
json_t *str_element;
int index;
json_array_foreach (json_element, index, str_element) {
if (json_is_string (str_element))
g_ptr_array_add (data, g_strdup (json_string_value (str_element)));
}
if (data->len) {
g_value_init (value, G_TYPE_STRV);
g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (data));
}
g_ptr_array_free (data, TRUE);
} else {
g_assert_not_reached ();
g_free (value);
value = NULL;
}
}
if (json)
json_decref (json);
return value;
}
/* if conf is updated in place returns TRUE */
gboolean
_nm_utils_team_config_set (char **conf,
const char *key,
const char *key2,
const char *key3,
const GValue *value)
{
json_t *json, *json_element, *json_link, *json_value = NULL;
json_error_t jerror;
gboolean updated = FALSE;
char **strv;
const char *iter_key = key;
int i;
json = json_loads (*conf?: "{}", JSON_REJECT_DUPLICATES, &jerror);
if (!json)
return FALSE;
/* no new value? delete element */
if (!value) {
json_element = json;
json_link = NULL;
if (key2) {
json_link = json;
json_element = json_object_get (json, key);
if (!json_element)
goto done;
iter_key = key2;
}
if (key3) {
json_link = json_element;
json_element = json_object_get (json_element, key2);
if (!json_element)
goto done;
iter_key = key3;
}
if (json_object_del (json_element, iter_key) != 0)
goto done;
updated = TRUE;
/* 1st level key only */
if (!json_link)
goto done;
if (json_object_size (json_element) == 0)
json_object_del (json_link, (key3 ? key2 : key));
if (key3 && json_object_size (json_link) == 0)
json_object_del (json, key);
goto done;
}
/* insert new value */
updated = TRUE;
if (G_VALUE_HOLDS_STRING (value))
json_value = json_string (g_value_get_string (value));
else if (G_VALUE_HOLDS_INT (value))
json_value = json_integer (g_value_get_int (value));
else if (G_VALUE_HOLDS_BOOLEAN (value))
json_value = json_boolean (g_value_get_boolean (value));
else if (G_VALUE_HOLDS_BOXED (value)) {
strv = g_value_get_boxed (value);
if (strv) {
json_value = json_array ();
for (i = 0; strv[i]; i++)
json_array_append_new (json_value, json_string (strv[i]));
} else
return FALSE;
} else {
g_assert_not_reached ();
updated = FALSE;
goto done;
}
/* Simplest case: first level key only */
json_element = json;
json_link = NULL;
if (key2) {
json_link = json;
json_element = json_object_get (json, iter_key);
if (!json_element) {
json_element = json_object ();
json_object_set_new (json_link, iter_key, json_element);
}
iter_key = key2;
}
if (key3) {
json_link = json_element;
json_element = json_object_get (json_link, iter_key);
if (!json_element) {
json_element = json_object ();
json_object_set_new (json_link, iter_key, json_element);
}
iter_key = key3;
}
json_object_set_new (json_element, iter_key, json_value);
done:
if (updated) {
g_free (*conf);
*conf = json_dumps (json, 0);
/* Don't save an empty config */
if (nm_streq0 (*conf, "{}")) {
g_free (*conf);
*conf = NULL;
}
}
json_decref (json);
return updated;
}
#else /* WITH_JANSSON */
gboolean
@ -4491,6 +4769,26 @@ _nm_utils_team_config_equal (const char *conf1,
{
return nm_streq0 (conf1, conf2);
}
GValue *
_nm_utils_team_config_get (const char *conf,
const char *key,
const char *key2,
const char *key3,
gboolean port_config)
{
return NULL;
}
gboolean
_nm_utils_team_config_set (char **conf,
const char *key,
const char *key2,
const char *key3,
const GValue *value)
{
return FALSE;
}
#endif
static char *

View file

@ -146,4 +146,18 @@
# define NM_AVAILABLE_IN_1_10
#endif
#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_12
# define NM_DEPRECATED_IN_1_12 G_DEPRECATED
# define NM_DEPRECATED_IN_1_12_FOR(f) G_DEPRECATED_FOR(f)
#else
# define NM_DEPRECATED_IN_1_12
# define NM_DEPRECATED_IN_1_12_FOR(f)
#endif
#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_12
# define NM_AVAILABLE_IN_1_12 G_UNAVAILABLE(1,12)
#else
# define NM_AVAILABLE_IN_1_12
#endif
#endif /* NM_VERSION_H */

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!-- A lame duck typelib which prevents GIR from loading the
real one (which would crash due to conflict with libnm) -->
<repository version="1.2"
xmlns="http://www.gtk.org/introspection/core/1.0"
xmlns:c="http://www.gtk.org/introspection/c/1.0"
xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
<namespace name="NMClient" version="0.0" />
</repository>

View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- A lame duck typelib which prevents GIR from loading the
real one (which would crash due to conflict with libnm) -->
<repository version="1.2"
xmlns="http://www.gtk.org/introspection/core/1.0"
xmlns:c="http://www.gtk.org/introspection/c/1.0"
xmlns:glib="http://www.gtk.org/introspection/glib/1.0">
<namespace name="NetworkManager" version="0.0">
</namespace>
</repository>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/freedesktop/libnm/fake-typelib">
<file>NetworkManager.typelib</file>
<file>NMClient.typelib</file>
</gresource>
</gresources>

View file

@ -1221,3 +1221,41 @@ global:
nm_setting_wireless_security_pmf_get_type;
nm_setting_wireless_security_wps_method_get_type;
} libnm_1_8_0;
libnm_1_12_0 {
global:
nm_checkpoint_get_created;
nm_checkpoint_get_devices;
nm_checkpoint_get_rollback_timeout;
nm_checkpoint_get_type;
nm_client_checkpoint_create_async;
nm_client_checkpoint_create_finish;
nm_client_checkpoint_destroy_async;
nm_client_checkpoint_destroy_finish;
nm_client_checkpoint_rollback_async;
nm_client_checkpoint_rollback_finish;
nm_client_get_checkpoints;
nm_setting_team_add_runner_tx_hash;
nm_setting_team_get_mcast_rejoin_count;
nm_setting_team_get_mcast_rejoin_interval;
nm_setting_team_get_notify_peers_count;
nm_setting_team_get_notify_peers_interval;
nm_setting_team_get_num_runner_tx_hash;
nm_setting_team_get_runner;
nm_setting_team_get_runner_hwaddr_policy;
nm_setting_team_get_runner_tx_balancer;
nm_setting_team_get_runner_tx_balancer_interval;
nm_setting_team_get_runner_tx_hash;
nm_setting_team_get_runner_active;
nm_setting_team_get_runner_fast_rate;
nm_setting_team_get_runner_sys_prio;
nm_setting_team_get_runner_min_ports;
nm_setting_team_get_runner_agg_select_policy;
nm_setting_team_port_get_queue_id;
nm_setting_team_port_get_prio;
nm_setting_team_port_get_sticky;
nm_setting_team_port_get_lacp_prio;
nm_setting_team_port_get_lacp_key;
nm_setting_team_remove_runner_tx_hash;
nm_setting_team_remove_runner_tx_hash_by_value;
} libnm_1_10_0;

219
libnm/nm-checkpoint.c Normal file
View file

@ -0,0 +1,219 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-checkpoint.h"
#include "nm-core-internal.h"
#include "nm-dbus-interface.h"
#include "nm-device.h"
#include "nm-object-private.h"
typedef struct {
GPtrArray *devices;
gint64 created;
guint32 rollback_timeout;
} NMCheckpointPrivate;
struct _NMCheckpoint {
NMObject parent;
NMCheckpointPrivate _priv;
};
struct _NMCheckpointClass {
NMObjectClass parent;
};
G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_OBJECT)
#define NM_CHECKPOINT_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMCheckpoint, NM_IS_CHECKPOINT)
enum {
PROP_0,
PROP_DEVICES,
PROP_CREATED,
PROP_ROLLBACK_TIMEOUT,
LAST_PROP
};
/**
* nm_checkpoint_get_devices:
* @checkpoint: a #NMCheckpoint
*
* The devices that are part of this checkpoint.
*
* Returns: (element-type NMDevice): the devices list.
*
* Since: 1.12
**/
const GPtrArray *
nm_checkpoint_get_devices (NMCheckpoint *checkpoint)
{
g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), NULL);
return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->devices;
}
/**
* nm_checkpoint_get_created:
* @checkpoint: a #NMCheckpoint
*
* Gets the timestamp (in CLOCK_BOOTTIME milliseconds)
* of checkpoint creation.
*
* Returns: the timestamp of checkpoint creation.
*
* Since: 1.12
**/
gint64
nm_checkpoint_get_created (NMCheckpoint *checkpoint)
{
g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), 0);
return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->created;
}
/**
* nm_checkpoint_get_rollback_timeout:
* @checkpoint: a #NMCheckpoint
*
* Gets the the timeout in seconds for automatic rollback.
*
* Returns: the rollback timeout.
*
* Since: 1.12
**/
guint32
nm_checkpoint_get_rollback_timeout (NMCheckpoint *checkpoint)
{
g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), 0);
return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->rollback_timeout;
}
/*****************************************************************************/
static void
nm_checkpoint_init (NMCheckpoint *checkpoint)
{
}
static void
finalize (GObject *object)
{
NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object));
g_ptr_array_unref (priv->devices);
G_OBJECT_CLASS (nm_checkpoint_parent_class)->finalize (object);
}
static void
get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMCheckpoint *checkpoint = NM_CHECKPOINT (object);
NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (checkpoint);
switch (prop_id) {
case PROP_DEVICES:
g_value_take_boxed (value, _nm_utils_copy_object_array (priv->devices));
break;
case PROP_CREATED:
g_value_set_int64 (value, priv->created);
break;
case PROP_ROLLBACK_TIMEOUT:
g_value_set_uint (value, priv->rollback_timeout);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
init_dbus (NMObject *object)
{
NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object));
const NMPropertiesInfo property_info[] = {
{ NM_CHECKPOINT_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE },
{ NM_CHECKPOINT_CREATED, &priv->created },
{ NM_CHECKPOINT_ROLLBACK_TIMEOUT, &priv->rollback_timeout },
{ NULL },
};
NM_OBJECT_CLASS (nm_checkpoint_parent_class)->init_dbus (object);
_nm_object_register_properties (object,
NM_DBUS_INTERFACE_CHECKPOINT,
property_info);
}
static void
nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (checkpoint_class);
NMObjectClass *nm_object_class = NM_OBJECT_CLASS (checkpoint_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
nm_object_class->init_dbus = init_dbus;
/**
* NMCheckpoint:devices:
*
* The devices that are part of this checkpoint.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_DEVICES,
g_param_spec_boxed (NM_CHECKPOINT_DEVICES, "", "",
G_TYPE_PTR_ARRAY,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMCheckpoint:created:
*
* The timestamp (in CLOCK_BOOTTIME milliseconds) of checkpoint creation.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_CREATED,
g_param_spec_int64 (NM_CHECKPOINT_CREATED, "", "",
G_MININT64, G_MAXINT64, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMCheckpoint:rollback-timeout:
*
* Timeout in seconds for automatic rollback, or zero.
*
* Since: 1.12
**/
g_object_class_install_property
(object_class, PROP_ROLLBACK_TIMEOUT,
g_param_spec_uint (NM_CHECKPOINT_ROLLBACK_TIMEOUT, "", "",
0, G_MAXUINT32, 0,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
}

53
libnm/nm-checkpoint.h Normal file
View file

@ -0,0 +1,53 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_CHECKPOINT_H__
#define __NM_CHECKPOINT_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-object.h"
G_BEGIN_DECLS
#define NM_TYPE_CHECKPOINT (nm_checkpoint_get_type ())
#define NM_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CHECKPOINT, NMCheckpoint))
#define NM_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CHECKPOINT, NMCheckpointClass))
#define NM_IS_CHECKPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CHECKPOINT))
#define NM_IS_CHECKPOINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_CHECKPOINT))
#define NM_CHECKPOINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CHECKPOINT, NMCheckpointClass))
#define NM_CHECKPOINT_DEVICES "devices"
#define NM_CHECKPOINT_CREATED "created"
#define NM_CHECKPOINT_ROLLBACK_TIMEOUT "rollback-timeout"
/**
* NMCheckpoint:
*/
typedef struct _NMCheckpointClass NMCheckpointClass;
GType nm_checkpoint_get_type (void);
NM_AVAILABLE_IN_1_12
const GPtrArray *nm_checkpoint_get_devices (NMCheckpoint *checkpoint);
NM_AVAILABLE_IN_1_12
gint64 nm_checkpoint_get_created (NMCheckpoint *checkpoint);
NM_AVAILABLE_IN_1_12
guint32 nm_checkpoint_get_rollback_timeout (NMCheckpoint *checkpoint);
G_END_DECLS
#endif /* __NM_CHECKPOINT_H__ */

View file

@ -50,6 +50,7 @@
#include "nm-access-point.h"
#include "nm-active-connection.h"
#include "nm-checkpoint.h"
#include "nm-device-adsl.h"
#include "nm-device-bond.h"
#include "nm-device-bridge.h"
@ -139,6 +140,7 @@ enum {
PROP_DNS_MODE,
PROP_DNS_RC_MANAGER,
PROP_DNS_CONFIGURATION,
PROP_CHECKPOINTS,
LAST_PROP
};
@ -2058,6 +2060,294 @@ dns_notify (GObject *object,
}
}
static void
checkpoint_create_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
NMCheckpoint *checkpoint;
GError *error = NULL;
checkpoint = nm_manager_checkpoint_create_finish (NM_MANAGER (object), result, &error);
if (checkpoint)
g_simple_async_result_set_op_res_gpointer (simple, checkpoint, g_object_unref);
else
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
/**
* nm_client_get_checkpoints:
* @client: a #NMClient
*
* Gets all the active checkpoints.
*
* Returns: (transfer none) (element-type NMCheckpoint): a #GPtrArray
* containing all the #NMCheckpoint. The returned array is owned by the
* #NMClient object and should not be modified.
*
* Since: 1.12
**/
const GPtrArray *
nm_client_get_checkpoints (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
if (!nm_client_get_nm_running (client))
return &empty;
return nm_manager_get_checkpoints (NM_CLIENT_GET_PRIVATE (client)->manager);
}
/**
* nm_client_checkpoint_create_async:
* @client: the %NMClient
* @devices: (element-type NMDevice): a list of devices for which a
* checkpoint should be created.
* @rollback_timeout: the rollback timeout in seconds
* @flags: creation flags
* @cancellable: a #GCancellable, or %NULL
* @callback: (scope async): callback to be called when the add operation completes
* @user_data: (closure): caller-specific data passed to @callback
*
* Creates a checkpoint of the current networking configuration
* for given interfaces. An empty @devices argument means all
* devices. If @rollback_timeout is not zero, a rollback is
* automatically performed after the given timeout.
*
* Since: 1.12
**/
void
nm_client_checkpoint_create_async (NMClient *client,
const GPtrArray *devices,
guint32 rollback_timeout,
NMCheckpointCreateFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (NM_IS_CLIENT (client));
if (!_nm_client_check_nm_running (client, &error)) {
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
return;
}
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
nm_client_checkpoint_create_async);
nm_manager_checkpoint_create_async (NM_CLIENT_GET_PRIVATE (client)->manager,
devices, rollback_timeout, flags,
cancellable, checkpoint_create_cb, simple);
}
/**
* nm_client_checkpoint_create_finish:
* @client: the #NMClient
* @result: the result passed to the #GAsyncReadyCallback
* @error: location for a #GError, or %NULL
*
* Gets the result of a call to nm_client_checkpoint_create_async().
*
* Returns: (transfer full): the new #NMCheckpoint on success, %NULL on
* failure, in which case @error will be set.
*
* Since: 1.12
**/
NMCheckpoint *
nm_client_checkpoint_create_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
else
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
}
static void
checkpoint_destroy_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
if (nm_manager_checkpoint_destroy_finish (NM_MANAGER (object), result, &error))
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
else
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
/**
* nm_client_checkpoint_destroy_async:
* @client: the %NMClient
* @checkpoint: a checkpoint
* @cancellable: a #GCancellable, or %NULL
* @callback: (scope async): callback to be called when the add operation completes
* @user_data: (closure): caller-specific data passed to @callback
*
* Destroys an existing checkpoint without performing a rollback.
*
* Since: 1.12
**/
void
nm_client_checkpoint_destroy_async (NMClient *client,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (NM_IS_CLIENT (client));
if (!_nm_client_check_nm_running (client, &error)) {
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
return;
}
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
nm_client_checkpoint_destroy_async);
nm_manager_checkpoint_destroy_async (NM_CLIENT_GET_PRIVATE (client)->manager,
checkpoint,
cancellable, checkpoint_destroy_cb, simple);
}
/**
* nm_client_checkpoint_destroy_finish:
* @client: an #NMClient
* @result: the result passed to the #GAsyncReadyCallback
* @error: location for a #GError, or %NULL
*
* Gets the result of a call to nm_client_checkpoint_destroy_async().
*
* Returns: %TRUE on success or %FALSE on failure, in which case
* @error will be set.
*
* Since: 1.12
**/
gboolean
nm_client_checkpoint_destroy_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
else
return g_simple_async_result_get_op_res_gboolean (simple);
}
static void
checkpoint_rollback_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
GHashTable *hash;
GError *error = NULL;
hash = nm_manager_checkpoint_rollback_finish (NM_MANAGER (object), result, &error);
if (hash)
g_simple_async_result_set_op_res_gpointer (simple, hash, (GDestroyNotify) g_hash_table_unref);
else
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
/**
* nm_client_checkpoint_rollback_async:
* @client: the %NMClient
* @checkpoint: a checkpoint
* @cancellable: a #GCancellable, or %NULL
* @callback: (scope async): callback to be called when the add operation completes
* @user_data: (closure): caller-specific data passed to @callback
*
* Performs the rollback of a checkpoint before the timeout is reached.
*
* Since: 1.12
**/
void
nm_client_checkpoint_rollback_async (NMClient *client,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *simple;
GError *error = NULL;
g_return_if_fail (NM_IS_CLIENT (client));
if (!_nm_client_check_nm_running (client, &error)) {
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
return;
}
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
nm_client_checkpoint_rollback_async);
nm_manager_checkpoint_rollback_async (NM_CLIENT_GET_PRIVATE (client)->manager,
checkpoint,
cancellable, checkpoint_rollback_cb, simple);
}
/**
* nm_client_checkpoint_rollback_finish:
* @client: an #NMClient
* @result: the result passed to the #GAsyncReadyCallback
* @error: location for a #GError, or %NULL
*
* Gets the result of a call to nm_client_checkpoint_rollback_async().
*
* Returns: (transfer full) (element-type utf8 guint32): an hash table of
* devices and results. Devices are represented by their original
* D-Bus path; each result is a #NMRollbackResult.
*
* Since: 1.12
**/
GHashTable *
nm_client_checkpoint_rollback_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
GHashTable *hash;
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
else {
hash = g_simple_async_result_get_op_res_gpointer (simple);
return g_hash_table_ref (hash);
}
}
/****************************************************************/
/* Object Initialization */
/****************************************************************/
@ -2188,6 +2478,8 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager
type = NM_TYPE_VPN_CONNECTION;
else if (strcmp (ifname, NM_DBUS_INTERFACE_WIMAX_NSP) == 0)
type = NM_TYPE_WIMAX_NSP;
else if (strcmp (ifname, NM_DBUS_INTERFACE_CHECKPOINT) == 0)
type = NM_TYPE_CHECKPOINT;
if (type != G_TYPE_INVALID)
break;
@ -2763,6 +3055,12 @@ get_property (GObject *object, guint prop_id,
case PROP_ALL_DEVICES:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_all_devices (self)));
break;
case PROP_CHECKPOINTS:
if (priv->manager)
g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
else
g_value_take_boxed (value, g_ptr_array_new ());
break;
/* Settings properties. */
case PROP_CONNECTIONS:
@ -3169,6 +3467,20 @@ nm_client_class_init (NMClientClass *client_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMClient::checkpoints
*
* The list of active checkpoints.
*
* Since: 1.12
*/
g_object_class_install_property
(object_class, PROP_CHECKPOINTS,
g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "",
G_TYPE_PTR_ARRAY,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/* signals */
/**

View file

@ -403,6 +403,45 @@ const char *nm_client_get_dns_rc_manager (NMClient *client);
NM_AVAILABLE_IN_1_6
const GPtrArray *nm_client_get_dns_configuration (NMClient *client);
NM_AVAILABLE_IN_1_12
const GPtrArray *nm_client_get_checkpoints (NMClient *client);
NM_AVAILABLE_IN_1_12
void nm_client_checkpoint_create_async (NMClient *client,
const GPtrArray *devices,
guint32 rollback_timeout,
NMCheckpointCreateFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NM_AVAILABLE_IN_1_12
NMCheckpoint *nm_client_checkpoint_create_finish (NMClient *client,
GAsyncResult *result,
GError **error);
NM_AVAILABLE_IN_1_12
void nm_client_checkpoint_destroy_async (NMClient *client,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NM_AVAILABLE_IN_1_12
gboolean nm_client_checkpoint_destroy_finish (NMClient *client,
GAsyncResult *result,
GError **error);
NM_AVAILABLE_IN_1_12
void nm_client_checkpoint_rollback_async (NMClient *client,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NM_AVAILABLE_IN_1_12
GHashTable *nm_client_checkpoint_rollback_finish (NMClient *client,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __NM_CLIENT_H__ */

View file

@ -23,6 +23,8 @@
#include "nm-libnm-utils.h"
#include <girepository.h>
/*****************************************************************************/
char *
@ -160,3 +162,83 @@ next:
nm_assert (g_utf8_validate (desc_full, -1, NULL));
return desc_full;
}
#if WITH_FAKE_TYPELIBS
/*
* Here we register empty "NMClient" and "NetworkManager" GIR modules as soon
* as we are loaded (if gnome-introspection is being used). This prevents the
* real modules from being loaded because they would in turn load libnm-glib
* and abort() and crash.
*
* For the high level languages that utilize GIR the crash is highly inconvenient
* while the inability to resolve any methods and attributes is potentially
* recoverable.
*/
GResource *typelibs_get_resource (void);
void typelibs_register_resource (void);
static void __attribute__((constructor))
_nm_libnm_utils_init (void)
{
GITypelib *typelib;
GBytes *data;
const char *namespace;
GModule *self;
GITypelib *(*_g_typelib_new_from_const_memory) (const guint8 *memory,
gsize len,
GError **error) = NULL;
const char *(*_g_irepository_load_typelib) (GIRepository *repository,
GITypelib *typelib,
GIRepositoryLoadFlags flags,
GError **error) = NULL;
const char *names[] = { "/org/freedesktop/libnm/fake-typelib/NetworkManager.typelib",
"/org/freedesktop/libnm/fake-typelib/NMClient.typelib" };
int i;
self = g_module_open (NULL, 0);
if (!self)
return;
g_module_symbol (self, "g_typelib_new_from_const_memory",
(gpointer *) &_g_typelib_new_from_const_memory);
if (_g_typelib_new_from_const_memory) {
g_module_symbol (self, "g_irepository_load_typelib",
(gpointer *) &_g_irepository_load_typelib);
}
g_module_close (self);
if (!_g_typelib_new_from_const_memory || !_g_irepository_load_typelib)
return;
typelibs_register_resource ();
for (i = 0; i < 2; i++) {
gs_free_error GError *error = NULL;
data = g_resource_lookup_data (typelibs_get_resource (),
names[i],
G_RESOURCE_LOOKUP_FLAGS_NONE,
&error);
if (!data) {
g_warning ("Fake typelib %s could not be loaded: %s", names[i], error->message);
return;
}
typelib = _g_typelib_new_from_const_memory (g_bytes_get_data (data, NULL),
g_bytes_get_size (data),
&error);
if (!typelib) {
g_warning ("Could not create fake typelib instance %s: %s", names[i], error->message);
return;
}
namespace = _g_irepository_load_typelib (NULL, typelib, 0, &error);
if (!namespace) {
g_warning ("Could not load fake typelib %s: %s", names[i], error->message);
return;
}
}
}
#endif /* WITH_FAKE_TYPELIBS */

View file

@ -26,6 +26,7 @@
#include <string.h>
#include "nm-utils.h"
#include "nm-checkpoint.h"
#include "nm-common-macros.h"
#include "nm-device-ethernet.h"
#include "nm-device-wifi.h"
@ -61,6 +62,8 @@ typedef struct {
GPtrArray *devices;
GPtrArray *all_devices;
GPtrArray *active_connections;
GPtrArray *checkpoints;
GSList *added_checkpoints;
NMConnectivityState connectivity;
NMActiveConnection *primary_connection;
NMActiveConnection *activating_connection;
@ -107,6 +110,7 @@ enum {
PROP_PRIMARY_CONNECTION,
PROP_ACTIVATING_CONNECTION,
PROP_DEVICES,
PROP_CHECKPOINTS,
PROP_METERED,
PROP_ALL_DEVICES,
@ -120,6 +124,8 @@ enum {
ANY_DEVICE_REMOVED,
ACTIVE_CONNECTION_ADDED,
ACTIVE_CONNECTION_REMOVED,
CHECKPOINT_ADDED,
CHECKPOINT_REMOVED,
PERMISSION_CHANGED,
LAST_SIGNAL
@ -129,6 +135,53 @@ static guint signals[LAST_SIGNAL] = { 0 };
/*****************************************************************************/
typedef struct {
NMManager *manager;
GSimpleAsyncResult *simple;
char *path;
} CheckpointInfo;
static CheckpointInfo *
find_checkpoint_info (NMManager *manager, const char *path)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
CheckpointInfo *info;
GSList *iter;
for (iter = priv->added_checkpoints; iter; iter = g_slist_next (iter)) {
info = iter->data;
if (nm_streq (path, info->path))
return info;
}
return NULL;
}
static void
checkpoint_info_complete (NMManager *self,
CheckpointInfo *info,
NMCheckpoint *checkpoint,
GError *error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
g_return_if_fail (info);
if (checkpoint) {
g_simple_async_result_set_op_res_gpointer (info->simple,
g_object_ref (checkpoint),
g_object_unref);
} else
g_simple_async_result_set_from_error (info->simple, error);
g_simple_async_result_complete (info->simple);
g_object_unref (info->simple);
priv->added_checkpoints = g_slist_remove (priv->added_checkpoints, info);
g_free (info->path);
g_slice_free (CheckpointInfo, info);
}
static void
nm_manager_init (NMManager *manager)
{
@ -189,6 +242,7 @@ init_dbus (NMObject *object)
{ NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
{ NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
{ NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
{ NM_MANAGER_CHECKPOINTS, &priv->checkpoints, NULL, NM_TYPE_CHECKPOINT, "checkpoint" },
{ NM_MANAGER_METERED, &priv->metered },
{ NM_MANAGER_ALL_DEVICES, &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" },
{ NULL },
@ -206,6 +260,23 @@ init_dbus (NMObject *object)
G_CALLBACK (manager_recheck_permissions), object, 0);
}
static void
object_creation_failed (NMObject *object, const char *failed_path)
{
NMManager *self = NM_MANAGER (object);
CheckpointInfo *info;
GError *add_error;
info = find_checkpoint_info (self, failed_path);
if (info) {
add_error = g_error_new_literal (NM_CLIENT_ERROR,
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
_("Checkpoint was removed before it was initialized"));
checkpoint_info_complete (self, info, NULL, add_error);
g_error_free (add_error);
}
}
static NMClientPermission
nm_permission_to_client (const char *nm)
{
@ -1109,6 +1180,21 @@ active_connection_removed (NMManager *self, NMActiveConnection *ac)
recheck_pending_activations (self);
}
static void
checkpoint_added (NMManager *manager, NMCheckpoint *checkpoint)
{
CheckpointInfo *info;
info = find_checkpoint_info (manager, nm_object_get_path (NM_OBJECT (checkpoint)));
if (info)
checkpoint_info_complete (manager, info, checkpoint, NULL);
}
static void
checkpoint_removed (NMManager *manager, NMCheckpoint *checkpoint)
{
}
gboolean
nm_manager_deactivate_connection (NMManager *manager,
NMActiveConnection *active,
@ -1208,6 +1294,226 @@ free_active_connections (NMManager *manager)
/*****************************************************************************/
static const char **
get_device_paths (const GPtrArray *devices)
{
const char **array;
guint i;
array = g_new (const char *, devices->len + 1);
for (i = 0; i < devices->len; i++)
array[i] = nm_object_get_path (NM_OBJECT (devices->pdata[i]));
array[i] = NULL;
return array;
}
const GPtrArray *
nm_manager_get_checkpoints (NMManager *manager)
{
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
return NM_MANAGER_GET_PRIVATE (manager)->checkpoints;
}
static void
checkpoint_created_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
CheckpointInfo *info = user_data;
GError *error = NULL;
nmdbus_manager_call_checkpoint_create_finish (NMDBUS_MANAGER (object),
&info->path, result, &error);
if (error) {
g_dbus_error_strip_remote_error (error);
checkpoint_info_complete (info->manager, info, NULL, error);
g_clear_error (&error);
}
}
void
nm_manager_checkpoint_create_async (NMManager *manager,
const GPtrArray *devices,
guint32 rollback_timeout,
NMCheckpointCreateFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
gs_free const char **paths = NULL;
CheckpointInfo *info;
g_return_if_fail (NM_IS_MANAGER (manager));
info = g_slice_new0 (CheckpointInfo);
info->manager = manager;
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
nm_manager_checkpoint_create_async);
paths = get_device_paths (devices);
nmdbus_manager_call_checkpoint_create (NM_MANAGER_GET_PRIVATE (manager)->proxy,
paths,
rollback_timeout,
flags,
cancellable,
checkpoint_created_cb,
info);
priv->added_checkpoints = g_slist_append (priv->added_checkpoints, info);
}
NMCheckpoint *
nm_manager_checkpoint_create_finish (NMManager *manager,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
else
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
}
static void
checkpoint_destroy_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
if (nmdbus_manager_call_checkpoint_destroy_finish (NMDBUS_MANAGER (object),
result, &error))
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
else {
g_dbus_error_strip_remote_error (error);
g_simple_async_result_take_error (simple, error);
}
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
void
nm_manager_checkpoint_destroy_async (NMManager *manager,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
const char *path;
GSimpleAsyncResult *simple;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_CHECKPOINT (checkpoint));
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
nm_manager_checkpoint_destroy_async);
path = nm_object_get_path (NM_OBJECT (checkpoint));
nmdbus_manager_call_checkpoint_destroy (NM_MANAGER_GET_PRIVATE (manager)->proxy,
path,
cancellable,
checkpoint_destroy_cb, simple);
}
gboolean
nm_manager_checkpoint_destroy_finish (NMManager *manager,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager),
nm_manager_checkpoint_destroy_async),
FALSE);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
else
return g_simple_async_result_get_op_res_gboolean (simple);
}
static void
checkpoint_rollback_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GSimpleAsyncResult *simple = user_data;
GError *error = NULL;
GVariant *variant = NULL;
GVariantIter iter;
GHashTable *hash;
const char *path;
guint r;
if (nmdbus_manager_call_checkpoint_rollback_finish (NMDBUS_MANAGER (object),
&variant,
result,
&error)) {
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_variant_iter_init (&iter, variant);
while (g_variant_iter_next (&iter, "{&su}", &path, &r))
g_hash_table_insert (hash, g_strdup (path), GUINT_TO_POINTER (r));
g_simple_async_result_set_op_res_gpointer (simple, hash, (GDestroyNotify) g_hash_table_unref);
} else {
g_dbus_error_strip_remote_error (error);
g_simple_async_result_take_error (simple, error);
}
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
void
nm_manager_checkpoint_rollback_async (NMManager *manager,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
const char *path;
GSimpleAsyncResult *simple;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_CHECKPOINT (checkpoint));
simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
nm_manager_checkpoint_rollback_async);
path = nm_object_get_path (NM_OBJECT (checkpoint));
nmdbus_manager_call_checkpoint_rollback (NM_MANAGER_GET_PRIVATE (manager)->proxy,
path,
cancellable,
checkpoint_rollback_cb, simple);
}
GHashTable *
nm_manager_checkpoint_rollback_finish (NMManager *manager,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager),
nm_manager_checkpoint_rollback_async),
NULL);
simple = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (simple, error))
return NULL;
else
return g_simple_async_result_get_op_res_gpointer (simple);
}
/*****************************************************************************/
static void
constructed (GObject *object)
{
@ -1472,6 +1778,9 @@ get_property (GObject *object,
case PROP_DEVICES:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
break;
case PROP_CHECKPOINTS:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_checkpoints (self)));
break;
case PROP_METERED:
g_value_set_uint (value, priv->metered);
break;
@ -1500,11 +1809,14 @@ nm_manager_class_init (NMManagerClass *manager_class)
object_class->finalize = finalize;
nm_object_class->init_dbus = init_dbus;
nm_object_class->object_creation_failed = object_creation_failed;
manager_class->device_added = device_added;
manager_class->device_removed = device_removed;
manager_class->active_connection_added = active_connection_added;
manager_class->active_connection_removed = active_connection_removed;
manager_class->checkpoint_added = checkpoint_added;
manager_class->checkpoint_removed = checkpoint_removed;
/* properties */
@ -1612,6 +1924,12 @@ nm_manager_class_init (NMManagerClass *manager_class)
G_TYPE_PTR_ARRAY,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_CHECKPOINTS,
g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "",
G_TYPE_PTR_ARRAY,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMManager:metered:
*
@ -1683,6 +2001,23 @@ nm_manager_class_init (NMManagerClass *manager_class)
NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
signals[CHECKPOINT_ADDED] =
g_signal_new ("checkpoint-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMManagerClass, checkpoint_added),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
signals[CHECKPOINT_REMOVED] =
g_signal_new ("checkpoint-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMManagerClass, checkpoint_removed),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
signals[PERMISSION_CHANGED] =
g_signal_new ("permission-changed",
G_OBJECT_CLASS_TYPE (object_class),

View file

@ -51,6 +51,7 @@ G_BEGIN_DECLS
#define NM_MANAGER_PRIMARY_CONNECTION "primary-connection"
#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
#define NM_MANAGER_DEVICES "devices"
#define NM_MANAGER_CHECKPOINTS "checkpoints"
#define NM_MANAGER_METERED "metered"
#define NM_MANAGER_ALL_DEVICES "all-devices"
@ -69,6 +70,8 @@ typedef struct {
void (*device_removed) (NMManager *manager, NMDevice *device);
void (*active_connection_added) (NMManager *manager, NMActiveConnection *ac);
void (*active_connection_removed) (NMManager *manager, NMActiveConnection *ac);
void (*checkpoint_added) (NMManager *manager, NMCheckpoint *checkpoint);
void (*checkpoint_removed) (NMManager *manager, NMCheckpoint *checkpoint);
void (*permission_changed) (NMManager *manager,
NMClientPermission permission,
NMClientPermissionResult result);
@ -184,6 +187,34 @@ gboolean nm_manager_deactivate_connection_finish (NMManager *manager,
GAsyncResult *result,
GError **error);
const GPtrArray *nm_manager_get_checkpoints (NMManager *manager);
void nm_manager_checkpoint_create_async (NMManager *manager,
const GPtrArray *devices,
guint32 rollback_timeout,
NMCheckpointCreateFlags flags,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
NMCheckpoint *nm_manager_checkpoint_create_finish (NMManager *manager,
GAsyncResult *result,
GError **error);
void nm_manager_checkpoint_destroy_async (NMManager *manager,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean nm_manager_checkpoint_destroy_finish (NMManager *manager,
GAsyncResult *result,
GError **error);
void nm_manager_checkpoint_rollback_async (NMManager *manager,
NMCheckpoint *checkpoint,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GHashTable *nm_manager_checkpoint_rollback_finish (NMManager *manager,
GAsyncResult *result,
GError **error);
G_END_DECLS
#endif /* __NM_MANAGER_H__ */

View file

@ -28,6 +28,7 @@
typedef struct _NMAccessPoint NMAccessPoint;
typedef struct _NMActiveConnection NMActiveConnection;
typedef struct _NMCheckpoint NMCheckpoint;
typedef struct _NMClient NMClient;
typedef struct _NMDevice NMDevice;
typedef struct _NMDeviceAdsl NMDeviceAdsl;

3888
po/ar.po

File diff suppressed because it is too large Load diff

3928
po/as.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3989
po/bg.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3886
po/bs.po

File diff suppressed because it is too large Load diff

3942
po/ca.po

File diff suppressed because it is too large Load diff

3966
po/cs.po

File diff suppressed because it is too large Load diff

3971
po/da.po

File diff suppressed because it is too large Load diff

3221
po/de.po

File diff suppressed because it is too large Load diff

3892
po/dz.po

File diff suppressed because it is too large Load diff

3937
po/el.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3927
po/eo.po

File diff suppressed because it is too large Load diff

3998
po/es.po

File diff suppressed because it is too large Load diff

3876
po/et.po

File diff suppressed because it is too large Load diff

3964
po/eu.po

File diff suppressed because it is too large Load diff

3945
po/fi.po

File diff suppressed because it is too large Load diff

4028
po/fr.po

File diff suppressed because it is too large Load diff

3930
po/gd.po

File diff suppressed because it is too large Load diff

3934
po/gl.po

File diff suppressed because it is too large Load diff

3929
po/gu.po

File diff suppressed because it is too large Load diff

3869
po/he.po

File diff suppressed because it is too large Load diff

4006
po/hi.po

File diff suppressed because it is too large Load diff

3961
po/hr.po

File diff suppressed because it is too large Load diff

3948
po/hu.po

File diff suppressed because it is too large Load diff

3944
po/id.po

File diff suppressed because it is too large Load diff

3943
po/it.po

File diff suppressed because it is too large Load diff

3916
po/ja.po

File diff suppressed because it is too large Load diff

3915
po/ka.po

File diff suppressed because it is too large Load diff

3942
po/kn.po

File diff suppressed because it is too large Load diff

3934
po/ko.po

File diff suppressed because it is too large Load diff

3922
po/ku.po

File diff suppressed because it is too large Load diff

3937
po/lt.po

File diff suppressed because it is too large Load diff

3909
po/lv.po

File diff suppressed because it is too large Load diff

3870
po/mk.po

File diff suppressed because it is too large Load diff

3934
po/ml.po

File diff suppressed because it is too large Load diff

3930
po/mr.po

File diff suppressed because it is too large Load diff

3873
po/nb.po

File diff suppressed because it is too large Load diff

3888
po/ne.po

File diff suppressed because it is too large Load diff

3877
po/nl.po

File diff suppressed because it is too large Load diff

3922
po/oc.po

File diff suppressed because it is too large Load diff

3931
po/or.po

File diff suppressed because it is too large Load diff

3933
po/pa.po

File diff suppressed because it is too large Load diff

2187
po/pl.po

File diff suppressed because it is too large Load diff

3890
po/pt.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3944
po/ru.po

File diff suppressed because it is too large Load diff

3901
po/rw.po

File diff suppressed because it is too large Load diff

3908
po/sk.po

File diff suppressed because it is too large Load diff

3944
po/sl.po

File diff suppressed because it is too large Load diff

3881
po/sq.po

File diff suppressed because it is too large Load diff

3993
po/sr.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,8 +7,9 @@
msgid ""
msgstr ""
"Project-Id-Version: NetworkManager\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-11-10 15:29+0100\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?"
"product=NetworkManager&keywords=I18N+L10N&component=Translations\n"
"POT-Creation-Date: 2017-11-06 15:24+0000\n"
"PO-Revision-Date: 2017-11-07 15:38+0100\n"
"Last-Translator: Josef Andersson <l10nl18nsweja@gmail.com>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@ -5682,7 +5683,7 @@ msgstr "Användarinställningar"
msgid "VLAN connection"
msgstr "VLAN-anslutning"
#: ../clients/common/nm-meta-setting-desc.c:6818 ../src/nm-manager.c:4191
#: ../clients/common/nm-meta-setting-desc.c:6818 ../src/nm-manager.c:4213
msgid "VPN connection"
msgstr "VPN-anslutning"
@ -12566,7 +12567,7 @@ msgstr "TUN-anslutning"
msgid "Team connection"
msgstr "Gruppanslutning"
#: ../src/devices/wifi/nm-device-olpc-mesh.c:152
#: ../src/devices/wifi/nm-device-olpc-mesh.c:156
msgid "Mesh"
msgstr "Mesh"

3944
po/ta.po

File diff suppressed because it is too large Load diff

3933
po/te.po

File diff suppressed because it is too large Load diff

3915
po/th.po

File diff suppressed because it is too large Load diff

3947
po/tr.po

File diff suppressed because it is too large Load diff

1219
po/uk.po

File diff suppressed because it is too large Load diff

3875
po/vi.po

File diff suppressed because it is too large Load diff

3893
po/wa.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more