merge: branch 'lr/ovs'

https://bugzilla.redhat.com/show_bug.cgi?id=1470282
This commit is contained in:
Lubomir Rintel 2017-10-30 21:48:22 +01:00
commit 79168a5434
64 changed files with 6235 additions and 414 deletions

View file

@ -206,6 +206,12 @@ introspection_sources = \
introspection/org.freedesktop.NetworkManager.Device.Modem.h \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.c \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.h \
introspection/org.freedesktop.NetworkManager.Device.OvsInterface.c \
introspection/org.freedesktop.NetworkManager.Device.OvsInterface.h \
introspection/org.freedesktop.NetworkManager.Device.OvsPort.c \
introspection/org.freedesktop.NetworkManager.Device.OvsPort.h \
introspection/org.freedesktop.NetworkManager.Device.OvsBridge.c \
introspection/org.freedesktop.NetworkManager.Device.OvsBridge.h \
introspection/org.freedesktop.NetworkManager.Device.Ppp.c \
introspection/org.freedesktop.NetworkManager.Device.Ppp.h \
introspection/org.freedesktop.NetworkManager.Device.Statistics.c \
@ -281,6 +287,9 @@ DBUS_INTERFACE_DOCS = \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Tun.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Bridge.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.OlpcMesh.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.OvsInterface.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.OvsPort.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.OvsBridge.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Ppp.xml \
docs/api/dbus-org.freedesktop.NetworkManager.DHCP4Config.xml \
docs/api/dbus-org.freedesktop.NetworkManager.Device.Generic.xml \
@ -329,6 +338,9 @@ dbusinterfaces_DATA = \
introspection/org.freedesktop.NetworkManager.Device.Macvlan.xml \
introspection/org.freedesktop.NetworkManager.Device.Modem.xml \
introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.xml \
introspection/org.freedesktop.NetworkManager.Device.OvsInterface.xml \
introspection/org.freedesktop.NetworkManager.Device.OvsPort.xml \
introspection/org.freedesktop.NetworkManager.Device.OvsBridge.xml \
introspection/org.freedesktop.NetworkManager.Device.Ppp.xml \
introspection/org.freedesktop.NetworkManager.Device.Statistics.xml \
introspection/org.freedesktop.NetworkManager.Device.Team.xml \
@ -393,6 +405,10 @@ libnm_core_lib_h_pub_real = \
libnm-core/nm-setting-macsec.h \
libnm-core/nm-setting-macvlan.h \
libnm-core/nm-setting-olpc-mesh.h \
libnm-core/nm-setting-ovs-bridge.h \
libnm-core/nm-setting-ovs-interface.h \
libnm-core/nm-setting-ovs-patch.h \
libnm-core/nm-setting-ovs-port.h \
libnm-core/nm-setting-ppp.h \
libnm-core/nm-setting-pppoe.h \
libnm-core/nm-setting-proxy.h \
@ -474,6 +490,10 @@ libnm_core_lib_c_real = \
libnm-core/nm-setting-macsec.c \
libnm-core/nm-setting-macvlan.c \
libnm-core/nm-setting-olpc-mesh.c \
libnm-core/nm-setting-ovs-bridge.c \
libnm-core/nm-setting-ovs-interface.c \
libnm-core/nm-setting-ovs-patch.c \
libnm-core/nm-setting-ovs-port.c \
libnm-core/nm-setting-ppp.c \
libnm-core/nm-setting-pppoe.c \
libnm-core/nm-setting-proxy.c \
@ -731,6 +751,9 @@ libnm_lib_h_pub_real = \
libnm/nm-device-macvlan.h \
libnm/nm-device-modem.h \
libnm/nm-device-olpc-mesh.h \
libnm/nm-device-ovs-interface.h \
libnm/nm-device-ovs-port.h \
libnm/nm-device-ovs-bridge.h \
libnm/nm-device-ppp.h \
libnm/nm-device-team.h \
libnm/nm-device-tun.h \
@ -784,6 +807,9 @@ libnm_lib_c_real = \
libnm/nm-device-macvlan.c \
libnm/nm-device-modem.c \
libnm/nm-device-olpc-mesh.c \
libnm/nm-device-ovs-interface.c \
libnm/nm-device-ovs-port.c \
libnm/nm-device-ovs-bridge.c \
libnm/nm-device-ppp.c \
libnm/nm-device-team.c \
libnm/nm-device-tun.c \
@ -2742,6 +2768,63 @@ check_local += check-local-devices-team
endif
###############################################################################
# src/devices/ovs
###############################################################################
if WITH_OPENVSWITCH
if HAVE_SYSTEMD
systemdnmunitdir = $(systemdsystemunitdir)/NetworkManager.service.d
systemdnmunit_DATA = \
data/NetworkManager-ovs.conf
endif
core_plugins += src/devices/ovs/libnm-device-plugin-ovs.la
src_devices_ovs_libnm_device_plugin_ovs_la_SOURCES = \
src/devices/ovs/nm-ovsdb.c \
src/devices/ovs/nm-ovsdb.h \
src/devices/ovs/nm-ovs-factory.c \
src/devices/ovs/nm-device-ovs-interface.c \
src/devices/ovs/nm-device-ovs-interface.h \
src/devices/ovs/nm-device-ovs-port.c \
src/devices/ovs/nm-device-ovs-port.h \
src/devices/ovs/nm-device-ovs-bridge.c \
src/devices/ovs/nm-device-ovs-bridge.h
src_devices_ovs_libnm_device_plugin_ovs_la_CPPFLAGS = \
-I$(srcdir)/src \
-I$(builddir)/src \
-I$(srcdir)/shared \
-I$(builddir)/shared \
-I$(builddir)/libnm-core \
-I$(srcdir)/libnm-core \
\
-DG_LOG_DOMAIN=\""NetworkManager"\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_INSIDE_DAEMON \
-DRUNSTATEDIR=\"$(runstatedir)\" \
\
$(JANSSON_CFLAGS) \
$(GLIB_CFLAGS)
src_devices_ovs_libnm_device_plugin_ovs_la_LDFLAGS = \
-module -avoid-version \
-Wl,--version-script="$(srcdir)/linker-script-devices.ver"
src_devices_ovs_libnm_device_plugin_ovs_la_LIBADD = \
introspection/libnmdbus.la \
$(JANSSON_LIBS) \
$(GLIB_LIBS)
check-local-devices-ovs: src/devices/ovs/libnm-device-plugin-ovs.la
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/ovs/.libs/libnm-device-plugin-ovs.so "$(srcdir)/linker-script-devices.ver"
$(call check_so_symbols,$(builddir)/src/devices/ovs/.libs/libnm-device-plugin-ovs.so)
endif
###############################################################################
# src/dnsmasq/tests
###############################################################################
@ -4292,6 +4375,13 @@ man_pages_autogen += \
man/nm-settings-keyfile.5 \
man/nm-settings.5
if WITH_OPENVSWITCH
man_pages += man/nm-openvswitch.7
else
EXTRA_DIST += man/nm-openvswitch.7
dist_dependencies += man/nm-openvswitch.7
endif
if CONFIG_PLUGIN_IFCFG_RH
man_pages_autogen += man/nm-settings-ifcfg-rh.5
else

View file

@ -136,6 +136,10 @@ const NmcMetaGenericInfo *const nmc_fields_con_active_details_general[] = {
NM_SETTING_BRIDGE_PORT_SETTING_NAME","\
NM_SETTING_TEAM_SETTING_NAME","\
NM_SETTING_TEAM_PORT_SETTING_NAME"," \
NM_SETTING_OVS_BRIDGE_SETTING_NAME","\
NM_SETTING_OVS_INTERFACE_SETTING_NAME","\
NM_SETTING_OVS_PATCH_SETTING_NAME","\
NM_SETTING_OVS_PORT_SETTING_NAME","\
NM_SETTING_DCB_SETTING_NAME"," \
NM_SETTING_TUN_SETTING_NAME"," \
NM_SETTING_IP_TUNNEL_SETTING_NAME"," \

View file

@ -243,9 +243,11 @@ nmc_device_state_to_string (NMDeviceState state)
return _("deactivating");
case NM_DEVICE_STATE_FAILED:
return _("connection failed");
default:
case NM_DEVICE_STATE_UNKNOWN:
return _("unknown");
}
return _("unknown");
}
const char *
@ -260,9 +262,11 @@ nmc_device_metered_to_string (NMMetered value)
return _("yes (guessed)");
case NM_METERED_GUESS_NO:
return _("no (guessed)");
default:
case NM_METERED_UNKNOWN:
return _("unknown");
}
return _("unknown");
}
const char *
@ -395,10 +399,13 @@ 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");
default:
/* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */
return _("Unknown");
case NM_DEVICE_STATE_REASON_OVSDB_FAILED:
return _("OpenVSwitch database connection failed");
}
/* TRANSLATORS: Unknown reason for a device state change (NMDeviceStateReason) */
return _("Unknown");
}
const char *

View file

@ -5009,6 +5009,8 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = {
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC (NM_SETTING_BOND_SETTING_NAME,
NM_SETTING_BRIDGE_SETTING_NAME,
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_TEAM_SETTING_NAME),
),
),
@ -5803,6 +5805,81 @@ static const NMMetaPropertyInfo *const property_infos_PPPOE[] = {
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_BRIDGE
static const NMMetaPropertyInfo *const property_infos_OVS_BRIDGE[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_FAIL_MODE,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("secure", "standalone"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE,
.property_type = &_pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_RSTP_ENABLE,
.property_type = &_pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_BRIDGE_STP_ENABLE,
.property_type = &_pt_gobject_bool,
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_INTERFACE
static const NMMetaPropertyInfo *const property_infos_OVS_INTERFACE[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_INTERFACE_TYPE,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("internal", "patch"),
),
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_PATCH
static const NMMetaPropertyInfo *const property_infos_OVS_PATCH[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PATCH_PEER,
.property_type = &_pt_gobject_string,
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OVS_PORT
static const NMMetaPropertyInfo *const property_infos_OVS_PORT[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_VLAN_MODE,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("access", "native-tagged", "native-untagged", "trunk"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_TAG,
.property_type = &_pt_gobject_int,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_LACP,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("active", "off", "passive"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_MODE,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = VALUES_STATIC ("active-backup", "balance-slb", "balance-tcp"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_UPDELAY,
.property_type = &_pt_gobject_int,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_OVS_PORT_BOND_DOWNDELAY,
.property_type = &_pt_gobject_int,
),
NULL
};
#undef _CURRENT_NM_META_SETTING_TYPE
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_PPP
static const NMMetaPropertyInfo *const property_infos_PPP[] = {
@ -6722,6 +6799,10 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
#define SETTING_PRETTY_NAME_MACSEC N_("MACsec connection")
#define SETTING_PRETTY_NAME_MACVLAN N_("macvlan connection")
#define SETTING_PRETTY_NAME_OLPC_MESH N_("OLPC Mesh connection")
#define SETTING_PRETTY_NAME_OVS_BRIDGE N_("OpenVSwitch bridge settings")
#define SETTING_PRETTY_NAME_OVS_INTERFACE N_("OpenVSwitch interface settings")
#define SETTING_PRETTY_NAME_OVS_PATCH N_("OpenVSwitch patch interface settings")
#define SETTING_PRETTY_NAME_OVS_PORT N_("OpenVSwitch port settings")
#define SETTING_PRETTY_NAME_PPP N_("PPP settings")
#define SETTING_PRETTY_NAME_PPPOE N_("PPPoE")
#define SETTING_PRETTY_NAME_PROXY N_("Proxy")
@ -6871,6 +6952,29 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
),
.setting_init_fcn = _setting_init_fcn_olpc_mesh,
),
SETTING_INFO (OVS_BRIDGE,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (OVS_BRIDGE, TRUE),
),
),
SETTING_INFO (OVS_INTERFACE,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (OVS_INTERFACE, TRUE),
NM_META_SETTING_VALID_PART_ITEM (OVS_PATCH, FALSE),
NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE),
NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE),
NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE),
),
),
SETTING_INFO (OVS_PATCH),
SETTING_INFO (OVS_PORT,
.valid_parts = NM_META_SETTING_VALID_PARTS (
NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE),
NM_META_SETTING_VALID_PART_ITEM (OVS_PORT, TRUE),
),
),
SETTING_INFO (PPPOE,
/* PPPoE is a base connection type from historical reasons.
* See libnm-core/nm-setting.c:_nm_setting_is_base_type()
@ -6977,6 +7081,16 @@ static const NMMetaSettingValidPartItem *const valid_settings_slave_bridge[] = {
NULL,
};
static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_bridge[] = {
NM_META_SETTING_VALID_PART_ITEM (OVS_PORT, FALSE),
NULL,
};
static const NMMetaSettingValidPartItem *const valid_settings_slave_ovs_port[] = {
NM_META_SETTING_VALID_PART_ITEM (OVS_INTERFACE, FALSE),
NULL,
};
static const NMMetaSettingValidPartItem *const valid_settings_slave_team[] = {
NM_META_SETTING_VALID_PART_ITEM (TEAM_PORT, TRUE),
NULL,
@ -6997,6 +7111,14 @@ nm_meta_setting_info_valid_parts_for_slave_type (const char *slave_type, const c
NM_SET_OUT (out_slave_name, "bridge-slave");
return valid_settings_slave_bridge;
}
if (nm_streq (slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
NM_SET_OUT (out_slave_name, "ovs-slave");
return valid_settings_slave_ovs_bridge;
}
if (nm_streq (slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) {
NM_SET_OUT (out_slave_name, "ovs-slave");
return valid_settings_slave_ovs_port;
}
if (nm_streq (slave_type, NM_SETTING_TEAM_SETTING_NAME)) {
NM_SET_OUT (out_slave_name, "team-slave");
return valid_settings_slave_team;

View file

@ -197,7 +197,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_INPUT_KEY N_("The key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_LOCAL N_("The local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_MODE N_("The tunneling mode, for example NM_IP_TUNNEL_MODE_IPIP (1) or NM_IP_TUNNEL_MODE_GRE (2).")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_MTU N_("None")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_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_IP_TUNNEL_OUTPUT_KEY N_("The key used for tunnel output packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_PARENT N_("If given, specifies the parent interface name or parent connection UUID the new device will be bound to so that tunneled packets will only be routed via that interface.")
@ -262,6 +262,22 @@
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PROMISCUOUS N_("Whether the interface should be put in promiscuous mode.")
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_TAP N_("Whether the interface should be a MACVTAP.")
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_FAIL_MODE N_("The bridge failure mode. One of \"secure\", \"standalone\" or empty.")
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE N_("Enable or disable multicast snooping.")
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_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_OVS_BRIDGE_RSTP_ENABLE N_("Enable or disable RSTP.")
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_STP_ENABLE N_("Enable or disable STP.")
#define DESCRIBE_DOC_NM_SETTING_OVS_INTERFACE_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_OVS_INTERFACE_TYPE N_("The interface type. Either \"internal\", or empty.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PATCH_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_OVS_PATCH_PEER N_("Specifies the unicast destination IP address of a remote OpenVSwitch bridge port to connect to.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_DOWNDELAY N_("The time port must be inactive in order to be considered down.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_MODE N_("Bonding mode. One of \"active-backup\", \"balance-slb\", or \"balance-tcp\".")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_BOND_UPDELAY N_("The time port must be active befor it starts forwarding traffic.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_LACP N_("LACP mode. One of \"active\", \"off\", or \"passive\".")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_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_OVS_PORT_TAG N_("The VLAN tag in the range 0-4095.")
#define DESCRIBE_DOC_NM_SETTING_OVS_PORT_VLAN_MODE N_("The VLAN mode. One of \"access\", \"native-tagged\", \"native-untagged\", \"trunk\" or unset.")
#define DESCRIBE_DOC_NM_SETTING_PPP_BAUD N_("If non-zero, instruct pppd to set the serial port to the specified baudrate. This value should normally be left as 0 to automatically choose the speed.")
#define DESCRIBE_DOC_NM_SETTING_PPP_CRTSCTS N_("If TRUE, specify that pppd should set the serial port to use hardware flow control with RTS and CTS signals. This value should normally be set to FALSE.")
#define DESCRIBE_DOC_NM_SETTING_PPP_LCP_ECHO_FAILURE N_("If non-zero, instruct pppd to presume the connection to the peer has failed if the specified number of LCP echo-requests go unanswered by the peer. The \"lcp-echo-interval\" property must also be set to a non-zero value if this property is used.")

View file

@ -871,6 +871,20 @@ if test "$with_dhcpcanon" != "no"; then
else
AC_DEFINE(WITH_DHCPCANON, 0, [Define if you have dhcpcanon])
fi
# OpenVSwitch integration
AC_ARG_ENABLE(ovs, AS_HELP_STRING([--enable-ovs], [enable OpenVSwitch support]))
if test "${enable_ovs}" != "no"; then
enable_ovs='yes'
if test "$have_jansson" = "no"; then
AC_MSG_ERROR(Jansson is required for ovs support)
fi
AC_DEFINE(WITH_OPENVSWITCH, 1, [Define if you have OpenVSwitch support])
else
AC_DEFINE(WITH_OPENVSWITCH, 0, [Define if you have OpenVSwitch support])
fi
AM_CONDITIONAL(WITH_OPENVSWITCH, test "${enable_ovs}" = "yes")
# DHCP client support
AC_ARG_WITH([dhclient],
AS_HELP_STRING([--with-dhclient=yes|no|path], [Enable dhclient 4.x support]))
@ -1282,6 +1296,8 @@ if test "$build_docs" != "yes" -a \
-f "$srcdir"/man/nmcli.1 -a \
-f "$srcdir"/man/nmtui.1 -a \
\
-f "$srcdir"/man/nm-openvswitch.7 -a \
\
-f "$srcdir"/man/nm-settings-ifcfg-rh.5 -a \
-f "$srcdir"/man/nm-settings-keyfile.5 -a \
-f "$srcdir"/man/nm-settings.5 -a \
@ -1359,6 +1375,7 @@ echo " modemmanager-1: $with_modem_manager_1"
echo " ofono: $with_ofono"
echo " concheck: $enable_concheck"
echo " libteamdctl: $enable_teamdctl"
echo " ovs: $enable_ovs"
echo " libnm-glib: $with_libnm_glib"
echo " nmcli: $build_nmcli"
echo " nmtui: $build_nmtui"

View file

@ -50,6 +50,7 @@
%bcond_without wwan
%bcond_without team
%bcond_without wifi
%bcond_without ovs
%bcond_without ppp
%bcond_without nmtui
%bcond_without regen_docs
@ -240,6 +241,19 @@ This package contains NetworkManager support for mobile broadband (WWAN)
devices.
%endif
%if %{with ovs}
%package ovs
Summary: OpenVSwitch device plugin for NetworkManager
Group: System Environment/Base
Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release}
Requires: openvswitch
%description ovs
This package contains NetworkManager support for OpenVSwitch bridges.
%endif
%if %{with ppp}
%package ppp
Summary: PPP plugin for NetworkManager
@ -563,7 +577,7 @@ fi
%dir %{nmlibdir}/VPN
%{_mandir}/man1/*
%{_mandir}/man5/*
%{_mandir}/man7/*
%{_mandir}/man7/nmcli-examples.7*
%{_mandir}/man8/*
%dir %{_localstatedir}/lib/NetworkManager
%dir %{_sysconfdir}/NetworkManager/system-connections
@ -608,6 +622,13 @@ fi
%{_libdir}/%{name}/libnm-wwan.so
%endif
%if %{with ovs}
%files ovs
%{_libdir}/%{name}/libnm-device-plugin-ovs.so
%{systemd_dir}/NetworkManager.service.d/NetworkManager-ovs.conf
%{_mandir}/man7/nm-openvswitch.7*
%endif
%if %{with ppp}
%files ppp
%{_libdir}/pppd/%{ppp_version}/nm-pppd-plugin.so

View file

@ -0,0 +1,2 @@
[Unit]
After=openvswitch.service

View file

@ -88,6 +88,7 @@ content_files = \
$(top_builddir)/man/nmcli-examples.xml \
$(top_builddir)/man/nm-settings.xml \
$(top_builddir)/man/nm-settings-keyfile.xml \
$(top_builddir)/man/nm-openvswitch.xml \
version.xml \
../../COPYING \
$(NULL)

View file

@ -76,6 +76,7 @@
<xi:include href="../../man/nm-settings-keyfile.xml"><xi:fallback /></xi:include>
<xi:include href="../../man/nm-settings-ifcfg-rh.xml"><xi:fallback /></xi:include>
<xi:include href="../../man/nm-online.xml"/>
<xi:include href="../../man/nm-openvswitch.xml"/>
</part>
<part id="ref-settings">

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.OvsBridge:
@short_description: OvsBridge Device
-->
<interface name="org.freedesktop.NetworkManager.Device.OvsBridge">
<!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
DEPRECATED. Use the standard "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" instead which exists since version NetworkManager 1.2.0.
-->
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}"/>
</signal>
</interface>
</node>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.OvsInterface:
@short_description: OvsInterface Device
-->
<interface name="org.freedesktop.NetworkManager.Device.OvsInterface">
<!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
DEPRECATED. Use the standard "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" instead which exists since version NetworkManager 1.2.0.
-->
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}"/>
</signal>
</interface>
</node>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.OvsPort:
@short_description: OvsPort Device
-->
<interface name="org.freedesktop.NetworkManager.Device.OvsPort">
<!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
DEPRECATED. Use the standard "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" instead which exists since version NetworkManager 1.2.0.
-->
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}"/>
</signal>
</interface>
</node>

View file

@ -34,4 +34,10 @@ const char *_nm_connection_detect_bluetooth_type (NMConnection *self);
gboolean _nm_connection_verify_required_interface_name (NMConnection *connection,
GError **error);
int _nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
GError **error);
#endif /* __NM_CONNECTION_PRIVATE_H__ */

View file

@ -729,6 +729,10 @@ _nm_connection_detect_slave_type (NMConnection *connection, NMSetting **out_s_po
i_slave_type = NM_SETTING_BRIDGE_SETTING_NAME;
else if (!strcmp (name, NM_SETTING_TEAM_PORT_SETTING_NAME))
i_slave_type = NM_SETTING_TEAM_SETTING_NAME;
else if (!strcmp (name, NM_SETTING_OVS_PORT_SETTING_NAME))
i_slave_type = NM_SETTING_OVS_BRIDGE_SETTING_NAME;
else if (!strcmp (name, NM_SETTING_OVS_INTERFACE_SETTING_NAME))
i_slave_type = NM_SETTING_OVS_PORT_SETTING_NAME;
else
continue;
@ -808,10 +812,21 @@ _normalize_ethernet_link_neg (NMConnection *self)
return FALSE;
}
static gboolean
_without_ip_config (NMConnection *self)
{
const char *connection_type = nm_connection_get_connection_type (self);
g_return_val_if_fail (connection_type, FALSE);
if (strcmp (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0)
return FALSE;
return !!nm_setting_connection_get_master (nm_connection_get_setting_connection (self));
}
static gboolean
_normalize_ip_config (NMConnection *self, GHashTable *parameters)
{
NMSettingConnection *s_con = nm_connection_get_setting_connection (self);
const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
const char *default_ip6_method = NULL;
NMSettingIPConfig *s_ip4, *s_ip6;
@ -829,7 +844,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters)
s_ip6 = nm_connection_get_setting_ip6_config (self);
s_proxy = nm_connection_get_setting_proxy (self);
if (nm_setting_connection_get_master (s_con)) {
if (_without_ip_config (self)) {
/* Slave connections don't have IP configuration. */
if (s_ip4)
@ -1095,6 +1110,27 @@ _normalize_bluetooth_type (NMConnection *self, GHashTable *parameters)
return FALSE;
}
static gboolean
_normalize_ovs_interface_type (NMConnection *self, GHashTable *parameters)
{
NMSettingOvsInterface *s_ovs_interface = nm_connection_get_setting_ovs_interface (self);
gboolean modified;
int v;
if (!s_ovs_interface)
return FALSE;
v = _nm_setting_ovs_interface_verify_interface_type (s_ovs_interface,
self,
TRUE,
&modified,
NULL);
if (v != TRUE)
g_return_val_if_reached (modified);
return modified;
}
static gboolean
_normalize_required_settings (NMConnection *self, GHashTable *parameters)
{
@ -1252,40 +1288,42 @@ _nm_connection_verify (NMConnection *connection, GError **error)
s_ip6 = nm_connection_get_setting_ip6_config (connection);
s_proxy = nm_connection_get_setting_proxy (connection);
if (nm_setting_connection_get_master (s_con)) {
if ( NM_IN_SET (normalizable_error_type, NM_SETTING_VERIFY_SUCCESS,
NM_SETTING_VERIFY_NORMALIZABLE)
&& (s_ip4 || s_ip6 || s_proxy)) {
g_clear_error (&normalizable_error);
g_set_error_literal (&normalizable_error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_SETTING,
_("setting not allowed in slave connection"));
g_prefix_error (&normalizable_error, "%s: ",
s_ip4
? NM_SETTING_IP4_CONFIG_SETTING_NAME
: (s_ip6
? NM_SETTING_IP6_CONFIG_SETTING_NAME
: NM_SETTING_PROXY_SETTING_NAME));
/* having a slave with IP config *was* and is a verify() error. */
normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
} else {
if ( NM_IN_SET (normalizable_error_type, NM_SETTING_VERIFY_SUCCESS)
&& (!s_ip4 || !s_ip6 || !s_proxy)) {
g_set_error_literal (&normalizable_error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("setting is required for non-slave connections"));
g_prefix_error (&normalizable_error, "%s: ",
!s_ip4
? NM_SETTING_IP4_CONFIG_SETTING_NAME
: (!s_ip6
? NM_SETTING_IP6_CONFIG_SETTING_NAME
: NM_SETTING_PROXY_SETTING_NAME));
/* having a master without IP config was not a verify() error, accept
* it for backward compatibility. */
normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE;
nm_assert (normalizable_error_type != NM_SETTING_VERIFY_ERROR);
if (NM_IN_SET (normalizable_error_type, NM_SETTING_VERIFY_SUCCESS,
NM_SETTING_VERIFY_NORMALIZABLE)) {
if (_without_ip_config (connection)) {
if (s_ip4 || s_ip6 || s_proxy) {
g_clear_error (&normalizable_error);
g_set_error_literal (&normalizable_error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_SETTING,
_("setting not allowed in slave connection"));
g_prefix_error (&normalizable_error, "%s: ",
s_ip4
? NM_SETTING_IP4_CONFIG_SETTING_NAME
: (s_ip6
? NM_SETTING_IP6_CONFIG_SETTING_NAME
: NM_SETTING_PROXY_SETTING_NAME));
/* having a slave with IP config *was* and is a verify() error. */
normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
} else {
if ( normalizable_error_type == NM_SETTING_VERIFY_SUCCESS
&& (!s_ip4 || !s_ip6 || !s_proxy)) {
g_set_error_literal (&normalizable_error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("setting is required for non-slave connections"));
g_prefix_error (&normalizable_error, "%s: ",
!s_ip4
? NM_SETTING_IP4_CONFIG_SETTING_NAME
: (!s_ip6
? NM_SETTING_IP6_CONFIG_SETTING_NAME
: NM_SETTING_PROXY_SETTING_NAME));
/* having a master without IP config was not a verify() error, accept
* it for backward compatibility. */
normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE;
}
}
}
@ -1397,6 +1435,7 @@ nm_connection_normalize (NMConnection *connection,
was_modified |= _normalize_team_config (connection, parameters);
was_modified |= _normalize_team_port_config (connection, parameters);
was_modified |= _normalize_bluetooth_type (connection, parameters);
was_modified |= _normalize_ovs_interface_type (connection, parameters);
/* Verify anew. */
success = _nm_connection_verify (connection, error);
@ -1414,6 +1453,7 @@ nm_connection_normalize (NMConnection *connection,
NM_CONNECTION_ERROR_FAILED,
_("Unexpected failure to normalize the connection"));
}
g_warning ("connection did not verify after normalization: %s", error ? (*error)->message : "??");
g_return_val_if_reached (FALSE);
}
@ -1746,6 +1786,60 @@ _for_each_sort (NMSetting **p_a, NMSetting **p_b, void *unused)
return strcmp (nm_setting_get_name (a), nm_setting_get_name (b));
}
/**
* nm_connection_get_settings:
* @connection: the #NMConnection instance
* @out_length: (allow-none): (out): the length of the returned array
*
* Retrieves the settings in @connection.
*
* The returned array is %NULL-terminated.
*
* Returns: (array length=out_length) (transfer container): a
* %NULL-terminated array containing every setting of
* @connection.
* If the connection has no settings, %NULL is returned.
*
* Since: 1.10
*/
NMSetting **
nm_connection_get_settings (NMConnection *connection,
guint *out_length)
{
NMConnectionPrivate *priv;
NMSetting **arr;
GHashTableIter iter;
NMSetting *setting;
guint i, size;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
priv = NM_CONNECTION_GET_PRIVATE (connection);
size = g_hash_table_size (priv->settings);
if (!size) {
NM_SET_OUT (out_length, 0);
return NULL;
}
arr = g_new (NMSetting *, size + 1);
g_hash_table_iter_init (&iter, priv->settings);
for (i = 0; g_hash_table_iter_next (&iter, NULL, (gpointer *) &setting); i++)
arr[i] = setting;
nm_assert (i == size);
arr[size] = NULL;
/* sort the settings. This has an effect on the order in which keyfile
* prints them. */
if (size > 1)
g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
NM_SET_OUT (out_length, size);
return arr;
}
/**
* nm_connection_for_each_setting_value:
* @connection: the #NMConnection
@ -1760,39 +1854,15 @@ nm_connection_for_each_setting_value (NMConnection *connection,
NMSettingValueIterFn func,
gpointer user_data)
{
NMConnectionPrivate *priv;
gs_free NMSetting **arr_free = NULL;
NMSetting *arr_temp[20], **arr;
GHashTableIter iter;
gpointer value;
guint i, size;
gs_free NMSetting **settings = NULL;
guint i, length = 0;
g_return_if_fail (NM_IS_CONNECTION (connection));
g_return_if_fail (func);
priv = NM_CONNECTION_GET_PRIVATE (connection);
size = g_hash_table_size (priv->settings);
if (!size)
return;
if (size > G_N_ELEMENTS (arr_temp))
arr = arr_free = g_new (NMSetting *, size);
else
arr = arr_temp;
g_hash_table_iter_init (&iter, priv->settings);
for (i = 0; g_hash_table_iter_next (&iter, NULL, &value); i++)
arr[i] = NM_SETTING (value);
g_assert (i == size);
/* sort the settings. This has an effect on the order in which keyfile
* prints them. */
if (size > 1)
g_qsort_with_data (arr, size, sizeof (NMSetting *), (GCompareDataFunc) _for_each_sort, NULL);
for (i = 0; i < size; i++)
nm_setting_enumerate_values (arr[i], func, user_data);
settings = nm_connection_get_settings (connection, &length);
for (i = 0; i < length; i++)
nm_setting_enumerate_values (settings[i], func, user_data);
}
/**
@ -1983,6 +2053,9 @@ nm_connection_is_virtual (NMConnection *connection)
|| !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME)
|| !strcmp (type, NM_SETTING_MACSEC_SETTING_NAME)
|| !strcmp (type, NM_SETTING_MACVLAN_SETTING_NAME)
|| !strcmp (type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)
|| !strcmp (type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)
|| !strcmp (type, NM_SETTING_OVS_PORT_SETTING_NAME)
|| !strcmp (type, NM_SETTING_VXLAN_SETTING_NAME))
return TRUE;
@ -2335,6 +2408,70 @@ nm_connection_get_setting_olpc_mesh (NMConnection *connection)
return _connection_get_setting_check (connection, NM_TYPE_SETTING_OLPC_MESH);
}
/**
* nm_connection_get_setting_ovs_bridge:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingOvsBridge the connection might contain.
*
* Returns: (transfer none): an #NMSettingOvsBridge if the connection contains one, otherwise %NULL
*
* Since: 1.10
**/
NMSettingOvsBridge *
nm_connection_get_setting_ovs_bridge (NMConnection *connection)
{
return _connection_get_setting_check (connection, NM_TYPE_SETTING_OVS_BRIDGE);
}
/**
* nm_connection_get_setting_ovs_interface:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingOvsInterface the connection might contain.
*
* Returns: (transfer none): an #NMSettingOvsInterface if the connection contains one, otherwise %NULL
*
* Since: 1.10
**/
NMSettingOvsInterface *
nm_connection_get_setting_ovs_interface (NMConnection *connection)
{
return _connection_get_setting_check (connection, NM_TYPE_SETTING_OVS_INTERFACE);
}
/**
* nm_connection_get_setting_ovs_patch:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingOvsPatch the connection might contain.
*
* Returns: (transfer none): an #NMSettingOvsPatch if the connection contains one, otherwise %NULL
*
* Since: 1.10
**/
NMSettingOvsPatch *
nm_connection_get_setting_ovs_patch (NMConnection *connection)
{
return _connection_get_setting_check (connection, NM_TYPE_SETTING_OVS_PATCH);
}
/**
* nm_connection_get_setting_ovs_port:
* @connection: the #NMConnection
*
* A shortcut to return any #NMSettingOvsPort the connection might contain.
*
* Returns: (transfer none): an #NMSettingOvsPort if the connection contains one, otherwise %NULL
*
* Since: 1.10
**/
NMSettingOvsPort *
nm_connection_get_setting_ovs_port (NMConnection *connection)
{
return _connection_get_setting_check (connection, NM_TYPE_SETTING_OVS_PORT);
}
/**
* nm_connection_get_setting_ppp:
* @connection: the #NMConnection

View file

@ -179,6 +179,10 @@ void nm_connection_for_each_setting_value (NMConnection *connection,
NMSettingValueIterFn func,
gpointer user_data);
NM_AVAILABLE_IN_1_10
NMSetting ** nm_connection_get_settings (NMConnection *connection,
guint *out_length);
void nm_connection_dump (NMConnection *connection);
/* Helpers */
@ -213,6 +217,13 @@ NMSettingMacsec * nm_connection_get_setting_macsec (NMConnec
NM_AVAILABLE_IN_1_2
NMSettingMacvlan * nm_connection_get_setting_macvlan (NMConnection *connection);
NMSettingOlpcMesh * nm_connection_get_setting_olpc_mesh (NMConnection *connection);
NM_AVAILABLE_IN_1_10
NMSettingOvsBridge * nm_connection_get_setting_ovs_bridge (NMConnection *connection);
NM_AVAILABLE_IN_1_10
NMSettingOvsInterface * nm_connection_get_setting_ovs_interface (NMConnection *connection);
NMSettingOvsPatch * nm_connection_get_setting_ovs_patch (NMConnection *connection);
NM_AVAILABLE_IN_1_10
NMSettingOvsPort * nm_connection_get_setting_ovs_port (NMConnection *connection);
NMSettingPpp * nm_connection_get_setting_ppp (NMConnection *connection);
NMSettingPppoe * nm_connection_get_setting_pppoe (NMConnection *connection);
NM_AVAILABLE_IN_1_6

View file

@ -56,6 +56,10 @@
#include "nm-setting-macsec.h"
#include "nm-setting-macvlan.h"
#include "nm-setting-olpc-mesh.h"
#include "nm-setting-ovs-bridge.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-patch.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ppp.h"
#include "nm-setting-pppoe.h"
#include "nm-setting-serial.h"

View file

@ -50,6 +50,10 @@ typedef struct _NMSettingIP6Config NMSettingIP6Config;
typedef struct _NMSettingMacsec NMSettingMacsec;
typedef struct _NMSettingMacvlan NMSettingMacvlan;
typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh;
typedef struct _NMSettingOvsBridge NMSettingOvsBridge;
typedef struct _NMSettingOvsInterface NMSettingOvsInterface;
typedef struct _NMSettingOvsPatch NMSettingOvsPatch;
typedef struct _NMSettingOvsPort NMSettingOvsPort;
typedef struct _NMSettingPpp NMSettingPpp;
typedef struct _NMSettingPppoe NMSettingPppoe;
typedef struct _NMSettingSerial NMSettingSerial;

View file

@ -36,43 +36,46 @@
/*
* dbus services details
*/
#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired"
#define NM_DBUS_INTERFACE_DEVICE_ADSL NM_DBUS_INTERFACE_DEVICE ".Adsl"
#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless"
#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH NM_DBUS_INTERFACE_DEVICE ".Bluetooth"
#define NM_DBUS_INTERFACE_DEVICE_OLPC_MESH NM_DBUS_INTERFACE_DEVICE ".OlpcMesh"
#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint"
#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint"
#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem"
#define NM_DBUS_INTERFACE_DEVICE_WIMAX NM_DBUS_INTERFACE_DEVICE ".WiMax"
#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp"
#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp"
#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config"
#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config"
#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband"
#define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond"
#define NM_DBUS_INTERFACE_DEVICE_DUMMY NM_DBUS_INTERFACE_DEVICE ".Dummy"
#define NM_DBUS_INTERFACE_DEVICE_TEAM NM_DBUS_INTERFACE_DEVICE ".Team"
#define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan"
#define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge"
#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic"
#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth"
#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun"
#define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec"
#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan"
#define NM_DBUS_INTERFACE_DEVICE_PPP NM_DBUS_INTERFACE_DEVICE ".Ppp"
#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan"
#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_PATH "/org/freedesktop/NetworkManager"
#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired"
#define NM_DBUS_INTERFACE_DEVICE_ADSL NM_DBUS_INTERFACE_DEVICE ".Adsl"
#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless"
#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH NM_DBUS_INTERFACE_DEVICE ".Bluetooth"
#define NM_DBUS_INTERFACE_DEVICE_OLPC_MESH NM_DBUS_INTERFACE_DEVICE ".OlpcMesh"
#define NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE NM_DBUS_INTERFACE_DEVICE ".OvsInterface"
#define NM_DBUS_INTERFACE_DEVICE_OVS_PORT NM_DBUS_INTERFACE_DEVICE ".OvsPort"
#define NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE NM_DBUS_INTERFACE_DEVICE ".OvsBridge"
#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint"
#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint"
#define NM_DBUS_INTERFACE_DEVICE_MODEM NM_DBUS_INTERFACE_DEVICE ".Modem"
#define NM_DBUS_INTERFACE_DEVICE_WIMAX NM_DBUS_INTERFACE_DEVICE ".WiMax"
#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp"
#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp"
#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
#define NM_DBUS_INTERFACE_IP6_CONFIG NM_DBUS_INTERFACE ".IP6Config"
#define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config"
#define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband"
#define NM_DBUS_INTERFACE_DEVICE_BOND NM_DBUS_INTERFACE_DEVICE ".Bond"
#define NM_DBUS_INTERFACE_DEVICE_DUMMY NM_DBUS_INTERFACE_DEVICE ".Dummy"
#define NM_DBUS_INTERFACE_DEVICE_TEAM NM_DBUS_INTERFACE_DEVICE ".Team"
#define NM_DBUS_INTERFACE_DEVICE_VLAN NM_DBUS_INTERFACE_DEVICE ".Vlan"
#define NM_DBUS_INTERFACE_DEVICE_BRIDGE NM_DBUS_INTERFACE_DEVICE ".Bridge"
#define NM_DBUS_INTERFACE_DEVICE_GENERIC NM_DBUS_INTERFACE_DEVICE ".Generic"
#define NM_DBUS_INTERFACE_DEVICE_VETH NM_DBUS_INTERFACE_DEVICE ".Veth"
#define NM_DBUS_INTERFACE_DEVICE_TUN NM_DBUS_INTERFACE_DEVICE ".Tun"
#define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec"
#define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan"
#define NM_DBUS_INTERFACE_DEVICE_PPP NM_DBUS_INTERFACE_DEVICE ".Ppp"
#define NM_DBUS_INTERFACE_DEVICE_VXLAN NM_DBUS_INTERFACE_DEVICE ".Vxlan"
#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_SETTINGS "org.freedesktop.NetworkManager.Settings"
#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings"
@ -205,35 +208,41 @@ typedef enum {
* @NM_DEVICE_TYPE_MACSEC: a MACsec interface
* @NM_DEVICE_TYPE_DUMMY: a dummy interface
* @NM_DEVICE_TYPE_PPP: a PPP interface
* @NM_DEVICE_TYPE_OVS_INTERFACE: a OpenVSwitch interface
* @NM_DEVICE_TYPE_OVS_PORT: a OpenVSwitch port
* @NM_DEVICE_TYPE_OVS_BRIDGE: a OpenVSwitch bridge
*
* #NMDeviceType values indicate the type of hardware represented by a
* device object.
**/
typedef enum {
NM_DEVICE_TYPE_UNKNOWN = 0,
NM_DEVICE_TYPE_ETHERNET = 1,
NM_DEVICE_TYPE_WIFI = 2,
NM_DEVICE_TYPE_UNUSED1 = 3,
NM_DEVICE_TYPE_UNUSED2 = 4,
NM_DEVICE_TYPE_BT = 5, /* Bluetooth */
NM_DEVICE_TYPE_OLPC_MESH = 6,
NM_DEVICE_TYPE_WIMAX = 7,
NM_DEVICE_TYPE_MODEM = 8,
NM_DEVICE_TYPE_INFINIBAND = 9,
NM_DEVICE_TYPE_BOND = 10,
NM_DEVICE_TYPE_VLAN = 11,
NM_DEVICE_TYPE_ADSL = 12,
NM_DEVICE_TYPE_BRIDGE = 13,
NM_DEVICE_TYPE_GENERIC = 14,
NM_DEVICE_TYPE_TEAM = 15,
NM_DEVICE_TYPE_TUN = 16,
NM_DEVICE_TYPE_IP_TUNNEL = 17,
NM_DEVICE_TYPE_MACVLAN = 18,
NM_DEVICE_TYPE_VXLAN = 19,
NM_DEVICE_TYPE_VETH = 20,
NM_DEVICE_TYPE_MACSEC = 21,
NM_DEVICE_TYPE_DUMMY = 22,
NM_DEVICE_TYPE_PPP = 23,
NM_DEVICE_TYPE_UNKNOWN = 0,
NM_DEVICE_TYPE_ETHERNET = 1,
NM_DEVICE_TYPE_WIFI = 2,
NM_DEVICE_TYPE_UNUSED1 = 3,
NM_DEVICE_TYPE_UNUSED2 = 4,
NM_DEVICE_TYPE_BT = 5, /* Bluetooth */
NM_DEVICE_TYPE_OLPC_MESH = 6,
NM_DEVICE_TYPE_WIMAX = 7,
NM_DEVICE_TYPE_MODEM = 8,
NM_DEVICE_TYPE_INFINIBAND = 9,
NM_DEVICE_TYPE_BOND = 10,
NM_DEVICE_TYPE_VLAN = 11,
NM_DEVICE_TYPE_ADSL = 12,
NM_DEVICE_TYPE_BRIDGE = 13,
NM_DEVICE_TYPE_GENERIC = 14,
NM_DEVICE_TYPE_TEAM = 15,
NM_DEVICE_TYPE_TUN = 16,
NM_DEVICE_TYPE_IP_TUNNEL = 17,
NM_DEVICE_TYPE_MACVLAN = 18,
NM_DEVICE_TYPE_VXLAN = 19,
NM_DEVICE_TYPE_VETH = 20,
NM_DEVICE_TYPE_MACSEC = 21,
NM_DEVICE_TYPE_DUMMY = 22,
NM_DEVICE_TYPE_PPP = 23,
NM_DEVICE_TYPE_OVS_INTERFACE = 24,
NM_DEVICE_TYPE_OVS_PORT = 25,
NM_DEVICE_TYPE_OVS_BRIDGE = 26,
} NMDeviceType;
/**
@ -541,6 +550,7 @@ typedef enum {
* @NM_DEVICE_STATE_REASON_NEW_ACTIVATION: New connection activation was enqueued
* @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
*
* Device state change reason codes
*/
@ -608,6 +618,7 @@ typedef enum {
NM_DEVICE_STATE_REASON_NEW_ACTIVATION = 60,
NM_DEVICE_STATE_REASON_PARENT_CHANGED = 61,
NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED = 62,
NM_DEVICE_STATE_REASON_OVSDB_FAILED = 63,
} NMDeviceStateReason;
/**

View file

@ -859,6 +859,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
gboolean is_slave;
const char *slave_setting_type;
NMSetting *normerr_base_type = NULL;
const char *type;
const char *slave_type;
const char *normerr_slave_setting_type = NULL;
const char *normerr_missing_slave_type = NULL;
const char *normerr_missing_slave_type_port = NULL;
@ -904,8 +906,10 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (!priv->type) {
if (!connection || !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) {
type = priv->type;
if (!type) {
if ( !connection
|| !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
@ -913,10 +917,11 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
type = nm_setting_get_name (normerr_base_type);
} else {
GType base_type;
if (!priv->type[0]) {
if (!type[0]) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
@ -925,21 +930,21 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
base_type = nm_setting_lookup_type (priv->type);
base_type = nm_setting_lookup_type (type);
if ( base_type == G_TYPE_INVALID
|| _nm_setting_type_get_base_type_priority (base_type) == NM_SETTING_PRIORITY_INVALID) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("connection type '%s' is not valid"),
priv->type);
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
/* Make sure the corresponding 'type' item is present */
if ( connection
&& !nm_connection_get_setting_by_name (connection, priv->type)) {
&& !nm_connection_get_setting_by_name (connection, type)) {
NMSetting *s_base;
NMConnection *connection2;
@ -952,7 +957,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_object_unref (connection2);
if (!normerr_base_setting) {
_set_error_missing_base_setting (error, priv->type);
_set_error_missing_base_setting (error, type);
return FALSE;
}
}
@ -960,13 +965,14 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
is_slave = FALSE;
slave_setting_type = NULL;
if (priv->slave_type) {
is_slave = _nm_setting_slave_type_is_valid (priv->slave_type, &slave_setting_type);
slave_type = priv->slave_type;
if (slave_type) {
is_slave = _nm_setting_slave_type_is_valid (slave_type, &slave_setting_type);
if (!is_slave) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("Unknown slave type '%s'"), priv->slave_type);
_("Unknown slave type '%s'"), slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
@ -986,8 +992,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
&& !nm_connection_get_setting_by_name (connection, slave_setting_type))
normerr_slave_setting_type = slave_setting_type;
} else {
nm_assert (!slave_type);
if (priv->master) {
const char *slave_type;
NMSetting *s_port;
if ( connection
@ -1006,6 +1012,18 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if ( nm_streq0 (type, NM_SETTING_OVS_PORT_SETTING_NAME)
&& !nm_streq0 (slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("Only '%s' connections can be enslaved to '%s'"),
NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_OVS_BRIDGE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
if (priv->metered != NM_METERED_UNKNOWN &&
priv->metered != NM_METERED_YES &&
priv->metered != NM_METERED_NO) {

View file

@ -758,7 +758,7 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *setting_class)
G_PARAM_STATIC_STRINGS));
/**
* NMSettingIPTunel:mtu:
* NMSettingIPTunnel:mtu:
*
* If non-zero, only transmit packets of the specified size or smaller,
* breaking larger packets up into multiple fragments.

View file

@ -0,0 +1,337 @@
/* -*- 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ovs-bridge.h"
#include "nm-connection-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-private.h"
/**
* SECTION:nm-setting-ovs-bridge
* @short_description: Describes connection properties for OpenVSwitch bridges.
*
* The #NMSettingOvsBridge object is a #NMSetting subclass that describes properties
* necessary for OpenVSwitch bridges.
**/
enum {
PROP_0,
PROP_FAIL_MODE,
PROP_MCAST_SNOOPING_ENABLE,
PROP_RSTP_ENABLE,
PROP_STP_ENABLE,
LAST_PROP
};
/**
* NMSettingOvsBridge:
*
* OvsBridge Link Settings
*/
struct _NMSettingOvsBridge {
NMSetting parent;
char *fail_mode;
gboolean mcast_snooping_enable;
gboolean rstp_enable;
gboolean stp_enable;
};
struct _NMSettingOvsBridgeClass {
NMSettingClass parent;
};
G_DEFINE_TYPE_WITH_CODE (NMSettingOvsBridge, nm_setting_ovs_bridge, NM_TYPE_SETTING,
_nm_register_setting (OVS_BRIDGE, NM_SETTING_PRIORITY_HW_BASE))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_OVS_BRIDGE)
/*****************************************************************************/
/**
* nm_setting_ovs_bridge_get_fail_mode:
* @self: the #NMSettingOvsBridge
*
* Returns: the #NMSettingOvsBridge:fail_mode property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_bridge_get_fail_mode (NMSettingOvsBridge *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_BRIDGE (self), NULL);
return self->fail_mode;
}
/**
* nm_setting_ovs_bridge_get_mcast_snooping_enable:
* @self: the #NMSettingOvsBridge
*
* Returns: the #NMSettingOvsBridge:mcast_snooping_enable property of the setting
*
* Since: 1.10
**/
gboolean
nm_setting_ovs_bridge_get_mcast_snooping_enable (NMSettingOvsBridge *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_BRIDGE (self), FALSE);
return self->mcast_snooping_enable;
}
/**
* nm_setting_ovs_bridge_get_rstp_enable:
* @self: the #NMSettingOvsBridge
*
* Returns: the #NMSettingOvsBridge:rstp_enable property of the setting
*
* Since: 1.10
**/
gboolean
nm_setting_ovs_bridge_get_rstp_enable (NMSettingOvsBridge *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_BRIDGE (self), FALSE);
return self->rstp_enable;
}
/**
* nm_setting_ovs_bridge_get_stp_enable:
* @self: the #NMSettingOvsBridge
*
* Returns: the #NMSettingOvsBridge:stp_enable property of the setting
*
* Since: 1.10
**/
gboolean
nm_setting_ovs_bridge_get_stp_enable (NMSettingOvsBridge *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_BRIDGE (self), FALSE);
return self->stp_enable;
}
/*****************************************************************************/
static int
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE (setting);
if (!_nm_connection_verify_required_interface_name (connection, error))
return FALSE;
if (connection) {
NMSettingConnection *s_con;
s_con = nm_connection_get_setting_connection (connection);
if (!s_con) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("missing setting"));
g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME);
return FALSE;
}
if (nm_setting_connection_get_master (s_con)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must not have a master."),
NM_SETTING_OVS_BRIDGE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER);
return FALSE;
}
}
if (!NM_IN_STRSET (self->fail_mode, "secure", "standalone", NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not allowed in fail_mode"),
self->fail_mode);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_BRIDGE_SETTING_NAME, NM_SETTING_OVS_BRIDGE_FAIL_MODE);
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE (object);
switch (prop_id) {
case PROP_FAIL_MODE:
g_value_set_string (value, self->fail_mode);
break;
case PROP_MCAST_SNOOPING_ENABLE:
g_value_set_boolean (value, self->mcast_snooping_enable);
break;
case PROP_RSTP_ENABLE:
g_value_set_boolean (value, self->rstp_enable);
break;
case PROP_STP_ENABLE:
g_value_set_boolean (value, self->stp_enable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE (object);
switch (prop_id) {
case PROP_FAIL_MODE:
g_free (self->fail_mode);
self->fail_mode = g_value_dup_string (value);
break;
case PROP_MCAST_SNOOPING_ENABLE:
self->mcast_snooping_enable = g_value_get_boolean (value);
break;
case PROP_RSTP_ENABLE:
self->rstp_enable = g_value_get_boolean (value);
break;
case PROP_STP_ENABLE:
self->stp_enable = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_setting_ovs_bridge_init (NMSettingOvsBridge *self)
{
}
/**
* nm_setting_ovs_bridge_new:
*
* Creates a new #NMSettingOvsBridge object with default values.
*
* Returns: (transfer full): the new empty #NMSettingOvsBridge object
*
* Since: 1.10
**/
NMSetting *
nm_setting_ovs_bridge_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_OVS_BRIDGE, NULL);
}
static void
finalize (GObject *object)
{
NMSettingOvsBridge *self = NM_SETTING_OVS_BRIDGE (object);
g_free (self->fail_mode);
G_OBJECT_CLASS (nm_setting_ovs_bridge_parent_class)->finalize (object);
}
static void
nm_setting_ovs_bridge_class_init (NMSettingOvsBridgeClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
/**
* NMSettingOvsBridge:fail-mode:
*
* The bridge failure mode. One of "secure", "standalone" or empty.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_FAIL_MODE,
g_param_spec_string (NM_SETTING_OVS_BRIDGE_FAIL_MODE, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsBridge:mcast-snooping-enable:
*
* Enable or disable multicast snooping.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_MCAST_SNOOPING_ENABLE,
g_param_spec_boolean (NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsBridge:rstp-enable:
*
* Enable or disable RSTP.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_RSTP_ENABLE,
g_param_spec_boolean (NM_SETTING_OVS_BRIDGE_RSTP_ENABLE, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsBridge:stp-enable:
*
* Enable or disable STP.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_STP_ENABLE,
g_param_spec_boolean (NM_SETTING_OVS_BRIDGE_STP_ENABLE, "", "",
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
}

View file

@ -0,0 +1,63 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_SETTING_OVS_BRIDGE_H__
#define __NM_SETTING_OVS_BRIDGE_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_OVS_BRIDGE (nm_setting_ovs_bridge_get_type ())
#define NM_SETTING_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_OVS_BRIDGE, NMSettingOvsBridge))
#define NM_SETTING_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_OVS_BRIDGECONFIG, NMSettingOvsBridgeClass))
#define NM_IS_SETTING_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_OVS_BRIDGE))
#define NM_IS_SETTING_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_OVS_BRIDGE))
#define NM_SETTING_OVS_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_OVS_BRIDGE, NMSettingOvsBridgeClass))
#define NM_SETTING_OVS_BRIDGE_SETTING_NAME "ovs-bridge"
#define NM_SETTING_OVS_BRIDGE_FAIL_MODE "fail-mode"
#define NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE "mcast-snooping-enable"
#define NM_SETTING_OVS_BRIDGE_RSTP_ENABLE "rstp-enable"
#define NM_SETTING_OVS_BRIDGE_STP_ENABLE "stp-enable"
typedef struct _NMSettingOvsBridgeClass NMSettingOvsBridgeClass;
NM_AVAILABLE_IN_1_10
GType nm_setting_ovs_bridge_get_type (void);
NM_AVAILABLE_IN_1_10
NMSetting *nm_setting_ovs_bridge_new (void);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_bridge_get_fail_mode (NMSettingOvsBridge *self);
NM_AVAILABLE_IN_1_10
gboolean nm_setting_ovs_bridge_get_mcast_snooping_enable (NMSettingOvsBridge *self);
NM_AVAILABLE_IN_1_10
gboolean nm_setting_ovs_bridge_get_rstp_enable (NMSettingOvsBridge *self);
NM_AVAILABLE_IN_1_10
gboolean nm_setting_ovs_bridge_get_stp_enable (NMSettingOvsBridge *self);
G_END_DECLS
#endif /* __NM_SETTING_OVS_BRIDGE_H__ */

View file

@ -0,0 +1,392 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ovs-interface.h"
#include "nm-connection-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-private.h"
/**
* SECTION:nm-setting-ovs-interface
* @short_description: Describes connection properties for OpenVSwitch interfaces.
*
* The #NMSettingOvsInterface object is a #NMSetting subclass that describes properties
* necessary for OpenVSwitch interfaces.
**/
enum {
PROP_0,
PROP_TYPE,
LAST_PROP
};
/**
* NMSettingOvsInterface:
*
* OpenVSwitch Interface Settings
*/
struct _NMSettingOvsInterface {
NMSetting parent;
char *type;
};
struct _NMSettingOvsInterfaceClass {
NMSettingClass parent;
};
G_DEFINE_TYPE_WITH_CODE (NMSettingOvsInterface, nm_setting_ovs_interface, NM_TYPE_SETTING,
_nm_register_setting (OVS_INTERFACE, NM_SETTING_PRIORITY_HW_BASE))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_OVS_INTERFACE)
/*****************************************************************************/
/**
* nm_setting_ovs_interface_get_interface_type:
* @self: the #NMSettingOvsInterface
*
* Returns: the #NMSettingOvsInterface:type property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_interface_get_interface_type (NMSettingOvsInterface *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_INTERFACE (self), NULL);
return self->type;
}
/*****************************************************************************/
int
_nm_setting_ovs_interface_verify_interface_type (NMSettingOvsInterface *self,
NMConnection *connection,
gboolean normalize,
gboolean *out_modified,
GError **error)
{
gboolean has_patch;
const char *type;
const char *connection_type;
gboolean is_ovs_connection_type;
gboolean missing_patch_setting = FALSE;
g_return_val_if_fail (NM_IS_SETTING_OVS_INTERFACE (self), FALSE);
if (normalize) {
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
nm_assert (self == nm_connection_get_setting_ovs_interface (connection));
} else
g_return_val_if_fail (!connection || NM_IS_CONNECTION (connection), FALSE);
NM_SET_OUT (out_modified, FALSE);
type = self ? self->type : NULL;
if ( type
&& !NM_IN_STRSET (type,
"internal",
"system",
"patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid interface type"),
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (!connection)
return TRUE;
connection_type = nm_connection_get_connection_type (connection);
if (!connection_type) {
/* if we have an ovs-interface, then the connection type must be either
* "ovs-interface" (for non "system" type) or anything else (for "system" type).
*
* The connection type usually can be normalized based on the presence of a
* base setting. However, in this case, if the connection type is missing,
* that is too complicate to guess what the user wanted.
*
* Require the use to be explicit and fail. */
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting needs connection.type explicitly set"),
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
return FALSE;
}
if (nm_streq (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
if ( type
&& nm_streq (type, "system")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection of type '%s' cannot have ovs-interface.type \"system\""),
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
is_ovs_connection_type = TRUE;
} else {
if ( type
&& !nm_streq (type, "system")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection of type '%s' cannot have an ovs-interface.type \"%s\""),
connection_type,
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
is_ovs_connection_type = FALSE;
}
has_patch = !!nm_connection_get_setting_by_name (connection, NM_SETTING_OVS_PATCH_SETTING_NAME);
if (has_patch) {
if (!is_ovs_connection_type) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting must be of connection.type \"ovs-interface\" but is \"%s\""),
NM_SETTING_OVS_PATCH_SETTING_NAME,
connection_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
if (type) {
if (!nm_streq (type, "patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with '%s' setting needs to be of 'patch' interface type, not '%s'"),
NM_SETTING_OVS_PATCH_SETTING_NAME,
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
return TRUE;
}
type = "patch";
goto normalize;
} else {
if (nm_streq0 (type, "patch")) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("A connection with ovs-interface.type '%s' setting a 'ovs-patch' setting"),
type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
return FALSE;
}
}
if (type)
return TRUE;
if (is_ovs_connection_type)
type = "internal";
else
type = "system";
normalize:
if (!normalize) {
if (!self) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("Missing ovs interface setting"));
g_prefix_error (error, "%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME);
} else {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("Missing ovs interface type"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_INTERFACE_SETTING_NAME, NM_SETTING_OVS_INTERFACE_TYPE);
}
if (missing_patch_setting) {
}
return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
}
if (!self) {
self = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (connection, NM_SETTING (self));
}
g_object_set (self,
NM_SETTING_OVS_INTERFACE_TYPE, type,
NULL);
NM_SET_OUT (out_modified, TRUE);
return TRUE;
}
static int
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE (setting);
if (connection) {
NMSettingConnection *s_con;
const char *slave_type;
s_con = nm_connection_get_setting_connection (connection);
if (!s_con) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("missing setting"));
g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME);
return FALSE;
}
if (!nm_setting_connection_get_master (s_con)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have a master."),
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER);
return FALSE;
}
slave_type = nm_setting_connection_get_slave_type (s_con);
if ( slave_type
&& !nm_streq (slave_type, NM_SETTING_OVS_PORT_SETTING_NAME)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"),
NM_SETTING_OVS_INTERFACE_SETTING_NAME,
NM_SETTING_OVS_PORT_SETTING_NAME,
slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
}
return _nm_setting_ovs_interface_verify_interface_type (self,
connection,
FALSE,
NULL,
error);
}
/*****************************************************************************/
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE (object);
switch (prop_id) {
case PROP_TYPE:
g_value_set_string (value, self->type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE (object);
switch (prop_id) {
case PROP_TYPE:
g_free (self->type);
self->type = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_setting_ovs_interface_init (NMSettingOvsInterface *self)
{
}
/**
* nm_setting_ovs_interface_new:
*
* Creates a new #NMSettingOvsInterface object with default values.
*
* Returns: (transfer full): the new empty #NMSettingOvsInterface object
*
* Since: 1.10
**/
NMSetting *
nm_setting_ovs_interface_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_OVS_INTERFACE, NULL);
}
static void
finalize (GObject *object)
{
NMSettingOvsInterface *self = NM_SETTING_OVS_INTERFACE (object);
g_free (self->type);
G_OBJECT_CLASS (nm_setting_ovs_interface_parent_class)->finalize (object);
}
static void
nm_setting_ovs_interface_class_init (NMSettingOvsInterfaceClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
/**
* NMSettingOvsInterface:type:
*
* The interface type. Either "internal", or empty.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_TYPE,
g_param_spec_string (NM_SETTING_OVS_INTERFACE_TYPE, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -0,0 +1,54 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_SETTING_OVS_INTERFACE_H__
#define __NM_SETTING_OVS_INTERFACE_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_get_type ())
#define NM_SETTING_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_OVS_INTERFACE, NMSettingOvsInterface))
#define NM_SETTING_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_OVS_INTERFACECONFIG, NMSettingOvsInterfaceClass))
#define NM_IS_SETTING_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_OVS_INTERFACE))
#define NM_IS_SETTING_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_OVS_INTERFACE))
#define NM_SETTING_OVS_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_OVS_INTERFACE, NMSettingOvsInterfaceClass))
#define NM_SETTING_OVS_INTERFACE_SETTING_NAME "ovs-interface"
#define NM_SETTING_OVS_INTERFACE_TYPE "type"
typedef struct _NMSettingOvsInterfaceClass NMSettingOvsInterfaceClass;
NM_AVAILABLE_IN_1_10
GType nm_setting_ovs_interface_get_type (void);
NM_AVAILABLE_IN_1_10
NMSetting *nm_setting_ovs_interface_new (void);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_interface_get_interface_type (NMSettingOvsInterface *self);
G_END_DECLS
#endif /* __NM_SETTING_OVS_INTERFACE_H__ */

View file

@ -0,0 +1,215 @@
/* -*- 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ovs-patch.h"
#include "nm-connection-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-private.h"
/**
* SECTION:nm-setting-ovs-patch
* @short_description: Describes connection properties for OpenVSwitch patch interfaces.
*
* The #NMSettingOvsPatch object is a #NMSetting subclass that describes properties
* necessary for OpenVSwitch interfaces of type "patch".
**/
enum {
PROP_0,
PROP_PEER,
LAST_PROP
};
/**
* NMSettingOvsPatch:
*
* OvsPatch Link Settings
*/
struct _NMSettingOvsPatch {
NMSetting parent;
char *peer;
};
struct _NMSettingOvsPatchClass {
NMSettingClass parent;
};
G_DEFINE_TYPE_WITH_CODE (NMSettingOvsPatch, nm_setting_ovs_patch, NM_TYPE_SETTING,
_nm_register_setting (OVS_PATCH, NM_SETTING_PRIORITY_HW_BASE))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_OVS_PATCH)
/*****************************************************************************/
/**
* nm_setting_ovs_patch_get_peer:
* @self: the #NMSettingOvsPatch
*
* Returns: the #NMSettingOvsPatch:peer property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_patch_get_peer (NMSettingOvsPatch *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PATCH (self), NULL);
return self->peer;
}
/*****************************************************************************/
static int
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH (setting);
int family = AF_UNSPEC;
if (!_nm_connection_verify_required_interface_name (connection, error))
return FALSE;
if (!self->peer) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ",
NM_SETTING_OVS_PATCH_SETTING_NAME,
NM_SETTING_OVS_PATCH_PEER);
return FALSE;
}
if (nm_utils_ipaddr_valid (AF_INET, self->peer))
family = AF_INET;
else if (nm_utils_ipaddr_valid (AF_INET6, self->peer))
family = AF_INET6;
else {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not a valid IP address"),
self->peer);
g_prefix_error (error, "%s.%s: ",
NM_SETTING_OVS_PATCH_SETTING_NAME,
NM_SETTING_OVS_PATCH_PEER);
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH (object);
switch (prop_id) {
case PROP_PEER:
g_value_set_string (value, self->peer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH (object);
switch (prop_id) {
case PROP_PEER:
g_free (self->peer);
self->peer = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_setting_ovs_patch_init (NMSettingOvsPatch *self)
{
}
/**
* nm_setting_ovs_patch_new:
*
* Creates a new #NMSettingOvsPatch object with default values.
*
* Returns: (transfer full): the new empty #NMSettingOvsPatch object
*
* Since: 1.10
**/
NMSetting *
nm_setting_ovs_patch_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_OVS_PATCH, NULL);
}
static void
finalize (GObject *object)
{
NMSettingOvsPatch *self = NM_SETTING_OVS_PATCH (object);
g_free (self->peer);
G_OBJECT_CLASS (nm_setting_ovs_patch_parent_class)->finalize (object);
}
static void
nm_setting_ovs_patch_class_init (NMSettingOvsPatchClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
/**
* NMSettingOvsPatch:peer:
*
* Specifies the unicast destination IP address of a remote OpenVSwitch
* bridge port to connect to.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_PEER,
g_param_spec_string (NM_SETTING_OVS_PATCH_PEER, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -0,0 +1,54 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_SETTING_OVS_PATCH_H__
#define __NM_SETTING_OVS_PATCH_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_OVS_PATCH (nm_setting_ovs_patch_get_type ())
#define NM_SETTING_OVS_PATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_OVS_PATCH, NMSettingOvsPatch))
#define NM_SETTING_OVS_PATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_OVS_PATCHCONFIG, NMSettingOvsPatchClass))
#define NM_IS_SETTING_OVS_PATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_OVS_PATCH))
#define NM_IS_SETTING_OVS_PATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_OVS_PATCH))
#define NM_SETTING_OVS_PATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_OVS_PATCH, NMSettingOvsPatchClass))
#define NM_SETTING_OVS_PATCH_SETTING_NAME "ovs-patch"
#define NM_SETTING_OVS_PATCH_PEER "peer"
typedef struct _NMSettingOvsPatchClass NMSettingOvsPatchClass;
NM_AVAILABLE_IN_1_10
GType nm_setting_ovs_patch_get_type (void);
NM_AVAILABLE_IN_1_10
NMSetting *nm_setting_ovs_patch_new (void);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_patch_get_peer (NMSettingOvsPatch *self);
G_END_DECLS
#endif /* __NM_SETTING_OVS_PATCH_H__ */

View file

@ -0,0 +1,471 @@
/* -*- 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-setting-ovs-port.h"
#include "nm-connection-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-private.h"
/**
* SECTION:nm-setting-ovs-port
* @short_description: Describes connection properties for OpenVSwitch ports.
*
* The #NMSettingOvsPort object is a #NMSetting subclass that describes properties
* necessary for OpenVSwitch ports.
**/
enum {
PROP_0,
PROP_VLAN_MODE,
PROP_TAG,
PROP_LACP,
PROP_BOND_MODE,
PROP_BOND_UPDELAY,
PROP_BOND_DOWNDELAY,
LAST_PROP
};
/**
* NMSettingOvsPort:
*
* OvsPort Link Settings
*/
struct _NMSettingOvsPort {
NMSetting parent;
char *vlan_mode;
guint tag;
char *lacp;
char *bond_mode;
guint bond_updelay;
guint bond_downdelay;
};
struct _NMSettingOvsPortClass {
NMSettingClass parent;
};
G_DEFINE_TYPE_WITH_CODE (NMSettingOvsPort, nm_setting_ovs_port, NM_TYPE_SETTING,
_nm_register_setting (OVS_PORT, NM_SETTING_PRIORITY_HW_BASE))
NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_OVS_PORT)
/*****************************************************************************/
/**
* nm_setting_ovs_port_get_vlan_mode:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:vlan-mode property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_port_get_vlan_mode (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), NULL);
return self->vlan_mode;
}
/**
* nm_setting_ovs_port_get_tag:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:tag property of the setting
*
* Since: 1.10
**/
guint
nm_setting_ovs_port_get_tag (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), 0);
return self->tag;
}
/**
* nm_setting_ovs_port_get_lacp:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:lacp property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_port_get_lacp (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), NULL);
return self->lacp;
}
/**
* nm_setting_ovs_port_get_bond_mode:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:bond-mode property of the setting
*
* Since: 1.10
**/
const char *
nm_setting_ovs_port_get_bond_mode (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), NULL);
return self->bond_mode;
}
/**
* nm_setting_ovs_port_get_bond_updelay:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:bond-updelay property of the setting
*
* Since: 1.10
**/
guint
nm_setting_ovs_port_get_bond_updelay (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), 0);
return self->bond_updelay;
}
/**
* nm_setting_ovs_port_get_bond_downdelay:
* @self: the #NMSettingOvsPort
*
* Returns: the #NMSettingOvsPort:bond-downdelay property of the setting
*
* Since: 1.10
**/
guint
nm_setting_ovs_port_get_bond_downdelay (NMSettingOvsPort *self)
{
g_return_val_if_fail (NM_IS_SETTING_OVS_PORT (self), 0);
return self->bond_downdelay;
}
/*****************************************************************************/
static int
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingOvsPort *self = NM_SETTING_OVS_PORT (setting);
if (!_nm_connection_verify_required_interface_name (connection, error))
return FALSE;
if (connection) {
NMSettingConnection *s_con;
const char *slave_type;
s_con = nm_connection_get_setting_connection (connection);
if (!s_con) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_SETTING,
_("missing setting"));
g_prefix_error (error, "%s: ", NM_SETTING_CONNECTION_SETTING_NAME);
return FALSE;
}
if (!nm_setting_connection_get_master (s_con)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have a master."),
NM_SETTING_OVS_PORT_SETTING_NAME);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER);
return FALSE;
}
slave_type = nm_setting_connection_get_slave_type (s_con);
if ( slave_type
&& strcmp (slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("A connection with a '%s' setting must have the slave-type set to '%s'. Instead it is '%s'"),
NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
slave_type);
g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
return FALSE;
}
}
if (!NM_IN_STRSET (self->vlan_mode, "access", "native-tagged", "native-untagged", "trunk", NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not allowed in vlan_mode"),
self->vlan_mode);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_PORT_VLAN_MODE);
return FALSE;
}
if (self->tag >= 4095) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("the tag id must be in range 0-4094 but is %u"),
self->tag);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_PORT_TAG);
return FALSE;
}
if (!NM_IN_STRSET (self->lacp, "active", "off", "passive", NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not allowed in lacp"),
self->lacp);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_PORT_LACP);
return FALSE;
}
if (!NM_IN_STRSET (self->bond_mode, "active-backup", "balance-slb", "balance-tcp", NULL)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' is not allowed in bond_mode"),
self->bond_mode);
g_prefix_error (error, "%s.%s: ", NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_OVS_PORT_BOND_MODE);
return FALSE;
}
return TRUE;
}
/*****************************************************************************/
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSettingOvsPort *self = NM_SETTING_OVS_PORT (object);
switch (prop_id) {
case PROP_VLAN_MODE:
g_value_set_string (value, self->vlan_mode);
break;
case PROP_TAG:
g_value_set_uint (value, self->tag);
break;
case PROP_LACP:
g_value_set_string (value, self->lacp);
break;
case PROP_BOND_MODE:
g_value_set_string (value, self->bond_mode);
break;
case PROP_BOND_UPDELAY:
g_value_set_uint (value, self->bond_updelay);
break;
case PROP_BOND_DOWNDELAY:
g_value_set_uint (value, self->bond_downdelay);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMSettingOvsPort *self = NM_SETTING_OVS_PORT (object);
switch (prop_id) {
case PROP_VLAN_MODE:
g_free (self->vlan_mode);
self->vlan_mode = g_value_dup_string (value);
break;
case PROP_TAG:
self->tag = g_value_get_uint (value);
break;
case PROP_LACP:
g_free (self->lacp);
self->lacp = g_value_dup_string (value);
break;
case PROP_BOND_MODE:
g_free (self->bond_mode);
self->bond_mode = g_value_dup_string (value);
break;
case PROP_BOND_UPDELAY:
self->bond_updelay = g_value_get_uint (value);
break;
case PROP_BOND_DOWNDELAY:
self->bond_downdelay = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_setting_ovs_port_init (NMSettingOvsPort *self)
{
}
/**
* nm_setting_ovs_port_new:
*
* Creates a new #NMSettingOvsPort object with default values.
*
* Returns: (transfer full): the new empty #NMSettingOvsPort object
*
* Since: 1.10
**/
NMSetting *
nm_setting_ovs_port_new (void)
{
return (NMSetting *) g_object_new (NM_TYPE_SETTING_OVS_PORT, NULL);
}
static void
finalize (GObject *object)
{
NMSettingOvsPort *self = NM_SETTING_OVS_PORT (object);
g_free (self->vlan_mode);
g_free (self->lacp);
g_free (self->bond_mode);
G_OBJECT_CLASS (nm_setting_ovs_port_parent_class)->finalize (object);
}
static void
nm_setting_ovs_port_class_init (NMSettingOvsPortClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
parent_class->verify = verify;
/**
* NMSettingOvsPort:vlan-mode:
*
* The VLAN mode. One of "access", "native-tagged", "native-untagged",
* "trunk" or unset.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_VLAN_MODE,
g_param_spec_string (NM_SETTING_OVS_PORT_VLAN_MODE, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsPort:tag:
*
* The VLAN tag in the range 0-4095.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_TAG,
g_param_spec_uint (NM_SETTING_OVS_PORT_TAG, "", "",
0, 4095, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsPort:lacp:
*
* LACP mode. One of "active", "off", or "passive".
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_LACP,
g_param_spec_string (NM_SETTING_OVS_PORT_LACP, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsPort:bond-mode:
*
* Bonding mode. One of "active-backup", "balance-slb", or "balance-tcp".
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_BOND_MODE,
g_param_spec_string (NM_SETTING_OVS_PORT_BOND_MODE, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsPort:bond-updelay:
*
* The time port must be active befor it starts forwarding traffic.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_BOND_UPDELAY,
g_param_spec_uint (NM_SETTING_OVS_PORT_BOND_UPDELAY, "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingOvsPort:bond-downdelay:
*
* The time port must be inactive in order to be considered down.
*
* Since: 1.10
**/
g_object_class_install_property
(object_class, PROP_BOND_DOWNDELAY,
g_param_spec_uint (NM_SETTING_OVS_PORT_BOND_DOWNDELAY, "", "",
0, G_MAXUINT, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -0,0 +1,69 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_SETTING_OVS_PORT_H__
#define __NM_SETTING_OVS_PORT_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-setting.h"
G_BEGIN_DECLS
#define NM_TYPE_SETTING_OVS_PORT (nm_setting_ovs_port_get_type ())
#define NM_SETTING_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_OVS_PORT, NMSettingOvsPort))
#define NM_SETTING_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_OVS_PORTCONFIG, NMSettingOvsPortClass))
#define NM_IS_SETTING_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_OVS_PORT))
#define NM_IS_SETTING_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_OVS_PORT))
#define NM_SETTING_OVS_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_OVS_PORT, NMSettingOvsPortClass))
#define NM_SETTING_OVS_PORT_SETTING_NAME "ovs-port"
#define NM_SETTING_OVS_PORT_VLAN_MODE "vlan-mode"
#define NM_SETTING_OVS_PORT_TAG "tag"
#define NM_SETTING_OVS_PORT_LACP "lacp"
#define NM_SETTING_OVS_PORT_BOND_MODE "bond-mode"
#define NM_SETTING_OVS_PORT_BOND_UPDELAY "bond-updelay"
#define NM_SETTING_OVS_PORT_BOND_DOWNDELAY "bond-downdelay"
typedef struct _NMSettingOvsPortClass NMSettingOvsPortClass;
NM_AVAILABLE_IN_1_10
GType nm_setting_ovs_port_get_type (void);
NM_AVAILABLE_IN_1_10
NMSetting *nm_setting_ovs_port_new (void);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_port_get_vlan_mode (NMSettingOvsPort *self);
NM_AVAILABLE_IN_1_10
guint nm_setting_ovs_port_get_tag (NMSettingOvsPort *self);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_port_get_lacp (NMSettingOvsPort *self);
NM_AVAILABLE_IN_1_10
const char *nm_setting_ovs_port_get_bond_mode (NMSettingOvsPort *self);
NM_AVAILABLE_IN_1_10
guint nm_setting_ovs_port_get_bond_updelay (NMSettingOvsPort *self);
NM_AVAILABLE_IN_1_10
guint nm_setting_ovs_port_get_bond_downdelay (NMSettingOvsPort *self);
G_END_DECLS
#endif /* __NM_SETTING_OVS_PORT_H__ */

View file

@ -219,7 +219,7 @@ _nm_setting_get_base_type_priority (NMSetting *setting)
GType
nm_setting_lookup_type (const char *name)
{
SettingInfo *info;
const SettingInfo *info;
g_return_val_if_fail (name, G_TYPE_INVALID);
@ -258,6 +258,10 @@ _nm_setting_slave_type_is_valid (const char *slave_type, const char **out_port_t
;
else if (!strcmp (slave_type, NM_SETTING_BRIDGE_SETTING_NAME))
port_type = NM_SETTING_BRIDGE_PORT_SETTING_NAME;
else if (!strcmp (slave_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME))
port_type = NM_SETTING_OVS_PORT_SETTING_NAME;
else if (!strcmp (slave_type, NM_SETTING_OVS_PORT_SETTING_NAME))
port_type = NM_SETTING_OVS_INTERFACE_SETTING_NAME;
else if (!strcmp (slave_type, NM_SETTING_TEAM_SETTING_NAME))
port_type = NM_SETTING_TEAM_PORT_SETTING_NAME;
else

View file

@ -4654,6 +4654,344 @@ test_connection_normalize_shared_addresses (void)
g_assert_cmpstr (nm_ip_address_get_address (addr), ==, "1.1.1.1");
}
static void
test_connection_normalize_ovs_interface_type_system (gconstpointer test_data)
{
const guint TEST_CASE = GPOINTER_TO_UINT (test_data);
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
NMSettingOvsInterface *s_ovs_if;
con = nmtst_create_minimal_connection ("test_connection_normalize_ovs_interface_type_system",
NULL,
NM_SETTING_WIRED_SETTING_NAME, &s_con);
switch (TEST_CASE) {
case 1:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
s_ovs_if = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_if);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "system");
break;
case 2:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "system");
break;
case 3:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
break;
case 4:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
/* the setting doesn't verify, because the interface-type must be "system". */
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 5:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
break;
case 6:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME,
NULL);
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 7:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_BRIDGE_SETTING_NAME,
NULL);
nm_connection_add_setting (con, nm_setting_bridge_port_new ());
s_ovs_if = NM_SETTING_OVS_INTERFACE (nm_setting_ovs_interface_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_if));
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
default:
g_assert_not_reached ();
break;
}
}
static void
test_connection_normalize_ovs_interface_type_ovs_interface (gconstpointer test_data)
{
const guint TEST_CASE = GPOINTER_TO_UINT (test_data);
gs_unref_object NMConnection *con = NULL;
NMSettingConnection *s_con;
NMSettingOvsInterface *s_ovs_if;
NMSettingOvsPatch *s_ovs_patch;
NMSettingIP4Config *s_ip4;
NMSettingIP6Config *s_ip6;
con = nmtst_create_minimal_connection ("test_connection_normalize_ovs_interface_type_ovs_interface",
NULL,
NM_SETTING_OVS_INTERFACE_SETTING_NAME, &s_con);
s_ovs_if = nm_connection_get_setting_ovs_interface (con);
g_assert (s_ovs_if);
switch (TEST_CASE) {
case 1:
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 2:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 3:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 4:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 5:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nm_connection_add_setting (con, nm_setting_ip4_config_new ());
nm_connection_add_setting (con, nm_setting_ip6_config_new ());
nm_connection_add_setting (con, nm_setting_proxy_new ());
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting_ip4_config (con));
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (con));
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, "auto",
NULL);
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, "auto",
NULL);
nmtst_assert_connection_verifies_without_normalization (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
break;
case 6:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "internal",
NULL);
nmtst_assert_connection_verifies_and_normalizable (con);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "internal");
break;
case 7:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "system",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 8:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "bogus",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
break;
case 9:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING);
break;
case 10:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nm_connection_add_setting (con, nm_setting_ovs_patch_new ());
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
break;
case 11:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
nm_connection_add_setting (con, nm_setting_ovs_patch_new ());
nmtst_assert_connection_unnormalizable (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY);
break;
case 12:
g_object_set (s_con,
NM_SETTING_CONNECTION_MASTER, "master0",
NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_OVS_PORT_SETTING_NAME,
NM_SETTING_CONNECTION_INTERFACE_NAME, "adsf",
NULL);
g_object_set (s_ovs_if,
NM_SETTING_OVS_INTERFACE_TYPE, "patch",
NULL);
s_ovs_patch = NM_SETTING_OVS_PATCH (nm_setting_ovs_patch_new ());
nm_connection_add_setting (con, NM_SETTING (s_ovs_patch));
g_object_set (s_ovs_patch,
NM_SETTING_OVS_PATCH_PEER, "1.2.3.4",
NULL);
nmtst_assert_connection_verifies_and_normalizable (con);
nmtst_connection_normalize (con);
nmtst_assert_connection_has_settings (con, NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME,
NM_SETTING_OVS_PATCH_SETTING_NAME);
g_assert (s_con == nm_connection_get_setting_connection (con));
g_assert (s_ovs_if == nm_connection_get_setting_ovs_interface (con));
g_assert_cmpstr (nm_setting_connection_get_slave_type (s_con), ==, NM_SETTING_OVS_PORT_SETTING_NAME);
g_assert_cmpstr (nm_setting_ovs_interface_get_interface_type (s_ovs_if), ==, "patch");
break;
default:
g_assert_not_reached ();
}
}
static void
test_setting_ip4_gateway (void)
{
@ -6540,6 +6878,25 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_connection_normalize_gateway_never_default", test_connection_normalize_gateway_never_default);
g_test_add_func ("/core/general/test_connection_normalize_may_fail", test_connection_normalize_may_fail);
g_test_add_func ("/core/general/test_connection_normalize_shared_addresses", test_connection_normalize_shared_addresses);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/1", GUINT_TO_POINTER (1), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/2", GUINT_TO_POINTER (2), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/3", GUINT_TO_POINTER (3), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/4", GUINT_TO_POINTER (4), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/5", GUINT_TO_POINTER (5), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/6", GUINT_TO_POINTER (6), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_system/7", GUINT_TO_POINTER (7), test_connection_normalize_ovs_interface_type_system);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/1", GUINT_TO_POINTER (1), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/2", GUINT_TO_POINTER (2), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/3", GUINT_TO_POINTER (3), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/4", GUINT_TO_POINTER (4), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/5", GUINT_TO_POINTER (5), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/6", GUINT_TO_POINTER (6), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/7", GUINT_TO_POINTER (7), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/8", GUINT_TO_POINTER (8), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/9", GUINT_TO_POINTER (9), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/10", GUINT_TO_POINTER (10), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/11", GUINT_TO_POINTER (11), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_data_func ("/core/general/test_connection_normalize_ovs_interface_type_ovs_interface/12", GUINT_TO_POINTER (12), test_connection_normalize_ovs_interface_type_ovs_interface);
g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers);
g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property);

View file

@ -41,6 +41,9 @@
#include "nm-device-macvlan.h"
#include "nm-device-modem.h"
#include "nm-device-olpc-mesh.h"
#include "nm-device-ovs-interface.h"
#include "nm-device-ovs-port.h"
#include "nm-device-ovs-bridge.h"
#include "nm-device-team.h"
#include "nm-device-tun.h"
#include "nm-device-vlan.h"
@ -73,6 +76,10 @@
#include "nm-setting-macsec.h"
#include "nm-setting-macvlan.h"
#include "nm-setting-olpc-mesh.h"
#include "nm-setting-ovs-bridge.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-patch.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ppp.h"
#include "nm-setting-pppoe.h"
#include "nm-setting-proxy.h"

View file

@ -257,6 +257,9 @@ for settingxml in settings:
prop_upper = prop.upper().replace('-', '_')
if value_desc is None:
raise Exception("%s.%s needs a documentation description" % (setting.props.name, prop))
if default_value is not None:
outfile.write(" <property name=\"%s\" name_upper=\"%s\" type=\"%s\" default=\"%s\" description=\"%s\" />\n" %
(prop, prop_upper, value_type, escape(default_value), escape(value_desc)))

View file

@ -1185,11 +1185,35 @@ global:
nm_client_connectivity_check_get_available;
nm_client_connectivity_check_get_enabled;
nm_client_connectivity_check_set_enabled;
nm_connection_get_settings;
nm_device_dummy_get_hw_address;
nm_device_ovs_bridge_get_type;
nm_device_ovs_interface_get_type;
nm_device_ovs_port_get_type;
nm_device_ppp_get_type;
nm_ip_route_equal_full;
nm_setting_bridge_get_group_forward_mask;
nm_setting_ip_config_get_route_table;
nm_setting_ovs_bridge_get_fail_mode;
nm_setting_ovs_bridge_get_mcast_snooping_enable;
nm_setting_ovs_bridge_get_rstp_enable;
nm_setting_ovs_bridge_get_stp_enable;
nm_setting_ovs_bridge_get_type;
nm_setting_ovs_bridge_new;
nm_setting_ovs_interface_get_interface_type;
nm_setting_ovs_interface_get_type;
nm_setting_ovs_interface_new;
nm_setting_ovs_patch_get_peer;
nm_setting_ovs_patch_get_type;
nm_setting_ovs_patch_new;
nm_setting_ovs_port_get_bond_downdelay;
nm_setting_ovs_port_get_bond_mode;
nm_setting_ovs_port_get_bond_updelay;
nm_setting_ovs_port_get_lacp;
nm_setting_ovs_port_get_tag;
nm_setting_ovs_port_get_type;
nm_setting_ovs_port_get_vlan_mode;
nm_setting_ovs_port_new;
nm_setting_pppoe_get_parent;
nm_setting_wireless_security_get_pmf;
nm_setting_wireless_security_get_wps_method;

View file

@ -63,6 +63,9 @@
#include "nm-device-macvlan.h"
#include "nm-device-modem.h"
#include "nm-device-olpc-mesh.h"
#include "nm-device-ovs-interface.h"
#include "nm-device-ovs-port.h"
#include "nm-device-ovs-bridge.h"
#include "nm-device-ppp.h"
#include "nm-device-team.h"
#include "nm-device-tun.h"
@ -2147,6 +2150,12 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager
type = NM_TYPE_DEVICE_MODEM;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH) == 0)
type = NM_TYPE_DEVICE_OLPC_MESH;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE) == 0)
type = NM_TYPE_DEVICE_OVS_INTERFACE;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_PORT) == 0)
type = NM_TYPE_DEVICE_OVS_PORT;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE) == 0)
type = NM_TYPE_DEVICE_OVS_BRIDGE;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_PPP) == 0)
type = NM_TYPE_DEVICE_PPP;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TEAM) == 0)

View file

@ -0,0 +1,96 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include <string.h>
#include "nm-device-ovs-bridge.h"
#include "nm-object-private.h"
#include "nm-setting-ovs-bridge.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-connection.h"
/**
* NMDeviceOvsBridge:
*/
struct _NMDeviceOvsBridge {
NMDevice parent;
};
struct _NMDeviceOvsBridgeClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsBridge, nm_device_ovs_bridge, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-bridge";
}
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
const char *iface_name;
if (!NM_DEVICE_CLASS (nm_device_ovs_bridge_parent_class)->connection_compatible (device, connection, error))
return FALSE;
if (!nm_connection_is_type (connection, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
_("The connection was not a ovs_bridge connection."));
return FALSE;
}
iface_name = nm_connection_get_interface_name (connection);
if (!iface_name) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
_("The connection did not specify an interface name."));
return FALSE;
}
return TRUE;
}
static GType
get_setting_type (NMDevice *device)
{
return NM_TYPE_SETTING_OVS_BRIDGE;
}
/*****************************************************************************/
static void
nm_device_ovs_bridge_init (NMDeviceOvsBridge *device)
{
}
static void
nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *ovs_bridge_class)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (ovs_bridge_class);
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
}

View file

@ -0,0 +1,45 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_OVS_BRIDGE_H__
#define __NM_DEVICE_OVS_BRIDGE_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-device.h"
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_OVS_BRIDGE (nm_device_ovs_bridge_get_type ())
#define NM_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridge))
#define NM_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass))
#define NM_IS_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_BRIDGE))
#define NM_IS_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_BRIDGE))
#define NM_DEVICE_OVS_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass))
typedef struct _NMDeviceOvsBridgeClass NMDeviceOvsBridgeClass;
NM_AVAILABLE_IN_1_10
GType nm_device_ovs_bridge_get_type (void);
G_END_DECLS
#endif /* __NM_DEVICE_OVS_BRIDGE_H__ */

View file

@ -0,0 +1,96 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include <string.h>
#include "nm-device-ovs-interface.h"
#include "nm-object-private.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-connection.h"
/**
* NMDeviceOvsInterface:
*/
struct _NMDeviceOvsInterface {
NMDevice parent;
};
struct _NMDeviceOvsInterfaceClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsInterface, nm_device_ovs_interface, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-interface";
}
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
const char *iface_name;
if (!NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->connection_compatible (device, connection, error))
return FALSE;
if (!nm_connection_is_type (connection, NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
_("The connection was not a ovs_interface connection."));
return FALSE;
}
iface_name = nm_connection_get_interface_name (connection);
if (!iface_name) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
_("The connection did not specify an interface name."));
return FALSE;
}
return TRUE;
}
static GType
get_setting_type (NMDevice *device)
{
return NM_TYPE_SETTING_OVS_INTERFACE;
}
/*****************************************************************************/
static void
nm_device_ovs_interface_init (NMDeviceOvsInterface *device)
{
}
static void
nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *ovs_interface_class)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (ovs_interface_class);
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
}

View file

@ -0,0 +1,45 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_OVS_INTERFACE_H__
#define __NM_DEVICE_OVS_INTERFACE_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-device.h"
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_OVS_INTERFACE (nm_device_ovs_interface_get_type ())
#define NM_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterface))
#define NM_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass))
#define NM_IS_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_INTERFACE))
#define NM_IS_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_INTERFACE))
#define NM_DEVICE_OVS_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass))
typedef struct _NMDeviceOvsInterfaceClass NMDeviceOvsInterfaceClass;
NM_AVAILABLE_IN_1_10
GType nm_device_ovs_interface_get_type (void);
G_END_DECLS
#endif /* __NM_DEVICE_OVS_INTERFACE_H__ */

View file

@ -0,0 +1,95 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include <string.h>
#include "nm-device-ovs-port.h"
#include "nm-object-private.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-connection.h"
/**
* NMDeviceOvsPort:
*/
struct _NMDeviceOvsPort {
NMDevice parent;
};
struct _NMDeviceOvsPortClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsPort, nm_device_ovs_port, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-port";
}
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
const char *iface_name;
if (!NM_DEVICE_CLASS (nm_device_ovs_port_parent_class)->connection_compatible (device, connection, error))
return FALSE;
if (!nm_connection_is_type (connection, NM_SETTING_OVS_PORT_SETTING_NAME)) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
_("The connection was not a ovs_port connection."));
return FALSE;
}
iface_name = nm_connection_get_interface_name (connection);
if (!iface_name) {
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
_("The connection did not specify an interface name."));
return FALSE;
}
return TRUE;
}
static GType
get_setting_type (NMDevice *device)
{
return NM_TYPE_SETTING_OVS_PORT;
}
/*****************************************************************************/
static void
nm_device_ovs_port_init (NMDeviceOvsPort *device)
{
}
static void
nm_device_ovs_port_class_init (NMDeviceOvsPortClass *ovs_port_class)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (ovs_port_class);
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
}

View file

@ -0,0 +1,45 @@
/*
* 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.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2017 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_OVS_PORT_H__
#define __NM_DEVICE_OVS_PORT_H__
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
#error "Only <NetworkManager.h> can be included directly."
#endif
#include "nm-device.h"
G_BEGIN_DECLS
#define NM_TYPE_DEVICE_OVS_PORT (nm_device_ovs_port_get_type ())
#define NM_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPort))
#define NM_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass))
#define NM_IS_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_PORT))
#define NM_IS_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_PORT))
#define NM_DEVICE_OVS_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass))
typedef struct _NMDeviceOvsPortClass NMDeviceOvsPortClass;
NM_AVAILABLE_IN_1_10
GType nm_device_ovs_port_get_type (void);
G_END_DECLS
#endif /* __NM_DEVICE_OVS_PORT_H__ */

View file

@ -261,6 +261,9 @@ coerce_type (NMDeviceType type)
case NM_DEVICE_TYPE_WIFI:
case NM_DEVICE_TYPE_BT:
case NM_DEVICE_TYPE_OLPC_MESH:
case NM_DEVICE_TYPE_OVS_INTERFACE:
case NM_DEVICE_TYPE_OVS_PORT:
case NM_DEVICE_TYPE_OVS_BRIDGE:
case NM_DEVICE_TYPE_WIMAX:
case NM_DEVICE_TYPE_MODEM:
case NM_DEVICE_TYPE_INFINIBAND:
@ -1522,6 +1525,12 @@ get_type_name (NMDevice *device)
return _("Bluetooth");
case NM_DEVICE_TYPE_OLPC_MESH:
return _("OLPC Mesh");
case NM_DEVICE_TYPE_OVS_INTERFACE:
return _("OpenVSwitch Interface");
case NM_DEVICE_TYPE_OVS_PORT:
return _("OpenVSwitch Port");
case NM_DEVICE_TYPE_OVS_BRIDGE:
return _("OpenVSwitch Bridge");
case NM_DEVICE_TYPE_WIMAX:
return _("WiMAX");
case NM_DEVICE_TYPE_MODEM:

View file

@ -26,35 +26,38 @@
#include "nm-dbus-interface.h"
#include "nm-connection.h"
typedef struct _NMAccessPoint NMAccessPoint;
typedef struct _NMActiveConnection NMActiveConnection;
typedef struct _NMClient NMClient;
typedef struct _NMDevice NMDevice;
typedef struct _NMDeviceAdsl NMDeviceAdsl;
typedef struct _NMDeviceBond NMDeviceBond;
typedef struct _NMDeviceBridge NMDeviceBridge;
typedef struct _NMDeviceBt NMDeviceBt;
typedef struct _NMDeviceDummy NMDeviceDummy;
typedef struct _NMDeviceEthernet NMDeviceEthernet;
typedef struct _NMDeviceGeneric NMDeviceGeneric;
typedef struct _NMDeviceInfiniband NMDeviceInfiniband;
typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel;
typedef struct _NMDeviceMacsec NMDeviceMacsec;
typedef struct _NMDeviceMacvlan NMDeviceMacvlan;
typedef struct _NMDeviceModem NMDeviceModem;
typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;
typedef struct _NMDevicePpp NMDevicePpp;
typedef struct _NMDeviceTeam NMDeviceTeam;
typedef struct _NMDeviceTun NMDeviceTun;
typedef struct _NMDeviceVlan NMDeviceVlan;
typedef struct _NMDeviceVxlan NMDeviceVxlan;
typedef struct _NMDeviceWifi NMDeviceWifi;
typedef struct _NMDeviceWimax NMDeviceWimax;
typedef struct _NMDhcpConfig NMDhcpConfig;
typedef struct _NMIPConfig NMIPConfig;
typedef struct _NMObject NMObject;
typedef struct _NMRemoteConnection NMRemoteConnection;
typedef struct _NMVpnConnection NMVpnConnection;
typedef struct _NMWimaxNsp NMWimaxNsp;
typedef struct _NMAccessPoint NMAccessPoint;
typedef struct _NMActiveConnection NMActiveConnection;
typedef struct _NMClient NMClient;
typedef struct _NMDevice NMDevice;
typedef struct _NMDeviceAdsl NMDeviceAdsl;
typedef struct _NMDeviceBond NMDeviceBond;
typedef struct _NMDeviceBridge NMDeviceBridge;
typedef struct _NMDeviceBt NMDeviceBt;
typedef struct _NMDeviceDummy NMDeviceDummy;
typedef struct _NMDeviceEthernet NMDeviceEthernet;
typedef struct _NMDeviceGeneric NMDeviceGeneric;
typedef struct _NMDeviceInfiniband NMDeviceInfiniband;
typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel;
typedef struct _NMDeviceMacsec NMDeviceMacsec;
typedef struct _NMDeviceMacvlan NMDeviceMacvlan;
typedef struct _NMDeviceModem NMDeviceModem;
typedef struct _NMDeviceOlpcMesh NMDeviceOlpcMesh;
typedef struct _NMDeviceOvsBridge NMDeviceOvsBridge;
typedef struct _NMDeviceOvsInterface NMDeviceOvsInterface;
typedef struct _NMDeviceOvsPort NMDeviceOvsPort;
typedef struct _NMDevicePpp NMDevicePpp;
typedef struct _NMDeviceTeam NMDeviceTeam;
typedef struct _NMDeviceTun NMDeviceTun;
typedef struct _NMDeviceVlan NMDeviceVlan;
typedef struct _NMDeviceVxlan NMDeviceVxlan;
typedef struct _NMDeviceWifi NMDeviceWifi;
typedef struct _NMDeviceWimax NMDeviceWimax;
typedef struct _NMDhcpConfig NMDhcpConfig;
typedef struct _NMIPConfig NMIPConfig;
typedef struct _NMObject NMObject;
typedef struct _NMRemoteConnection NMRemoteConnection;
typedef struct _NMVpnConnection NMVpnConnection;
typedef struct _NMWimaxNsp NMWimaxNsp;
#endif /* NM_TYPES_H */

204
man/nm-openvswitch.xml Normal file
View file

@ -0,0 +1,204 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
<!--
nmcli-examples(7) manual page
Copyright 2017 Red Hat, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. You may obtain a copy of the GNU Free Documentation License
from the Free Software Foundation by visiting their Web site or by
writing to:
Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<refentry id="nm-openvswitch">
<refentryinfo>
<title>nm-openvswitch</title>
<author>NetworkManager OpenVSwitch support</author>
</refentryinfo>
<refmeta>
<refentrytitle>nm-openvswitch</refentrytitle>
<manvolnum>7</manvolnum>
<refmiscinfo class="source">NetworkManager</refmiscinfo>
<refmiscinfo class="manual">OpenVSwitch support overview</refmiscinfo>
<refmiscinfo class="version">&NM_VERSION;</refmiscinfo>
</refmeta>
<refnamediv>
<refname>nm-openvswitch</refname>
<refpurpose>overview of NetworkManager OpenVSwitch support</refpurpose>
</refnamediv>
<refsect1>
<title>Overview</title>
<para>NetworkManager includes basic OpenVSwitch support, good enough
to be capable of setting up simple OpenVSwitch configurations. It is not
extensive and does not expose all functionality of OpenVSwitch provides.
For large or complicated deployments users are advised to use native tools
shipped with OpenVSwitch. This document seeks to provide overview of
functionality currently provided by NetworkManager, its capabilities and
limitations.</para>
<para>First and foremost: NetworkManager applies the configuration by
modifying the OVSDB directly. Its configuration model follows the OVSDB
database model closely and it does not provide the level of abstraction
<command>ovs-vsctl</command> provides.</para>
<para>In practical terms it means the following:
<itemizedlist>
<listitem>
<para>NetworkManager only ever talks to a single OVSDB instance via an
UNIX domain socket.</para>
</listitem>
<listitem>
<para>The configuration is made up of Bridges, Ports and
Interfaces. Interfaces are always enslaved to Ports, and Ports are always
enslaved to Bridges.</para>
</listitem>
<listitem>
<para>NetworkManager only creates Bridges, Ports and Interfaces
you ask it to. Unlike <command>ovs-vsctl</command>, it doesn't create the
local interface nor its port automatically.</para>
</listitem>
<listitem>
<para>You can't enslave Interface directly to a Bridge. You
always need a Port, even if it has just one interface.</para>
</listitem>
<listitem>
<para>There are no VLANs. The VLAN tagging is enabled by setting a
<link linkend="nm-settings.property.ovs-port.tag">ovs-port.tag</link>
property on a Port.</para>
</listitem>
<listitem>
<para>There are no bonds either. The bonding is enabled by
enslaving multiple Interfaces to a Port and configured by setting
properties on a port.</para>
</listitem>
</itemizedlist>
</para>
<refsect2>
<title>Bridges</title>
<para>Bridges are represented by connections of ovs-bridge
<link linkend="nm-settings.property.connection.type">type</link>.
Due to the limitations of OVSDB, "empty" Bridges (with no Ports) can't exist.
NetworkManager inserts the records for Bridges into OVSDB when a Port is
enslaved.
</para>
</refsect2>
<refsect2>
<title>Ports</title>
<para>Ports are represented by connections of ovs-port
<link linkend="nm-settings.property.connection.type">type</link>.
Due to the limitations of OVSDB, "empty" Ports (with no Interfaces) can't
exist. Ports can also be configured to do VLAN tagging or Bonding.
NetworkManager inserts the records for Ports into OVSDB when an Interface is
enslaved. Ports must be enslaved to a Bridge.</para>
</refsect2>
<refsect2>
<title>Interfaces</title>
<para>Interfaces are represented by a connections enslaved to a Port. The
system interfaces (that have a corresponding Linux link) have a respective
<link linkend="nm-settings.property.connection.type">connection.type</link>
of the link (e.g. "wired", "bond", "dummy", etc.). Other interfaces ("internal"
or "patch" interfaces) are of ovs-interface type. The OVSDB entries are
inserted upon enslavement to a Port.</para>
</refsect2>
</refsect1>
<refsect1>
<title>Examples</title>
<example><title>Creating a Bridge with a single internal Interface</title>
<screen><prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-bridge conn.interface bridge0</userinput>
Connection 'ovs-bridge-bridge0' (d10fc64d-1d48-4394-a1b8-e1aea72f27d5) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-port conn.interface port0 conn.master bridge0</userinput>
Connection 'ovs-port-port0' (5ae22bae-bba4-4815-9ade-7e635633e1f0) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-interface conn.interface iface0 conn.master port0 \
ipv4.method manual ipv4.address 192.0.2.1/24</userinput>
Connection 'ovs-interface-iface0' (3640d2a1-a2fd-4718-92f1-cffadb5b6cdc) successfully added.
</screen>
<para>As said above, you need to create a Port even for a single interface.
Also, before you add the Interface, the Bridge and Port devices appear active,
but are not configured in OVSDB yet. You can inspect the results with
<command>ovs-vsctl show</command>.</para>
</example>
<example><title>Adding a Linux interface to a Bridge</title>
<screen><prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-port conn.interface port1 conn.master bridge0</userinput>
Connection 'ovs-port-port1' (67d041eb-8e7b-4458-afee-a1d07c9c4552) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ethernet conn.interface eth0 conn.master port1</userinput>
Connection 'ovs-slave-eth0' (d459c45c-cf78-4c1c-b4b7-505e71379624) successfully added.
</screen>
<para>Again, you need a port.</para>
</example>
<example><title>Creating a VLAN</title>
<screen><prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-port conn.interface port2 conn.master bridge0 ovs-port.tag 120</userinput>
Connection 'ovs-port-port2' (3994c093-4ef7-4549-a4fd-627b831c3cb8) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ethernet conn.interface eth1 conn.master port2</userinput>
Connection 'ovs-slave-eth1' (099be06e-71ad-484d-8d5a-fcadc5f207f5) successfully added.
</screen>
<para>It's just a port with a tag.</para>
</example>
<example><title>Creating a Bond</title>
<screen><prompt>$ </prompt><userinput>nmcli conn add conn.type ovs-port conn.interface bond0 conn.master bridge0</userinput>
Connection 'ovs-port-bond0' (d154ebf9-e999-4e1b-a084-a3de53d25d8a) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ethernet conn.interface eth2 conn.master bond0</userinput>
Connection 'ovs-slave-eth2' (475ac1bf-30b2-4534-a877-27f33f58b082) successfully added.
<prompt>$ </prompt><userinput>nmcli conn add conn.type ethernet conn.interface eth3 conn.master bond0</userinput>
Connection 'ovs-slave-eth3' (8dedeecb-ed12-482b-b77a-24a4fb835136) successfully added.
</screen>
<para>It's just a Port with multiple interfaces. See nm-settings manual for
Bonding options you can use with "nmcli c add" or "nmcli c modify". You could
even set a VLAN tag on the same Port to do VLAN tagging and bonding at the same
time.</para>
</example>
</refsect1>
<refsect1>
<title>Bugs</title>
<itemizedlist>
<listitem>
<para>Not all OpenVSwitch capabilities are supported.</para>
</listitem>
<listitem>
<para>OpenVSwitch devices don't expose many useful properties on D-Bus.</para>
</listitem>
</itemizedlist>
<para>Probably many more.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<ulink url="https://www.rfc-editor.org/rfc/rfc7047.txt">RFC 7047: The Open vSwitch Database Management Protocol</ulink>,
<citerefentry><refentrytitle>ovs-vsctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>ovs-vswitchd.conf.db</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<link linkend='nm-settings'><citerefentry><refentrytitle>nm-settings</refentrytitle><manvolnum>5</manvolnum></citerefentry></link>,
<link linkend='nmcli'><citerefentry><refentrytitle>nmcli</refentrytitle><manvolnum>1</manvolnum></citerefentry></link>
</para>
</refsect1>
</refentry>

View file

@ -75,6 +75,10 @@ libnm-core/nm-setting-ip-tunnel.c
libnm-core/nm-setting-macsec.c
libnm-core/nm-setting-macvlan.c
libnm-core/nm-setting-olpc-mesh.c
libnm-core/nm-setting-ovs-interface.c
libnm-core/nm-setting-ovs-patch.c
libnm-core/nm-setting-ovs-port.c
libnm-core/nm-setting-ovs-bridge.c
libnm-core/nm-setting-ppp.c
libnm-core/nm-setting-pppoe.c
libnm-core/nm-setting-proxy.c
@ -137,6 +141,9 @@ libnm/nm-device-ip-tunnel.c
libnm/nm-device-macvlan.c
libnm/nm-device-modem.c
libnm/nm-device-olpc-mesh.c
libnm/nm-device-ovs-bridge.c
libnm/nm-device-ovs-interface.c
libnm/nm-device-ovs-port.c
libnm/nm-device-team.c
libnm/nm-device-vlan.c
libnm/nm-device-vxlan.c

View file

@ -43,6 +43,10 @@
#include "nm-setting-macsec.h"
#include "nm-setting-macvlan.h"
#include "nm-setting-olpc-mesh.h"
#include "nm-setting-ovs-bridge.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-patch.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ppp.h"
#include "nm-setting-pppoe.h"
#include "nm-setting-proxy.h"
@ -235,6 +239,26 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
.setting_name = NM_SETTING_OLPC_MESH_SETTING_NAME,
.get_setting_gtype = nm_setting_olpc_mesh_get_type,
},
[NM_META_SETTING_TYPE_OVS_BRIDGE] = {
.meta_type = NM_META_SETTING_TYPE_OVS_BRIDGE,
.setting_name = NM_SETTING_OVS_BRIDGE_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_bridge_get_type,
},
[NM_META_SETTING_TYPE_OVS_INTERFACE] = {
.meta_type = NM_META_SETTING_TYPE_OVS_INTERFACE,
.setting_name = NM_SETTING_OVS_INTERFACE_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_interface_get_type,
},
[NM_META_SETTING_TYPE_OVS_PATCH] = {
.meta_type = NM_META_SETTING_TYPE_OVS_PATCH,
.setting_name = NM_SETTING_OVS_PATCH_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_patch_get_type,
},
[NM_META_SETTING_TYPE_OVS_PORT] = {
.meta_type = NM_META_SETTING_TYPE_OVS_PORT,
.setting_name = NM_SETTING_OVS_PORT_SETTING_NAME,
.get_setting_gtype = nm_setting_ovs_port_get_type,
},
[NM_META_SETTING_TYPE_PPPOE] = {
.meta_type = NM_META_SETTING_TYPE_PPPOE,
.setting_name = NM_SETTING_PPPOE_SETTING_NAME,

View file

@ -75,6 +75,10 @@ typedef enum {
NM_META_SETTING_TYPE_MACSEC,
NM_META_SETTING_TYPE_MACVLAN,
NM_META_SETTING_TYPE_OLPC_MESH,
NM_META_SETTING_TYPE_OVS_BRIDGE,
NM_META_SETTING_TYPE_OVS_INTERFACE,
NM_META_SETTING_TYPE_OVS_PATCH,
NM_META_SETTING_TYPE_OVS_PORT,
NM_META_SETTING_TYPE_PPP,
NM_META_SETTING_TYPE_PPPOE,
NM_META_SETTING_TYPE_PROXY,

View file

@ -1697,6 +1697,63 @@ nmtst_assert_setting_verifies (NMSetting *setting)
g_assert (success);
}
#if defined(__NM_SIMPLE_CONNECTION_H__)
static inline void
_nmtst_assert_connection_has_settings (NMConnection *connection, gboolean has_at_least, gboolean has_at_most, ...)
{
gs_unref_hashtable GHashTable *names = NULL;
gs_free NMSetting **settings = NULL;
va_list ap;
const char *name;
guint i, len;
gs_unref_ptrarray GPtrArray *names_arr = NULL;
g_assert (NM_IS_CONNECTION (connection));
names = g_hash_table_new (g_str_hash, g_str_equal);
names_arr = g_ptr_array_new ();
va_start (ap, has_at_most);
while ((name = va_arg (ap, const char *))) {
if (!nm_g_hash_table_add (names, (gpointer) name))
g_assert_not_reached ();
g_ptr_array_add (names_arr, (gpointer) name);
}
va_end (ap);
g_ptr_array_add (names_arr, NULL);
settings = nm_connection_get_settings (connection, &len);
for (i = 0; i < len; i++) {
if ( !g_hash_table_remove (names, nm_setting_get_name (settings[i]))
&& has_at_most) {
g_error ("nmtst_assert_connection_has_settings(): has setting \"%s\" which is not expected",
nm_setting_get_name (settings[i]));
}
}
if ( g_hash_table_size (names) > 0
&& has_at_least) {
gs_free char *expected_str = g_strjoinv (" ", (char **) names_arr->pdata);
gs_free const char **settings_names = NULL;
gs_free char *has_str = NULL;
settings_names = g_new0 (const char *, len + 1);
for (i = 0; i < len; i++)
settings_names[i] = nm_setting_get_name (settings[i]);
has_str = g_strjoinv (" ", (char **) settings_names);
g_error ("nmtst_assert_connection_has_settings(): the setting lacks %u expected settings (expected: [%s] vs. has: [%s])",
g_hash_table_size (names),
expected_str,
has_str);
}
}
#define nmtst_assert_connection_has_settings(connection, ...) _nmtst_assert_connection_has_settings ((connection), TRUE, TRUE, __VA_ARGS__, NULL)
#define nmtst_assert_connection_has_settings_at_least(connection, ...) _nmtst_assert_connection_has_settings ((connection), TRUE, FALSE, __VA_ARGS__, NULL)
#define nmtst_assert_connection_has_settings_at_most(connection, ...) _nmtst_assert_connection_has_settings ((connection), FALSE, TRUE, __VA_ARGS__, NULL)
#endif /* __NM_SIMPLE_CONNECTION_H__ */
static inline void
nmtst_assert_setting_verify_fails (NMSetting *setting,
GQuark expect_error_domain,

View file

@ -175,32 +175,24 @@ nm_utils_get_ip_config_method (NMConnection *connection,
if (ip_setting_type == NM_TYPE_SETTING_IP4_CONFIG) {
g_return_val_if_fail (s_con != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
if (nm_setting_connection_get_master (s_con))
s_ip4 = nm_connection_get_setting_ip4_config (connection);
if (!s_ip4)
return NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
else {
s_ip4 = nm_connection_get_setting_ip4_config (connection);
if (!s_ip4)
return NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
method = nm_setting_ip_config_get_method (s_ip4);
g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
method = nm_setting_ip_config_get_method (s_ip4);
g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
return method;
}
return method;
} else if (ip_setting_type == NM_TYPE_SETTING_IP6_CONFIG) {
g_return_val_if_fail (s_con != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
if (nm_setting_connection_get_master (s_con))
s_ip6 = nm_connection_get_setting_ip6_config (connection);
if (!s_ip6)
return NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
else {
s_ip6 = nm_connection_get_setting_ip6_config (connection);
if (!s_ip6)
return NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
method = nm_setting_ip_config_get_method (s_ip6);
g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
method = nm_setting_ip_config_get_method (s_ip6);
g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
return method;
}
return method;
} else
g_assert_not_reached ();

View file

@ -40,13 +40,16 @@ _nm_device_log_self_to_device (t *self) \
\
if (nm_logging_enabled (_level, _domain)) { \
typeof (*self) *const _self = (self); \
const char *const _ifname = _nm_device_get_iface (_nm_device_log_self_to_device (_self)); \
NMDevice *_device = _nm_device_log_self_to_device (_self); \
const char *const _ifname = _nm_device_get_iface (_device); \
const char *const _type_description = _ifname ? nm_device_get_type_description (_device) : NULL; \
\
nm_log_obj (_level, _domain, \
_ifname, NULL, \
_self, "device", \
"%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
NM_PRINT_FMT_QUOTED (_ifname, "(", _ifname, ")", "[null]") \
"%s%s%s%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
NM_PRINT_FMT_QUOTED (_ifname, "(", _ifname, "", "[null]"), \
NM_PRINT_FMT_QUOTED (_ifname, ",", _type_description, ")", "") \
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} \
} G_STMT_END

View file

@ -117,7 +117,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
return;
}
if (renamed)
nm_manager_remove_device (nm_manager_get (), iface);
nm_manager_remove_device (nm_manager_get (), iface, NM_DEVICE_TYPE_PPP);
nm_device_activate_schedule_ip4_config_result (device, config);
return;
@ -195,7 +195,7 @@ act_stage3_ip4_config_start (NMDevice *device,
if (!nm_device_take_over_link (device, priv->pending_ifname, &renamed))
return NM_ACT_STAGE_RETURN_FAILURE;
if (renamed)
nm_manager_remove_device (nm_manager_get (), priv->pending_ifname);
nm_manager_remove_device (nm_manager_get (), priv->pending_ifname, NM_DEVICE_TYPE_PPP);
if (out_config)
*out_config = g_steal_pointer (&priv->pending_ip4_config);
else

View file

@ -646,6 +646,7 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_reason_to_string, NMDeviceStateReason,
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, "parent-managed-changed"),
NM_UTILS_LOOKUP_STR_ITEM (NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"),
);
#define reason_to_string(reason) \
@ -1661,6 +1662,10 @@ _get_route_metric_default (NMDevice *self)
return 700;
case NM_DEVICE_TYPE_BT:
return 750;
case NM_DEVICE_TYPE_OVS_BRIDGE:
case NM_DEVICE_TYPE_OVS_INTERFACE:
case NM_DEVICE_TYPE_OVS_PORT:
return 800;
case NM_DEVICE_TYPE_GENERIC:
return 950;
case NM_DEVICE_TYPE_UNKNOWN:
@ -2538,12 +2543,27 @@ static void
device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDevice *master;
nm_auto_nmpobj const NMPObject *plink_master_keep_alive = NULL;
const NMPlatformLink *plink_master;
g_return_if_fail (plink);
if (plink->master <= 0)
return;
master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
plink_master = nm_platform_link_get (nm_device_get_platform (self), plink->master);
plink_master_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink_master));
if ( master == NULL
&& plink_master
&& g_strcmp0 (plink_master->name, "ovs-system") == 0
&& plink_master->type == NM_LINK_TYPE_OPENVSWITCH) {
_LOGD (LOGD_DEVICE, "the device claimed by openvswitch");
return;
}
if (priv->master) {
if ( plink->master > 0
&& plink->master == nm_device_get_ifindex (priv->master)) {
@ -2555,20 +2575,16 @@ device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink)
nm_device_master_release_one_slave (priv->master, self, FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED);
}
if (plink->master > 0) {
NMDevice *master;
master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave)
nm_device_master_add_slave (master, self, FALSE);
else if (master) {
_LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
nm_device_get_iface (master));
} else {
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d %s",
plink->master,
nm_platform_link_get_name (nm_device_get_platform (self), plink->master));
}
if (master && NM_DEVICE_GET_CLASS (master)->enslave_slave)
nm_device_master_add_slave (master, self, FALSE);
else if (master) {
_LOGI (LOGD_DEVICE, "enslaved to non-master-type device %s; ignoring",
nm_device_get_iface (master));
} else {
_LOGW (LOGD_DEVICE, "enslaved to unknown device %d (%s%s%s)",
plink->master,
NM_PRINT_FMT_QUOTED (plink_master, "\"", plink_master->name, "\"", "??"));
}
}
@ -2650,8 +2666,7 @@ device_link_changed (NMDevice *self)
NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean ip_ifname_changed = FALSE;
const char *udi;
NMPlatformLink info;
nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL;
const NMPlatformLink *pllink;
int ifindex;
gboolean was_up;
@ -2665,37 +2680,20 @@ device_link_changed (NMDevice *self)
if (!pllink)
return G_SOURCE_REMOVE;
info = *pllink;
pllink_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (pllink));
udi = nm_platform_link_get_udi (nm_device_get_platform (self), info.ifindex);
if (udi && !nm_streq0 (udi, priv->udi)) {
/* Update UDI to what udev gives us */
g_free (priv->udi);
priv->udi = g_strdup (udi);
_notify (self, PROP_UDI);
}
if (!nm_streq0 (info.driver, priv->driver)) {
g_free (priv->driver);
priv->driver = g_strdup (info.driver);
_notify (self, PROP_DRIVER);
}
_set_mtu (self, info.mtu);
if (ifindex == nm_device_get_ip_ifindex (self))
_stats_update_counters_from_pllink (self, &info);
nm_device_update_from_platform_link (self, pllink);
had_hw_addr = (priv->hw_addr != NULL);
nm_device_update_hw_address (self);
got_hw_addr = (!had_hw_addr && priv->hw_addr);
nm_device_update_permanent_hw_address (self, FALSE);
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
if (pllink->name[0] && strcmp (priv->iface, pllink->name) != 0) {
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
priv->ifindex, priv->iface, info.name);
priv->ifindex, priv->iface, pllink->name);
g_free (priv->iface);
priv->iface = g_strdup (info.name);
priv->iface = g_strdup (pllink->name);
/* If the device has no explicit ip_iface, then changing iface changes ip_iface too. */
ip_ifname_changed = !priv->ip_iface;
@ -2718,8 +2716,8 @@ device_link_changed (NMDevice *self)
nm_device_emit_recheck_auto_activate (self);
}
if (priv->ndisc && info.inet6_token.id) {
if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token))
if (priv->ndisc && pllink->inet6_token.id) {
if (nm_ndisc_set_iid (priv->ndisc, pllink->inet6_token))
_LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface);
}
@ -2728,16 +2726,16 @@ device_link_changed (NMDevice *self)
&& !nm_device_has_capability (self, NM_DEVICE_CAP_NONSTANDARD_CARRIER))
nm_device_set_carrier (self, pllink->connected);
klass->link_changed (self, &info);
klass->link_changed (self, pllink);
/* Update DHCP, etc, if needed */
if (ip_ifname_changed)
nm_device_update_dynamic_ip_setup (self);
was_up = priv->up;
priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
priv->up = NM_FLAGS_HAS (pllink->n_ifi_flags, IFF_UP);
if ( info.initialized
if ( pllink->initialized
&& nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
NMDeviceStateReason reason;
@ -2767,7 +2765,7 @@ device_link_changed (NMDevice *self)
set_unmanaged_external_down (self, FALSE);
device_recheck_slave_status (self, &info);
device_recheck_slave_status (self, pllink);
if (priv->up && !was_up) {
/* the link was down and just came up. That happens for example, while changing MTU.
@ -3137,37 +3135,53 @@ nm_device_create_and_realize (NMDevice *self,
return TRUE;
}
static void
update_device_from_platform_link (NMDevice *self, const NMPlatformLink *plink)
void
nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
const char *udi;
const char *str;
int ifindex;
guint32 mtu;
g_return_if_fail (plink != NULL);
g_return_if_fail (plink == NULL || link_type_compatible (self, plink->type, NULL, NULL));
udi = nm_platform_link_get_udi (nm_device_get_platform (self), plink->ifindex);
if (udi && !nm_streq0 (udi, priv->udi)) {
str = plink ? nm_platform_link_get_udi (nm_device_get_platform (self), plink->ifindex) : NULL;
if (g_strcmp0 (str, priv->udi)) {
g_free (priv->udi);
priv->udi = g_strdup (udi);
priv->udi = g_strdup (str);
_notify (self, PROP_UDI);
}
if (!g_strcmp0 (plink->name, priv->iface)) {
str = plink ? plink->name : NULL;
if (str && g_strcmp0 (str, priv->iface)) {
g_free (priv->iface);
priv->iface = g_strdup (plink->name);
priv->iface = g_strdup (str);
_notify (self, PROP_IFACE);
}
if (priv->ifindex != plink->ifindex) {
priv->ifindex = plink->ifindex;
_notify (self, PROP_IFINDEX);
str = plink ? plink->driver : NULL;
if (g_strcmp0 (str, priv->driver) != 0) {
g_free (priv->driver);
priv->driver = g_strdup (str);
_notify (self, PROP_DRIVER);
}
priv->up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP);
if (plink->driver && g_strcmp0 (plink->driver, priv->driver) != 0) {
g_free (priv->driver);
priv->driver = g_strdup (plink->driver);
_notify (self, PROP_DRIVER);
if (plink) {
priv->up = NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP);
if (plink->ifindex == nm_device_get_ip_ifindex (self))
_stats_update_counters_from_pllink (self, plink);
} else {
priv->up = FALSE;
}
mtu = plink ? plink->mtu : 0;
_set_mtu (self, mtu);
ifindex = plink ? plink->ifindex : 0;
if (priv->ifindex != ifindex) {
priv->ifindex = ifindex;
_notify (self, PROP_IFINDEX);
NM_DEVICE_GET_CLASS (self)->link_changed (self, plink);
}
}
@ -3282,11 +3296,8 @@ realize_start_setup (NMDevice *self,
nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
if (plink) {
g_return_if_fail (link_type_compatible (self, plink->type, NULL, NULL));
update_device_from_platform_link (self, plink);
_stats_update_counters_from_pllink (self, plink);
}
if (plink)
nm_device_update_from_platform_link (self, plink);
if (priv->ifindex > 0) {
priv->physical_port_id = nm_platform_link_get_physical_port_id (nm_device_get_platform (self), priv->ifindex);
@ -3883,6 +3894,113 @@ nm_device_get_master (NMDevice *self)
return NULL;
}
static gboolean
get_ip_config_may_fail (NMDevice *self, int addr_family)
{
NMConnection *connection;
NMSettingIPConfig *s_ip = NULL;
connection = nm_device_get_applied_connection (self);
/* Fail the connection if the failed IP method is required to complete */
switch (addr_family) {
case AF_INET:
s_ip = nm_connection_get_setting_ip4_config (connection);
break;
case AF_INET6:
s_ip = nm_connection_get_setting_ip6_config (connection);
break;
default:
nm_assert_not_reached ();
}
return !s_ip || nm_setting_ip_config_get_may_fail (s_ip);
}
/*
* check_ip_state
*
* Transition the device from IP_CONFIG to the next state according to the
* outcome of IPv4 and IPv6 configuration. @may_fail indicates that we are
* called just after the initial configuration and thus IPv4/IPv6 are allowed to
* fail if the ipvx.may-fail properties say so, because the IP methods couldn't
* even be started.
*/
static void
check_ip_state (NMDevice *self, gboolean may_fail)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean ip4_disabled = FALSE, ip6_ignore = FALSE;
NMSettingIPConfig *s_ip4, *s_ip6;
NMDeviceState state;
if (nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
return;
/* Don't progress into IP_CHECK or SECONDARIES if we're waiting for the
* master to enslave us. */
if ( nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request))
&& !priv->is_enslaved)
return;
s_ip4 = (NMSettingIPConfig *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP4_CONFIG);
if (s_ip4 && nm_streq0 (nm_setting_ip_config_get_method (s_ip4),
NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
ip4_disabled = TRUE;
s_ip6 = (NMSettingIPConfig *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG);
if (s_ip6 && nm_streq0 (nm_setting_ip_config_get_method (s_ip6),
NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
ip6_ignore = TRUE;
if ( priv->ip4_state == IP_DONE
&& priv->ip6_state == IP_DONE) {
/* Both method completed (or disabled), proceed with activation */
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
return;
}
if ( (priv->ip4_state == IP_FAIL || (ip4_disabled && priv->ip4_state == IP_DONE))
&& (priv->ip6_state == IP_FAIL || (ip6_ignore && priv->ip6_state == IP_DONE))) {
/* Either both methods failed, or only one failed and the other is
* disabled */
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* We have assumed configuration, but couldn't redo it. No problem,
* move to check state. */
_set_ip_state (self, AF_INET, IP_DONE);
_set_ip_state (self, AF_INET6, IP_DONE);
state = NM_DEVICE_STATE_IP_CHECK;
} else if ( may_fail
&& get_ip_config_may_fail (self, AF_INET)
&& get_ip_config_may_fail (self, AF_INET6)) {
/* Couldn't start either IPv6 and IPv4 autoconfiguration,
* but both are allowed to fail. */
state = NM_DEVICE_STATE_SECONDARIES;
} else {
/* Autoconfiguration attempted without success. */
state = NM_DEVICE_STATE_FAILED;
}
nm_device_state_changed (self,
state,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
/* If a method is still pending but required, wait */
if (priv->ip4_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET))
return;
if (priv->ip6_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET6))
return;
/* If at least a method has completed, proceed with activation */
if ( (priv->ip4_state == IP_DONE && !ip4_disabled)
|| (priv->ip6_state == IP_DONE && !ip6_ignore)) {
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
return;
}
}
/**
* nm_device_slave_notify_enslave:
* @self: the slave device
@ -3919,10 +4037,8 @@ nm_device_slave_notify_enslave (NMDevice *self, gboolean success)
}
if (activating) {
_set_ip_state (self, AF_INET, IP_DONE);
_set_ip_state (self, AF_INET6, IP_DONE);
if (success)
nm_device_queue_state (self, NM_DEVICE_STATE_SECONDARIES, NM_DEVICE_STATE_REASON_NONE);
check_ip_state (self, FALSE);
else
nm_device_queue_state (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
} else
@ -4893,29 +5009,6 @@ activation_source_is_scheduled (NMDevice *self,
/*****************************************************************************/
static gboolean
get_ip_config_may_fail (NMDevice *self, int addr_family)
{
NMConnection *connection;
NMSettingIPConfig *s_ip = NULL;
connection = nm_device_get_applied_connection (self);
/* Fail the connection if the failed IP method is required to complete */
switch (addr_family) {
case AF_INET:
s_ip = nm_connection_get_setting_ip4_config (connection);
break;
case AF_INET6:
s_ip = nm_connection_get_setting_ip6_config (connection);
break;
default:
nm_assert_not_reached ();
}
return !s_ip || nm_setting_ip_config_get_may_fail (s_ip);
}
static void
master_ready (NMDevice *self,
NMActiveConnection *active)
@ -5210,84 +5303,6 @@ nm_device_activate_schedule_stage2_device_config (NMDevice *self)
activation_source_schedule (self, activate_stage2_device_config, AF_INET);
}
/*
* check_ip_state
*
* Transition the device from IP_CONFIG to the next state according to the
* outcome of IPv4 and IPv6 configuration. @may_fail indicates that we are
* called just after the initial configuration and thus IPv4/IPv6 are allowed to
* fail if the ipvx.may-fail properties say so, because the IP methods couldn't
* even be started.
*/
static void
check_ip_state (NMDevice *self, gboolean may_fail)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean ip4_disabled = FALSE, ip6_ignore = FALSE;
NMSettingIPConfig *s_ip4, *s_ip6;
NMDeviceState state;
if (nm_device_get_state (self) != NM_DEVICE_STATE_IP_CONFIG)
return;
s_ip4 = (NMSettingIPConfig *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP4_CONFIG);
if (s_ip4 && nm_streq0 (nm_setting_ip_config_get_method (s_ip4),
NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
ip4_disabled = TRUE;
s_ip6 = (NMSettingIPConfig *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_IP6_CONFIG);
if (s_ip6 && nm_streq0 (nm_setting_ip_config_get_method (s_ip6),
NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
ip6_ignore = TRUE;
if ( priv->ip4_state == IP_DONE
&& priv->ip6_state == IP_DONE) {
/* Both method completed (or disabled), proceed with activation */
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
return;
}
if ( (priv->ip4_state == IP_FAIL || (ip4_disabled && priv->ip4_state == IP_DONE))
&& (priv->ip6_state == IP_FAIL || (ip6_ignore && priv->ip6_state == IP_DONE))) {
/* Either both methods failed, or only one failed and the other is
* disabled */
if (nm_device_sys_iface_state_is_external_or_assume (self)) {
/* We have assumed configuration, but couldn't redo it. No problem,
* move to check state. */
_set_ip_state (self, AF_INET, IP_DONE);
_set_ip_state (self, AF_INET6, IP_DONE);
state = NM_DEVICE_STATE_IP_CHECK;
} else if ( may_fail
&& get_ip_config_may_fail (self, AF_INET)
&& get_ip_config_may_fail (self, AF_INET6)) {
/* Couldn't start either IPv6 and IPv4 autoconfiguration,
* but both are allowed to fail. */
state = NM_DEVICE_STATE_SECONDARIES;
} else {
/* Autoconfiguration attempted without success. */
state = NM_DEVICE_STATE_FAILED;
}
nm_device_state_changed (self,
state,
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
return;
}
/* If a method is still pending but required, wait */
if (priv->ip4_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET))
return;
if (priv->ip6_state != IP_DONE && !get_ip_config_may_fail (self, AF_INET6))
return;
/* If at least a method has completed, proceed with activation */
if ( (priv->ip4_state == IP_DONE && !ip4_disabled)
|| (priv->ip6_state == IP_DONE && !ip6_ignore)) {
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CHECK, NM_DEVICE_STATE_REASON_NONE);
return;
}
}
void
nm_device_ip_method_failed (NMDevice *self,
int addr_family,
@ -6249,9 +6264,16 @@ static gboolean
connection_requires_carrier (NMConnection *connection)
{
NMSettingIPConfig *s_ip4, *s_ip6;
NMSettingConnection *s_con;
gboolean ip4_carrier_wanted, ip6_carrier_wanted;
gboolean ip4_used = FALSE, ip6_used = FALSE;
/* We can progress to IP_CONFIG now, so that we're enslaved.
* That may actually cause carrier to go up and thus continue acivation. */
s_con = nm_connection_get_setting_connection (connection);
if (nm_setting_connection_get_master (s_con))
return FALSE;
ip4_carrier_wanted = connection_ip4_method_requires_carrier (connection, &ip4_used);
if (ip4_carrier_wanted) {
/* If IPv4 wants a carrier and cannot fail, the whole connection
@ -8009,12 +8031,6 @@ nm_device_activate_stage3_ip4_start (NMDevice *self)
g_assert (priv->ip4_state == IP_WAIT);
/* Slaves stay in IP_CONFIG state until master is ready, and then
* they go directly to SECONDARIES without configuring IPv4.
*/
if (nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request)))
return TRUE;
_set_ip_state (self, AF_INET, IP_CONF);
ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip4_config_start (self, &ip4_config, &failure_reason);
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
@ -8056,12 +8072,6 @@ nm_device_activate_stage3_ip6_start (NMDevice *self)
g_assert (priv->ip6_state == IP_WAIT);
/* Slaves stay in IP_CONFIG state until master is ready, and then
* they go directly to SECONDARIES without configuring IPv6.
*/
if (nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request)))
return TRUE;
_set_ip_state (self, AF_INET6, IP_CONF);
ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip6_config_start (self, &ip6_config, &failure_reason);
if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
@ -8100,10 +8110,6 @@ nm_device_activate_stage3_ip6_start (NMDevice *self)
static void
activate_stage3_ip_config_start (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActiveConnection *master;
NMDevice *master_device;
_set_ip_state (self, AF_INET, IP_WAIT);
_set_ip_state (self, AF_INET6, IP_WAIT);
@ -8116,26 +8122,6 @@ activate_stage3_ip_config_start (NMDevice *self)
if (!nm_platform_link_is_up (nm_device_get_platform (self), nm_device_get_ip_ifindex (self)))
_LOGW (LOGD_DEVICE, "interface %s not up for IP configuration", nm_device_get_ip_iface (self));
/* If the device is a slave, then we don't do any IP configuration but we
* use the IP config stage to indicate to the master we're ready for
* enslavement. If the master is already activating, it will have tried to
* enslave us when we changed state to IP_CONFIG, causing us to queue a
* transition to SECONDARIES (or FAILED if the enslavement failed), with
* our IP states set to IP_DONE either way. If the master isn't yet
* activating, then they'll still be in IP_WAIT. Either way, we bail out
* of IP config here.
*/
master = nm_active_connection_get_master (NM_ACTIVE_CONNECTION (priv->act_request));
if (master) {
master_device = nm_active_connection_get_device (master);
if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) {
_LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'",
nm_connection_get_id (nm_device_get_applied_connection (self)),
master_device ? nm_device_get_iface (master_device) : "(unknown)");
}
return;
}
/* IPv4 */
if ( nm_device_activate_ip4_state_in_wait (self)
&& !nm_device_activate_stage3_ip4_start (self))
@ -8901,7 +8887,7 @@ delete_on_deactivate_link_delete (gpointer user_data)
if (!nm_device_unrealize (data->device, TRUE, &error))
_LOGD (LOGD_DEVICE, "delete_on_deactivate: unrealizing %d failed (%s)", data->ifindex, error->message);
} else
} else if (data->ifindex > 0)
nm_platform_link_delete (nm_device_get_platform (self), data->ifindex);
g_free (data);
@ -8932,8 +8918,6 @@ delete_on_deactivate_check_and_schedule (NMDevice *self, int ifindex)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
DeleteOnDeactivateData *data;
if (ifindex <= 0)
return;
if (!priv->nm_owned)
return;
if (priv->queued_act_request)

View file

@ -660,6 +660,9 @@ gboolean nm_device_unrealize (NMDevice *device,
gboolean remove_resources,
GError **error);
void nm_device_update_from_platform_link (NMDevice *self,
const NMPlatformLink *plink);
gboolean nm_device_get_autoconnect (NMDevice *device);
void nm_device_set_autoconnect_intern (NMDevice *device, gboolean autoconnect);
void nm_device_emit_recheck_auto_activate (NMDevice *device);

View file

@ -0,0 +1,156 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-device-ovs-bridge.h"
#include "nm-device-ovs-port.h"
#include "nm-ovsdb.h"
#include "devices/nm-device-private.h"
#include "nm-active-connection.h"
#include "nm-setting-connection.h"
#include "nm-setting-ovs-bridge.h"
#include "introspection/org.freedesktop.NetworkManager.Device.OvsBridge.h"
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsBridge);
/*****************************************************************************/
struct _NMDeviceOvsBridge {
NMDevice parent;
};
struct _NMDeviceOvsBridgeClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsBridge, nm_device_ovs_bridge, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-bridge";
}
static gboolean
create_and_realize (NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
/* The actual backing resources will be created on enslavement by the port
* when it can identify the port and the bridge. */
return TRUE;
}
static gboolean
unrealize (NMDevice *device, GError **error)
{
return TRUE;
}
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
const char *connection_type;
if (!NM_DEVICE_CLASS (nm_device_ovs_bridge_parent_class)->check_connection_compatible (device, connection))
return FALSE;
connection_type = nm_connection_get_connection_type (connection);
if (!nm_streq0 (connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME))
return FALSE;
return TRUE;
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
NMIP4Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
static NMActStageReturn
act_stage3_ip6_config_start (NMDevice *device,
NMIP6Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
static gboolean
enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure)
{
if (!configure)
return TRUE;
if (!NM_IS_DEVICE_OVS_PORT (slave))
return FALSE;
return TRUE;
}
static void
release_slave (NMDevice *device, NMDevice *slave, gboolean configure)
{
}
/*****************************************************************************/
static void
nm_device_ovs_bridge_init (NMDeviceOvsBridge *self)
{
}
static void
nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
device_class->connection_type = NM_SETTING_OVS_BRIDGE_SETTING_NAME;
device_class->is_master = TRUE;
device_class->get_type_description = get_type_description;
device_class->create_and_realize = create_and_realize;
device_class->unrealize = unrealize;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->check_connection_compatible = check_connection_compatible;
device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
device_class->enslave_slave = enslave_slave;
device_class->release_slave = release_slave;
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_OVS_BRIDGE_SKELETON,
NULL);
}

View file

@ -0,0 +1,35 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__
#define __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__
#define NM_TYPE_DEVICE_OVS_BRIDGE (nm_device_ovs_bridge_get_type ())
#define NM_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridge))
#define NM_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass))
#define NM_IS_DEVICE_OVS_BRIDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_BRIDGE))
#define NM_IS_DEVICE_OVS_BRIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_BRIDGE))
#define NM_DEVICE_OVS_BRIDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_BRIDGE, NMDeviceOvsBridgeClass))
typedef struct _NMDeviceOvsBridge NMDeviceOvsBridge;
typedef struct _NMDeviceOvsBridgeClass NMDeviceOvsBridgeClass;
GType nm_device_ovs_bridge_get_type (void);
#endif /* __NETWORKMANAGER_DEVICE_OVS_BRIDGE_H__ */

View file

@ -0,0 +1,191 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-device-ovs-interface.h"
#include "nm-ovsdb.h"
#include "devices/nm-device-private.h"
#include "nm-active-connection.h"
#include "nm-setting-connection.h"
#include "nm-setting-ovs-interface.h"
#include "nm-setting-ovs-port.h"
#include "introspection/org.freedesktop.NetworkManager.Device.OvsInterface.h"
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsInterface);
/*****************************************************************************/
struct _NMDeviceOvsInterface {
NMDevice parent;
};
struct _NMDeviceOvsInterfaceClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsInterface, nm_device_ovs_interface, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-interface";
}
static gboolean
create_and_realize (NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
/* The actual backing resources will be created once an interface is
* added to a port of ours, since there can be neither an empty port nor
* an empty bridge. */
return TRUE;
}
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean
is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
{
return TRUE;
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMSettingConnection *s_con;
NMSettingOvsInterface *s_ovs_iface;
if (!NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->check_connection_compatible (device, connection))
return FALSE;
s_ovs_iface = nm_connection_get_setting_ovs_interface (connection);
if (!s_ovs_iface)
return FALSE;
if (!NM_IN_STRSET (nm_setting_ovs_interface_get_interface_type (s_ovs_iface),
"internal", "patch")) {
return FALSE;
}
s_con = nm_connection_get_setting_connection (connection);
if (g_strcmp0 (nm_setting_connection_get_connection_type (s_con),
NM_SETTING_OVS_INTERFACE_SETTING_NAME) != 0) {
return FALSE;
}
return TRUE;
}
static void
link_changed (NMDevice *device,
const NMPlatformLink *pllink)
{
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
nm_device_bring_up (device, TRUE, NULL);
nm_device_activate_schedule_stage3_ip_config_start (device);
}
}
static gboolean
_is_internal_interface (NMDevice *device)
{
NMConnection *connection = nm_device_get_applied_connection (device);
NMSettingOvsInterface *s_ovs_iface = nm_connection_get_setting_ovs_interface (connection);
g_return_val_if_fail (s_ovs_iface, FALSE);
return strcmp (nm_setting_ovs_interface_get_interface_type (s_ovs_iface), "internal") == 0;
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
NMIP4Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
if (!_is_internal_interface (device))
return NM_ACT_STAGE_RETURN_IP_FAIL;
if (!nm_device_get_ip_ifindex (device))
return NM_ACT_STAGE_RETURN_POSTPONE;
return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->act_stage3_ip4_config_start (device, out_config, out_failure_reason);
}
static NMActStageReturn
act_stage3_ip6_config_start (NMDevice *device,
NMIP6Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
if (!_is_internal_interface (device))
return NM_ACT_STAGE_RETURN_IP_FAIL;
if (!nm_device_get_ip_ifindex (device))
return NM_ACT_STAGE_RETURN_POSTPONE;
return NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->act_stage3_ip6_config_start (device, out_config, out_failure_reason);
}
static gboolean
can_unmanaged_external_down (NMDevice *self)
{
return FALSE;
}
/*****************************************************************************/
static void
nm_device_ovs_interface_init (NMDeviceOvsInterface *self)
{
}
static void
nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_OPENVSWITCH);
device_class->connection_type = NM_SETTING_OVS_INTERFACE_SETTING_NAME;
device_class->get_type_description = get_type_description;
device_class->create_and_realize = create_and_realize;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->is_available = is_available;
device_class->check_connection_compatible = check_connection_compatible;
device_class->link_changed = link_changed;
device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
device_class->can_unmanaged_external_down = can_unmanaged_external_down;
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_OVS_INTERFACE_SKELETON,
NULL);
}

View file

@ -0,0 +1,35 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__
#define __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__
#define NM_TYPE_DEVICE_OVS_INTERFACE (nm_device_ovs_interface_get_type ())
#define NM_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterface))
#define NM_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass))
#define NM_IS_DEVICE_OVS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_INTERFACE))
#define NM_IS_DEVICE_OVS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_INTERFACE))
#define NM_DEVICE_OVS_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_INTERFACE, NMDeviceOvsInterfaceClass))
typedef struct _NMDeviceOvsInterface NMDeviceOvsInterface;
typedef struct _NMDeviceOvsInterfaceClass NMDeviceOvsInterfaceClass;
GType nm_device_ovs_interface_get_type (void);
#endif /* __NETWORKMANAGER_DEVICE_OVS_INTERFACE_H__ */

View file

@ -0,0 +1,201 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-device-ovs-port.h"
#include "nm-ovsdb.h"
#include "devices/nm-device-private.h"
#include "nm-active-connection.h"
#include "nm-setting-connection.h"
#include "nm-setting-ovs-port.h"
#include "nm-setting-ovs-port.h"
#include "introspection/org.freedesktop.NetworkManager.Device.OvsPort.h"
#include "devices/nm-device-logging.h"
_LOG_DECLARE_SELF(NMDeviceOvsPort);
/*****************************************************************************/
struct _NMDeviceOvsPort {
NMDevice parent;
};
struct _NMDeviceOvsPortClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE (NMDeviceOvsPort, nm_device_ovs_port, NM_TYPE_DEVICE)
/*****************************************************************************/
static const char *
get_type_description (NMDevice *device)
{
return "ovs-port";
}
static gboolean
create_and_realize (NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
/* The port will be added to ovsdb when an interface is enslaved,
* because there's no such thing like an empty port. */
return TRUE;
}
static NMDeviceCapabilities
get_generic_capabilities (NMDevice *device)
{
return NM_DEVICE_CAP_IS_SOFTWARE;
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
NMSettingConnection *s_con;
const char *connection_type;
if (!NM_DEVICE_CLASS (nm_device_ovs_port_parent_class)->check_connection_compatible (device, connection))
return FALSE;
s_con = nm_connection_get_setting_connection (connection);
connection_type = nm_setting_connection_get_connection_type (s_con);
if (!connection_type)
return FALSE;
if (strcmp (connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0)
return TRUE;
return FALSE;
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
NMIP4Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
static NMActStageReturn
act_stage3_ip6_config_start (NMDevice *device,
NMIP6Config **out_config,
NMDeviceStateReason *out_failure_reason)
{
return NM_ACT_STAGE_RETURN_IP_FAIL;
}
static void
add_iface_cb (GError *error, gpointer user_data)
{
NMDevice *slave = user_data;
if (error) {
nm_log_warn (LOGD_DEVICE, "device %s could not be added to a ovs port: %s",
nm_device_get_iface (slave), error->message);
nm_device_state_changed (slave,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_OVSDB_FAILED);
}
g_object_unref (slave);
}
static gboolean
enslave_slave (NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure)
{
NMActiveConnection *ac_port = NULL;
NMActiveConnection *ac_bridge = NULL;
if (!configure)
return TRUE;
ac_port = NM_ACTIVE_CONNECTION (nm_device_get_act_request (device));
ac_bridge = nm_active_connection_get_master (ac_port);
if (!ac_bridge)
ac_bridge = ac_port;
nm_ovsdb_add_interface (nm_ovsdb_get (),
nm_active_connection_get_applied_connection (ac_bridge),
nm_device_get_applied_connection (device),
nm_device_get_applied_connection (slave),
add_iface_cb, g_object_ref (slave));
return TRUE;
}
static void
del_iface_cb (GError *error, gpointer user_data)
{
NMDevice *slave = user_data;
if (error) {
nm_log_warn (LOGD_DEVICE, "device %s could not be removed from a ovs port: %s",
nm_device_get_iface (slave), error->message);
nm_device_state_changed (slave,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_OVSDB_FAILED);
}
g_object_unref (slave);
}
static void
release_slave (NMDevice *device, NMDevice *slave, gboolean configure)
{
nm_ovsdb_del_interface (nm_ovsdb_get (), nm_device_get_iface (slave),
del_iface_cb, g_object_ref (slave));
}
/*****************************************************************************/
static void
nm_device_ovs_port_init (NMDeviceOvsPort *self)
{
}
static void
nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass)
{
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
device_class->connection_type = NM_SETTING_OVS_PORT_SETTING_NAME;
device_class->is_master = TRUE;
device_class->get_type_description = get_type_description;
device_class->create_and_realize = create_and_realize;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->check_connection_compatible = check_connection_compatible;
device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start;
device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start;
device_class->enslave_slave = enslave_slave;
device_class->release_slave = release_slave;
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_OVS_PORT_SKELETON,
NULL);
}

View file

@ -0,0 +1,35 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_OVS_PORT_H__
#define __NETWORKMANAGER_DEVICE_OVS_PORT_H__
#define NM_TYPE_DEVICE_OVS_PORT (nm_device_ovs_port_get_type ())
#define NM_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPort))
#define NM_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass))
#define NM_IS_DEVICE_OVS_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_OVS_PORT))
#define NM_IS_DEVICE_OVS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_OVS_PORT))
#define NM_DEVICE_OVS_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_OVS_PORT, NMDeviceOvsPortClass))
typedef struct _NMDeviceOvsPort NMDeviceOvsPort;
typedef struct _NMDeviceOvsPortClass NMDeviceOvsPortClass;
GType nm_device_ovs_port_get_type (void);
#endif /* __NETWORKMANAGER_DEVICE_OVS_PORT_H__ */

View file

@ -0,0 +1,195 @@
/* NetworkManager -- Network link manager
*
* 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 (C) 2017 Red Hat, Inc.
*/
#include "nm-default.h"
#include "nm-manager.h"
#include "nm-ovsdb.h"
#include "nm-device-ovs-interface.h"
#include "nm-device-ovs-port.h"
#include "nm-device-ovs-bridge.h"
#include "platform/nm-platform.h"
#include "nm-core-internal.h"
#include "devices/nm-device-factory.h"
/*****************************************************************************/
typedef struct {
NMDeviceFactory parent;
} NMOvsFactory;
typedef struct {
NMDeviceFactoryClass parent;
} NMOvsFactoryClass;
#define NM_TYPE_OVS_FACTORY (nm_ovs_factory_get_type ())
#define NM_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_OVS_FACTORY, NMOvsFactory))
#define NM_OVS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass))
#define NM_IS_OVS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_OVS_FACTORY))
#define NM_IS_OVS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_OVS_FACTORY))
#define NM_OVS_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OVS_FACTORY, NMOvsFactoryClass))
static GType nm_ovs_factory_get_type (void);
G_DEFINE_TYPE (NMOvsFactory, nm_ovs_factory, NM_TYPE_DEVICE_FACTORY)
/*****************************************************************************/
#define _NMLOG_DOMAIN LOGD_DEVICE
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "ovs", __VA_ARGS__)
/*****************************************************************************/
NM_DEVICE_FACTORY_DECLARE_TYPES (
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_OPENVSWITCH)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_OVS_BRIDGE_SETTING_NAME,
NM_SETTING_OVS_INTERFACE_SETTING_NAME,
NM_SETTING_OVS_PORT_SETTING_NAME)
)
G_MODULE_EXPORT NMDeviceFactory *
nm_device_factory_create (GError **error)
{
return (NMDeviceFactory *) g_object_new (NM_TYPE_OVS_FACTORY, NULL);
}
static NMDevice *
new_device_from_type (const char *name, NMDeviceType device_type)
{
GType type;
const char *type_desc;
NMLinkType link_type = NM_LINK_TYPE_NONE;
if (nm_manager_get_device (nm_manager_get (), name, device_type))
return NULL;
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) {
type = NM_TYPE_DEVICE_OVS_INTERFACE;
type_desc = "OpenVSwitch Interface";
link_type = NM_LINK_TYPE_OPENVSWITCH;
} else if (device_type == NM_DEVICE_TYPE_OVS_PORT) {
type = NM_TYPE_DEVICE_OVS_PORT;
type_desc = "OpenVSwitch Port";
} else if (device_type == NM_DEVICE_TYPE_OVS_BRIDGE) {
type = NM_TYPE_DEVICE_OVS_BRIDGE;
type_desc = "OpenVSwitch Bridge";
} else {
return NULL;
}
return g_object_new (type,
NM_DEVICE_IFACE, name,
NM_DEVICE_DRIVER, "openvswitch",
NM_DEVICE_DEVICE_TYPE, device_type,
NM_DEVICE_TYPE_DESC, type_desc,
NM_DEVICE_LINK_TYPE, link_type,
NULL);
}
static void
ovsdb_device_added (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type,
NMDeviceFactory *self)
{
NMDevice *device = NULL;
device = new_device_from_type (name, device_type);
if (!device)
return;
g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device);
g_object_unref (device);
}
static void
ovsdb_device_removed (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type,
NMDeviceFactory *self)
{
NMDevice *device;
NMDeviceState device_state;
device = nm_manager_get_device (nm_manager_get (), name, device_type);
if (!device)
return;
device_state = nm_device_get_state (device);
if ( device_type == NM_DEVICE_TYPE_OVS_INTERFACE
&& device_state > NM_DEVICE_STATE_DISCONNECTED
&& device_state < NM_DEVICE_STATE_DEACTIVATING) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DEACTIVATING,
NM_DEVICE_STATE_REASON_REMOVED);
} else if (device_state == NM_DEVICE_STATE_UNMANAGED) {
nm_device_unrealize (device, TRUE, NULL);
}
}
static void
start (NMDeviceFactory *self)
{
NMOvsdb *ovsdb;
ovsdb = nm_ovsdb_get ();
g_signal_connect_object (ovsdb, NM_OVSDB_DEVICE_ADDED, G_CALLBACK (ovsdb_device_added), self, (GConnectFlags) 0);
g_signal_connect_object (ovsdb, NM_OVSDB_DEVICE_REMOVED, G_CALLBACK (ovsdb_device_removed), self, (GConnectFlags) 0);
}
static NMDevice *
create_device (NMDeviceFactory *self,
const char *iface,
const NMPlatformLink *plink,
NMConnection *connection,
gboolean *out_ignore)
{
NMDeviceType device_type = NM_DEVICE_TYPE_UNKNOWN;
const char *connection_type = NULL;
if (g_strcmp0 (iface, "ovs-system") == 0) {
*out_ignore = TRUE;
return NULL;
}
if (connection)
connection_type = nm_connection_get_connection_type (connection);
if (plink)
device_type = NM_DEVICE_TYPE_OVS_INTERFACE;
else if (g_strcmp0 (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0)
device_type = NM_DEVICE_TYPE_OVS_INTERFACE;
else if (g_strcmp0 (connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0)
device_type = NM_DEVICE_TYPE_OVS_PORT;
else if (g_strcmp0 (connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME) == 0)
device_type = NM_DEVICE_TYPE_OVS_BRIDGE;
return new_device_from_type (iface, device_type);
}
static void
nm_ovs_factory_init (NMOvsFactory *self)
{
}
static void
nm_ovs_factory_class_init (NMOvsFactoryClass *klass)
{
NMDeviceFactoryClass *factory_class = NM_DEVICE_FACTORY_CLASS (klass);
factory_class->get_supported_types = get_supported_types;
factory_class->start = start;
factory_class->create_device = create_device;
}

1591
src/devices/ovs/nm-ovsdb.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,50 @@
/* NetworkManager -- Network link manager
*
* 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 2017 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_OVSDB_H__
#define __NETWORKMANAGER_OVSDB_H__
#define NM_TYPE_OVSDB (nm_ovsdb_get_type ())
#define NM_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_OVSDB, NMOvsdb))
#define NM_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_OVSDB, NMOvsdbClass))
#define NM_IS_OVSDB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_OVSDB))
#define NM_IS_OVSDB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_OVSDB))
#define NM_OVSDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OVSDB, NMOvsdbClass))
#define NM_OVSDB_DEVICE_ADDED "device-added"
#define NM_OVSDB_DEVICE_REMOVED "device-removed"
#define NM_OVSDB_DEVICE_CHANGED "device-changed"
typedef struct _NMOvsdb NMOvsdb;
typedef struct _NMOvsdbClass NMOvsdbClass;
typedef void (*NMOvsdbCallback) (GError *error, gpointer user_data);
NMOvsdb *nm_ovsdb_get (void);
GType nm_ovsdb_get_type (void);
void nm_ovsdb_add_interface (NMOvsdb *self,
NMConnection *bridge, NMConnection *port, NMConnection *interface,
NMOvsdbCallback callback, gpointer user_data);
void nm_ovsdb_del_interface (NMOvsdb *self, const char *ifname,
NMOvsdbCallback callback, gpointer user_data);
#endif /* __NETWORKMANAGER_OVSDB_H__ */

View file

@ -1270,22 +1270,38 @@ nm_manager_iface_for_uuid (NMManager *self, const char *uuid)
return nm_connection_get_interface_name (NM_CONNECTION (connection));
}
gboolean
nm_manager_remove_device (NMManager *self, const char *ifname)
NMDevice *
nm_manager_get_device (NMManager *self, const char *ifname, NMDeviceType device_type)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
GSList *iter;
NMDevice *d;
g_return_val_if_fail (ifname, NULL);
g_return_val_if_fail (device_type != NM_DEVICE_TYPE_UNKNOWN, NULL);
for (iter = priv->devices; iter; iter = iter->next) {
d = iter->data;
if (nm_streq0 (nm_device_get_iface (d), ifname)) {
remove_device (self, d, FALSE, FALSE);
return TRUE;
}
if ( nm_device_get_device_type (d) == device_type
&& nm_streq0 (nm_device_get_iface (d), ifname))
return d;
}
return FALSE;
return NULL;
}
gboolean
nm_manager_remove_device (NMManager *self, const char *ifname, NMDeviceType device_type)
{
NMDevice *d;
d = nm_manager_get_device (self, ifname, device_type);
if (!d)
return FALSE;
remove_device (self, d, FALSE, FALSE);
return TRUE;
}
/**
@ -2031,6 +2047,7 @@ device_ip_iface_changed (NMDevice *device,
NMManager *self)
{
const char *ip_iface = nm_device_get_ip_iface (device);
NMDeviceType device_type = nm_device_get_device_type (device);
GSList *iter;
/* Remove NMDevice objects that are actually child devices of others,
@ -2043,6 +2060,7 @@ device_ip_iface_changed (NMDevice *device,
if ( candidate != device
&& g_strcmp0 (nm_device_get_iface (candidate), ip_iface) == 0
&& nm_device_get_device_type (candidate) == device_type
&& nm_device_is_real (candidate)) {
remove_device (self, candidate, FALSE, FALSE);
break;
@ -2339,6 +2357,9 @@ platform_link_added (NMManager *self,
gboolean compatible = TRUE;
gs_free_error GError *error = NULL;
if (nm_device_get_link_type (candidate) != plink->type)
continue;
if (strcmp (nm_device_get_iface (candidate), plink->name))
continue;
@ -2346,6 +2367,7 @@ platform_link_added (NMManager *self,
/* Ignore the link added event since there's already a realized
* device with the link's name.
*/
nm_device_update_from_platform_link (candidate, plink);
return;
} else if (nm_device_realize_start (candidate,
plink,
@ -2476,6 +2498,8 @@ _platform_link_cb_idle (PlatformLinkCbData *data)
_LOG2W (LOGD_DEVICE, device, "failed to unrealize: %s", error->message);
g_clear_error (&error);
remove_device (self, device, FALSE, TRUE);
} else {
nm_device_update_from_platform_link (device, NULL);
}
} else {
/* Hardware and external devices always get removed when their kernel link is gone */

View file

@ -126,6 +126,11 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
void nm_manager_set_capability (NMManager *self, NMCapability cap);
gboolean nm_manager_remove_device (NMManager *self, const char *ifname);
NMDevice * nm_manager_get_device (NMManager *self,
const char *ifname,
NMDeviceType device_type);
gboolean nm_manager_remove_device (NMManager *self,
const char *ifname,
NMDeviceType device_type);
#endif /* __NETWORKMANAGER_MANAGER_H__ */