diff options
author | Thomas Haller <thaller@redhat.com> | 2020-11-27 10:12:47 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-11-27 10:12:47 +0100 |
commit | d80eee99913c4e68f9558f9ec53ff1e43b60f0c8 (patch) | |
tree | 58c45b04d3d46f1da748db2712f1814f7d720058 | |
parent | d615b902d8ded3f5de36704a3f3f00680899b40b (diff) | |
parent | cd0cf9229d49a05c4e8afbb9b87b5d621c23ea00 (diff) | |
download | NetworkManager-d80eee99913c4e68f9558f9ec53ff1e43b60f0c8.tar.gz |
veth: merge branch 'ffmancera:veth_support'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/682
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | clients/cli/connections.c | 48 | ||||
-rw-r--r-- | clients/cli/generate-docs-nm-settings-nmcli.xml.in | 5 | ||||
-rw-r--r-- | clients/common/nm-meta-setting-desc.c | 22 | ||||
-rw-r--r-- | clients/common/settings-docs.h.in | 1 | ||||
-rw-r--r-- | docs/libnm/libnm-docs.xml | 2 | ||||
-rw-r--r-- | libnm-core/meson.build | 2 | ||||
-rw-r--r-- | libnm-core/nm-connection.c | 1 | ||||
-rw-r--r-- | libnm-core/nm-core-internal.h | 1 | ||||
-rw-r--r-- | libnm-core/nm-core-types.h | 1 | ||||
-rw-r--r-- | libnm-core/nm-setting-veth.c | 194 | ||||
-rw-r--r-- | libnm-core/nm-setting-veth.h | 41 | ||||
-rw-r--r-- | libnm/NetworkManager.h | 1 | ||||
-rw-r--r-- | libnm/libnm.ver | 4 | ||||
-rw-r--r-- | libnm/meson.build | 2 | ||||
-rw-r--r-- | libnm/nm-autoptr.h | 2 | ||||
-rw-r--r-- | libnm/nm-device-ethernet.c | 59 | ||||
-rw-r--r-- | libnm/nm-device-veth.c | 129 | ||||
-rw-r--r-- | libnm/nm-device-veth.h | 41 | ||||
-rw-r--r-- | libnm/nm-libnm-utils.h | 14 | ||||
-rw-r--r-- | libnm/nm-types.h | 1 | ||||
-rw-r--r-- | man/nmcli.xml | 1 | ||||
-rw-r--r-- | po/POTFILES.in | 3 | ||||
-rw-r--r-- | shared/nm-meta-setting.c | 8 | ||||
-rw-r--r-- | shared/nm-meta-setting.h | 1 | ||||
-rw-r--r-- | src/devices/nm-device-ethernet.c | 16 | ||||
-rw-r--r-- | src/devices/nm-device-veth.c | 99 |
27 files changed, 639 insertions, 64 deletions
diff --git a/Makefile.am b/Makefile.am index 7fa353f1a4..0ea43de987 100644 --- a/Makefile.am +++ b/Makefile.am @@ -969,6 +969,7 @@ libnm_core_lib_h_pub_real = \ libnm-core/nm-setting-team.h \ libnm-core/nm-setting-tun.h \ libnm-core/nm-setting-user.h \ + libnm-core/nm-setting-veth.h \ libnm-core/nm-setting-vlan.h \ libnm-core/nm-setting-vpn.h \ libnm-core/nm-setting-vrf.h \ @@ -1044,6 +1045,7 @@ libnm_core_lib_c_settings_real = \ libnm-core/nm-setting-team.c \ libnm-core/nm-setting-tun.c \ libnm-core/nm-setting-user.c \ + libnm-core/nm-setting-veth.c \ libnm-core/nm-setting-vlan.c \ libnm-core/nm-setting-vpn.c \ libnm-core/nm-setting-vrf.c \ @@ -1363,6 +1365,7 @@ libnm_lib_h_pub_real = \ libnm/nm-device-ppp.h \ libnm/nm-device-team.h \ libnm/nm-device-tun.h \ + libnm/nm-device-veth.h \ libnm/nm-device-vlan.h \ libnm/nm-device-vrf.h \ libnm/nm-device-vxlan.h \ @@ -1427,6 +1430,7 @@ libnm_lib_c_real = \ libnm/nm-device-ppp.c \ libnm/nm-device-team.c \ libnm/nm-device-tun.c \ + libnm/nm-device-veth.c \ libnm/nm-device-vlan.c \ libnm/nm-device-vrf.c \ libnm/nm-device-vxlan.c \ diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 3fbf14d577..5b8929b997 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -858,30 +858,30 @@ const NmcMetaGenericInfo /*****************************************************************************/ -#define NMC_FIELDS_SETTINGS_NAMES_ALL \ - NM_SETTING_CONNECTION_SETTING_NAME \ - "," NM_SETTING_MATCH_SETTING_NAME "," NM_SETTING_WIRED_SETTING_NAME \ - "," NM_SETTING_802_1X_SETTING_NAME "," NM_SETTING_WIRELESS_SETTING_NAME \ - "," NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "," NM_SETTING_IP4_CONFIG_SETTING_NAME \ - "," NM_SETTING_IP6_CONFIG_SETTING_NAME "," NM_SETTING_SERIAL_SETTING_NAME \ - "," NM_SETTING_WIFI_P2P_SETTING_NAME "," NM_SETTING_PPP_SETTING_NAME \ - "," NM_SETTING_PPPOE_SETTING_NAME "," NM_SETTING_ADSL_SETTING_NAME \ - "," NM_SETTING_GSM_SETTING_NAME "," NM_SETTING_CDMA_SETTING_NAME \ - "," NM_SETTING_BLUETOOTH_SETTING_NAME "," NM_SETTING_OLPC_MESH_SETTING_NAME \ - "," NM_SETTING_VPN_SETTING_NAME "," NM_SETTING_INFINIBAND_SETTING_NAME \ - "," NM_SETTING_BOND_SETTING_NAME "," NM_SETTING_VLAN_SETTING_NAME \ - "," NM_SETTING_BRIDGE_SETTING_NAME "," 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 "," NM_SETTING_MACSEC_SETTING_NAME \ - "," NM_SETTING_MACVLAN_SETTING_NAME "," NM_SETTING_VXLAN_SETTING_NAME \ - "," NM_SETTING_VRF_SETTING_NAME "," NM_SETTING_WPAN_SETTING_NAME \ - "," NM_SETTING_6LOWPAN_SETTING_NAME "," NM_SETTING_WIREGUARD_SETTING_NAME \ - "," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \ - "," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \ - "," NM_SETTING_OVS_DPDK_SETTING_NAME \ +#define NMC_FIELDS_SETTINGS_NAMES_ALL \ + NM_SETTING_CONNECTION_SETTING_NAME \ + "," NM_SETTING_MATCH_SETTING_NAME "," NM_SETTING_WIRED_SETTING_NAME \ + "," NM_SETTING_VETH_SETTING_NAME "," NM_SETTING_802_1X_SETTING_NAME \ + "," NM_SETTING_WIRELESS_SETTING_NAME "," NM_SETTING_WIRELESS_SECURITY_SETTING_NAME \ + "," NM_SETTING_IP4_CONFIG_SETTING_NAME "," NM_SETTING_IP6_CONFIG_SETTING_NAME \ + "," NM_SETTING_SERIAL_SETTING_NAME "," NM_SETTING_WIFI_P2P_SETTING_NAME \ + "," NM_SETTING_PPP_SETTING_NAME "," NM_SETTING_PPPOE_SETTING_NAME \ + "," NM_SETTING_ADSL_SETTING_NAME "," NM_SETTING_GSM_SETTING_NAME \ + "," NM_SETTING_CDMA_SETTING_NAME "," NM_SETTING_BLUETOOTH_SETTING_NAME \ + "," NM_SETTING_OLPC_MESH_SETTING_NAME "," NM_SETTING_VPN_SETTING_NAME \ + "," NM_SETTING_INFINIBAND_SETTING_NAME "," NM_SETTING_BOND_SETTING_NAME \ + "," NM_SETTING_VLAN_SETTING_NAME "," NM_SETTING_BRIDGE_SETTING_NAME \ + "," 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 \ + "," NM_SETTING_MACSEC_SETTING_NAME "," NM_SETTING_MACVLAN_SETTING_NAME \ + "," NM_SETTING_VXLAN_SETTING_NAME "," NM_SETTING_VRF_SETTING_NAME \ + "," NM_SETTING_WPAN_SETTING_NAME "," NM_SETTING_6LOWPAN_SETTING_NAME \ + "," NM_SETTING_WIREGUARD_SETTING_NAME "," NM_SETTING_PROXY_SETTING_NAME \ + "," NM_SETTING_TC_CONFIG_SETTING_NAME "," NM_SETTING_SRIOV_SETTING_NAME \ + "," NM_SETTING_ETHTOOL_SETTING_NAME "," NM_SETTING_OVS_DPDK_SETTING_NAME \ "," NM_SETTING_HOSTNAME_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */ const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = { diff --git a/clients/cli/generate-docs-nm-settings-nmcli.xml.in b/clients/cli/generate-docs-nm-settings-nmcli.xml.in index 997d3c19ce..1d1a09ba4a 100644 --- a/clients/cli/generate-docs-nm-settings-nmcli.xml.in +++ b/clients/cli/generate-docs-nm-settings-nmcli.xml.in @@ -986,6 +986,11 @@ </setting> <setting name="user" > </setting> + <setting name="veth" > + <property name="peer" + alias="peer" + description="This property specifies the peer interface name of the veth. This property is mandatory." /> + </setting> <setting name="vlan" > <property name="parent" alias="dev" diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index c18035de83..e4b74751cb 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -7085,6 +7085,19 @@ static const NMMetaPropertyInfo *const property_infos_TUN[] = { }; #undef _CURRENT_NM_META_SETTING_TYPE +#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VETH +static const NMMetaPropertyInfo *const property_infos_VETH[] = { + PROPERTY_INFO_WITH_DESC (NM_SETTING_VETH_PEER, + .is_cli_option = TRUE, + .property_alias = "peer", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("veth peer"), + .property_type = &_pt_gobject_string, + ), + NULL +}; + +#undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VLAN static const NMMetaPropertyInfo *const property_infos_VLAN[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_VLAN_PARENT, @@ -7984,6 +7997,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #define SETTING_PRETTY_NAME_TEAM_PORT N_("Team port") #define SETTING_PRETTY_NAME_TUN N_("Tun device") #define SETTING_PRETTY_NAME_USER N_("User settings") +#define SETTING_PRETTY_NAME_VETH N_("Veth connection") #define SETTING_PRETTY_NAME_VLAN N_("VLAN connection") #define SETTING_PRETTY_NAME_VPN N_("VPN connection") #define SETTING_PRETTY_NAME_VRF N_("VRF connection") @@ -8224,6 +8238,14 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { .setting_init_fcn = _setting_init_fcn_tun, ), SETTING_INFO_EMPTY (USER), + SETTING_INFO (VETH, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (VETH, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), + ), + ), SETTING_INFO (VLAN, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in index 14d83ff4cd..9e42d99d6e 100644 --- a/clients/common/settings-docs.h.in +++ b/clients/common/settings-docs.h.in @@ -374,6 +374,7 @@ #define DESCRIBE_DOC_NM_SETTING_TUN_PI N_("If TRUE the interface will prepend a 4 byte header describing the physical interface to the packets.") #define DESCRIBE_DOC_NM_SETTING_TUN_VNET_HDR N_("If TRUE the IFF_VNET_HDR the tunnel packets will include a virtio network header.") #define DESCRIBE_DOC_NM_SETTING_USER_DATA N_("A dictionary of key/value pairs with user data. This data is ignored by NetworkManager and can be used at the users discretion. The keys only support a strict ascii format, but the values can be arbitrary UTF8 strings up to a certain length.") +#define DESCRIBE_DOC_NM_SETTING_VETH_PEER N_("This property specifies the peer interface name of the veth. This property is mandatory.") #define DESCRIBE_DOC_NM_SETTING_VLAN_EGRESS_PRIORITY_MAP N_("For outgoing packets, a list of mappings from Linux SKB priorities to 802.1p priorities. The mapping is given in the format \"from:to\" where both \"from\" and \"to\" are unsigned integers, ie \"7:3\".") #define DESCRIBE_DOC_NM_SETTING_VLAN_FLAGS N_("One or more flags which control the behavior and features of the VLAN interface. Flags include NM_VLAN_FLAG_REORDER_HEADERS (0x1) (reordering of output packet headers), NM_VLAN_FLAG_GVRP (0x2) (use of the GVRP protocol), and NM_VLAN_FLAG_LOOSE_BINDING (0x4) (loose binding of the interface to its master device's operating state). NM_VLAN_FLAG_MVRP (0x8) (use of the MVRP protocol). The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, but it used to be 0. To preserve backward compatibility, the default-value in the D-Bus API continues to be 0 and a missing property on D-Bus is still considered as 0.") #define DESCRIBE_DOC_NM_SETTING_VLAN_ID N_("The VLAN identifier that the interface created by this connection should be assigned. The valid range is from 0 to 4094, without the reserved id 4095.") diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml index 0a70694d3f..3ff07c37bf 100644 --- a/docs/libnm/libnm-docs.xml +++ b/docs/libnm/libnm-docs.xml @@ -350,6 +350,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in <xi:include href="xml/nm-setting-team.xml"/> <xi:include href="xml/nm-setting-tun.xml"/> <xi:include href="xml/nm-setting-user.xml"/> + <xi:include href="xml/nm-setting-veth.xml"/> <xi:include href="xml/nm-setting-vlan.xml"/> <xi:include href="xml/nm-setting-vpn.xml"/> <xi:include href="xml/nm-setting-vrf.xml"/> @@ -388,6 +389,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in <xi:include href="xml/nm-device-ppp.xml"/> <xi:include href="xml/nm-device-team.xml"/> <xi:include href="xml/nm-device-tun.xml"/> + <xi:include href="xml/nm-device-veth.xml"/> <xi:include href="xml/nm-device-vlan.xml"/> <xi:include href="xml/nm-device-vrf.xml"/> <xi:include href="xml/nm-device-vxlan.xml"/> diff --git a/libnm-core/meson.build b/libnm-core/meson.build index 15d8931c0f..e3a5dc8445 100644 --- a/libnm-core/meson.build +++ b/libnm-core/meson.build @@ -59,6 +59,7 @@ libnm_core_headers = files( 'nm-setting-team.h', 'nm-setting-tun.h', 'nm-setting-user.h', + 'nm-setting-veth.h', 'nm-setting-vlan.h', 'nm-setting-vpn.h', 'nm-setting-vrf.h', @@ -161,6 +162,7 @@ libnm_core_settings_sources = files( 'nm-setting-team.c', 'nm-setting-tun.c', 'nm-setting-user.c', + 'nm-setting-veth.c', 'nm-setting-vlan.c', 'nm-setting-vpn.c', 'nm-setting-vrf.c', diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 84a0b34835..651d919395 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -2642,6 +2642,7 @@ nm_connection_is_virtual(NMConnection *connection) NM_SETTING_OVS_PORT_SETTING_NAME, NM_SETTING_TEAM_SETTING_NAME, NM_SETTING_TUN_SETTING_NAME, + NM_SETTING_VETH_SETTING_NAME, NM_SETTING_VLAN_SETTING_NAME, NM_SETTING_VRF_SETTING_NAME, NM_SETTING_VXLAN_SETTING_NAME, diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index c3beb71ea3..b522487d12 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -60,6 +60,7 @@ #include "nm-setting-team-port.h" #include "nm-setting-team.h" #include "nm-setting-tun.h" +#include "nm-setting-veth.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" #include "nm-setting-vrf.h" diff --git a/libnm-core/nm-core-types.h b/libnm-core/nm-core-types.h index cb940a1ee9..9668ec8ff2 100644 --- a/libnm-core/nm-core-types.h +++ b/libnm-core/nm-core-types.h @@ -54,6 +54,7 @@ typedef struct _NMSettingTeam NMSettingTeam; typedef struct _NMSettingTeamPort NMSettingTeamPort; typedef struct _NMSettingTun NMSettingTun; typedef struct _NMSettingUser NMSettingUser; +typedef struct _NMSettingVeth NMSettingVeth; typedef struct _NMSettingVlan NMSettingVlan; typedef struct _NMSettingVpn NMSettingVpn; typedef struct _NMSettingVrf NMSettingVrf; diff --git a/libnm-core/nm-setting-veth.c b/libnm-core/nm-setting-veth.c new file mode 100644 index 0000000000..bde87dc831 --- /dev/null +++ b/libnm-core/nm-setting-veth.c @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-setting-veth.h" + +#include <stdlib.h> + +#include "nm-utils.h" +#include "nm-setting-connection.h" +#include "nm-setting-private.h" +#include "nm-connection-private.h" + +/** + * SECTION:nm-setting-veth + * @short_description: Describes connection properties for veth interfaces + * + * The #NMSettingVeth object is a #NMSetting subclass that describes properties + * necessary for connection to veth interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, ); + +typedef struct { + char *peer; +} NMSettingVethPrivate; + +/** + * NMSettingVeth: + * + * Veth Settings + */ +struct _NMSettingVeth { + NMSetting parent; + NMSettingVethPrivate _priv; +}; + +struct _NMSettingVethClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingVeth, nm_setting_veth, NM_TYPE_SETTING) + +#define NM_SETTING_VETH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMSettingVeth, NM_IS_SETTING_VETH, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_veth_get_peer: + * @setting: the #NMSettingVeth + * + * Returns: the #NMSettingVeth:peer property of the setting + * + * Since: 1.30 + **/ +const char * +nm_setting_veth_get_peer(NMSettingVeth *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_VETH(setting), NULL); + return NM_SETTING_VETH_GET_PRIVATE(setting)->peer; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + if (!priv->peer) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified")); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VETH_SETTING_NAME, NM_SETTING_VETH_PEER); + return FALSE; + } + + if (!nm_utils_ifname_valid(priv->peer, NMU_IFACE_KERNEL, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not a valid interface name"), + priv->peer); + g_prefix_error(error, "%s.%s: ", NM_SETTING_VETH_SETTING_NAME, NM_SETTING_VETH_PEER); + return FALSE; + } + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PEER: + g_value_set_string(value, priv->peer); + break; + } +} + +static void +set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + switch (prop_id) { + case PROP_PEER: + g_free(priv->peer); + priv->peer = g_value_dup_string(value); + break; + } +} + +/*****************************************************************************/ + +static void +nm_setting_veth_init(NMSettingVeth *setting) +{} + +/** + * nm_setting_veth_new: + * + * Creates a new #NMSettingVeth object with default values. + * + * Returns: (transfer full): the new empty #NMSettingVeth object + * + * Since: 1.30 + **/ +NMSetting * +nm_setting_veth_new(void) +{ + return g_object_new(NM_TYPE_SETTING_VETH, NULL); +} + +static void +finalize(GObject *object) +{ + NMSettingVeth * setting = NM_SETTING_VETH(object); + NMSettingVethPrivate *priv = NM_SETTING_VETH_GET_PRIVATE(setting); + + g_free(priv->peer); + + G_OBJECT_CLASS(nm_setting_veth_parent_class)->finalize(object); +} + +static void +nm_setting_veth_class_init(NMSettingVethClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMSettingVethPrivate)); + + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + + setting_class->verify = verify; + + /** + * NMSettingVeth:peer: + * + * This property specifies the peer interface name of the veth. This + * property is mandatory. + * + * Since: 1.30 + **/ + obj_properties[PROP_PEER] = g_param_spec_string(NM_SETTING_VETH_PEER, + "", + "", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE + | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_VETH); +} diff --git a/libnm-core/nm-setting-veth.h b/libnm-core/nm-setting-veth.h new file mode 100644 index 0000000000..27f80910e4 --- /dev/null +++ b/libnm-core/nm-setting-veth.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_VETH_H__ +#define __NM_SETTING_VETH_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_VETH (nm_setting_veth_get_type()) +#define NM_SETTING_VETH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_VETH, NMSettingVeth)) +#define NM_IS_SETTING_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_VETH)) +#define NM_IS_SETTING_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_VETH)) +#define NM_SETTING_VETH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_VETH, NMSettingVethClass)) + +#define NM_SETTING_VETH_SETTING_NAME "veth" + +#define NM_SETTING_VETH_PEER "peer" + +typedef struct _NMSettingVethClass NMSettingVethClass; + +NM_AVAILABLE_IN_1_30 +GType nm_setting_veth_get_type(void); +NM_AVAILABLE_IN_1_30 +NMSetting *nm_setting_veth_new(void); + +NM_AVAILABLE_IN_1_30 +const char *nm_setting_veth_get_peer(NMSettingVeth *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_VETH_H__ */ diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 6864f7e84c..c94f093e66 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -88,6 +88,7 @@ #include "nm-setting-team-port.h" #include "nm-setting-tun.h" #include "nm-setting-user.h" +#include "nm-setting-veth.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" #include "nm-setting-vrf.h" diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 100b9b93ee..c61792c749 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1758,6 +1758,7 @@ global: libnm_1_30_0 { global: + nm_device_veth_get_type; nm_keyfile_handler_data_fail_with_error; nm_keyfile_handler_data_get_context; nm_keyfile_handler_data_warn_get; @@ -1778,5 +1779,8 @@ global: nm_setting_ovs_external_ids_get_type; nm_setting_ovs_external_ids_new; nm_setting_ovs_external_ids_set_data; + nm_setting_veth_get_peer; + nm_setting_veth_get_type; + nm_setting_veth_new; nm_utils_print; } libnm_1_28_0; diff --git a/libnm/meson.build b/libnm/meson.build index 5808837459..abdcc1d325 100644 --- a/libnm/meson.build +++ b/libnm/meson.build @@ -40,6 +40,7 @@ libnm_headers = files( 'nm-device-ppp.h', 'nm-device-team.h', 'nm-device-tun.h', + 'nm-device-veth.h', 'nm-device-vlan.h', 'nm-device-vrf.h', 'nm-device-vxlan.h', @@ -106,6 +107,7 @@ libnm_sources = files( 'nm-device-ppp.c', 'nm-device-team.c', 'nm-device-tun.c', + 'nm-device-veth.c', 'nm-device-vlan.c', 'nm-device-vrf.c', 'nm-device-vxlan.c', diff --git a/libnm/nm-autoptr.h b/libnm/nm-autoptr.h index 93be5464b9..ca70a6ca49 100644 --- a/libnm/nm-autoptr.h +++ b/libnm/nm-autoptr.h @@ -53,6 +53,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceOvsPort, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDevicePpp, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceTeam, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceTun, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVeth, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVlan, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceVxlan, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceWifi, g_object_unref) @@ -98,6 +99,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTeam, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTeamPort, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingTun, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingUser, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVeth, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVlan, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVpn, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingVxlan, g_object_unref) diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c index 9177c3f7fe..bf4a36fee0 100644 --- a/libnm/nm-device-ethernet.c +++ b/libnm/nm-device-ethernet.c @@ -8,11 +8,14 @@ #include "nm-device-ethernet.h" +#include "nm-libnm-utils.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-pppoe.h" +#include "nm-setting-veth.h" #include "nm-utils.h" #include "nm-object-private.h" +#include "nm-device-veth.h" /*****************************************************************************/ @@ -21,26 +24,17 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PERM_HW_ADDRESS, PROP_CARRIER, PROP_S390_SUBCHANNELS, ); -typedef struct { +typedef struct _NMDeviceEthernetPrivate { char ** s390_subchannels; char * perm_hw_address; guint32 speed; bool carrier; } NMDeviceEthernetPrivate; -struct _NMDeviceEthernet { - NMDevice parent; - NMDeviceEthernetPrivate _priv; -}; - -struct _NMDeviceEthernetClass { - NMDeviceClass parent; -}; - G_DEFINE_TYPE(NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) #define NM_DEVICE_ETHERNET_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMObject, NMDevice) + _NM_GET_PRIVATE_PTR(self, NMDeviceEthernet, NM_IS_DEVICE_ETHERNET, NMObject) /*****************************************************************************/ @@ -181,9 +175,12 @@ connection_compatible(NMDevice *device, NMConnection *connection, GError **error ->connection_compatible(device, connection, error)) return FALSE; - if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)) { + if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME) + || nm_connection_is_type(connection, NM_SETTING_WIRED_SETTING_NAME) + || (nm_connection_is_type(connection, NM_SETTING_VETH_SETTING_NAME) + && NM_IS_DEVICE_VETH(device))) { /* NOP */ - } else if (!nm_connection_is_type(connection, NM_SETTING_WIRED_SETTING_NAME)) { + } else { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, @@ -271,7 +268,13 @@ get_setting_type(NMDevice *device) static void nm_device_ethernet_init(NMDeviceEthernet *device) -{} +{ + NMDeviceEthernetPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE(device, NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetPrivate); + + device->_priv = priv; +} static void finalize(GObject *object) @@ -309,38 +312,34 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) } } -/* TODO: implemented Veth. */ -const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth = NML_DBUS_META_IFACE_INIT( - NM_DBUS_INTERFACE_DEVICE_VETH, - NULL, - NML_DBUS_META_INTERFACE_PRIO_NONE, - NML_DBUS_META_IFACE_DBUS_PROPERTIES(NML_DBUS_META_PROPERTY_INIT_TODO("Peer", "o"), ), ); - const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired = NML_DBUS_META_IFACE_INIT_PROP( NM_DBUS_INTERFACE_DEVICE_WIRED, nm_device_ethernet_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, NML_DBUS_META_IFACE_DBUS_PROPERTIES( - NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceEthernet, _priv.carrier), + NML_DBUS_META_PROPERTY_INIT_B("Carrier", PROP_CARRIER, NMDeviceEthernetPrivate, carrier), NML_DBUS_META_PROPERTY_INIT_FCN("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address), NML_DBUS_META_PROPERTY_INIT_S("PermHwAddress", PROP_PERM_HW_ADDRESS, - NMDeviceEthernet, - _priv.perm_hw_address), + NMDeviceEthernetPrivate, + perm_hw_address), NML_DBUS_META_PROPERTY_INIT_AS("S390Subchannels", PROP_S390_SUBCHANNELS, - NMDeviceEthernet, - _priv.s390_subchannels), - NML_DBUS_META_PROPERTY_INIT_U("Speed", PROP_SPEED, NMDeviceEthernet, _priv.speed), ), ); + NMDeviceEthernetPrivate, + s390_subchannels), + NML_DBUS_META_PROPERTY_INIT_U("Speed", PROP_SPEED, NMDeviceEthernetPrivate, speed), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDeviceEthernet, _priv), ); static void -nm_device_ethernet_class_init(NMDeviceEthernetClass *eth_class) +nm_device_ethernet_class_init(NMDeviceEthernetClass *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(eth_class); - NMDeviceClass *device_class = NM_DEVICE_CLASS(eth_class); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + g_type_class_add_private(klass, sizeof(NMDeviceEthernetPrivate)); object_class->get_property = get_property; object_class->finalize = finalize; diff --git a/libnm/nm-device-veth.c b/libnm/nm-device-veth.c new file mode 100644 index 0000000000..ba51ae6455 --- /dev/null +++ b/libnm/nm-device-veth.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-device-veth.h" + +#include "nm-setting-connection.h" +#include "nm-setting-veth.h" +#include "nm-setting-wired.h" +#include "nm-utils.h" +#include "nm-device-ethernet.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PEER, ); + +typedef struct { + char *peer; +} NMDeviceVethPrivate; + +struct _NMDeviceVeth { + NMDeviceEthernet parent; + NMDeviceVethPrivate _priv; +}; + +struct _NMDeviceVethClass { + NMDeviceEthernetClass parent; +}; + +G_DEFINE_TYPE(NMDeviceVeth, nm_device_veth, NM_TYPE_DEVICE_ETHERNET) + +#define NM_DEVICE_VETH_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceVeth, NM_IS_DEVICE_VETH, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_veth_get_peer: + * @device: a #NMDeviceVeth + * + * Returns: the device's peer name + * + * Since: 1.30 + **/ +const char * +nm_device_veth_get_peer(NMDeviceVeth *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_VETH(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_VETH_GET_PRIVATE(device)->peer); +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_VETH; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceVeth *device = NM_DEVICE_VETH(object); + + switch (prop_id) { + case PROP_PEER: + g_value_set_string(value, nm_device_veth_get_peer(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_veth_init(NMDeviceVeth *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceVethPrivate *priv = NM_DEVICE_VETH_GET_PRIVATE(object); + + g_free(priv->peer); + + G_OBJECT_CLASS(nm_device_veth_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_VETH, + nm_device_veth_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_20, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("peer", PROP_PEER, NMDeviceVeth, _priv.peer), ), ); + +static void +nm_device_veth_class_init(NMDeviceVethClass *klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceVeth); + + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVeth:peer: + * + * The device's peer name. + * + * Since: 1.30 + **/ + obj_properties[PROP_PEER] = g_param_spec_string(NM_DEVICE_VETH_PEER, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_veth); +} diff --git a/libnm/nm-device-veth.h b/libnm/nm-device-veth.h new file mode 100644 index 0000000000..eb03d28055 --- /dev/null +++ b/libnm/nm-device-veth.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* + * Copyright (C) 2020 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_VETH_H__ +#define __NM_DEVICE_VETH_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_VETH (nm_device_veth_get_type()) +#define NM_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_VETH, NMDeviceVeth)) +#define NM_DEVICE_VETH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) +#define NM_IS_DEVICE_VETH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_VETH)) +#define NM_IS_DEVICE_VETH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_VETH)) +#define NM_DEVICE_VETH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_VETH, NMDeviceVethClass)) + +#define NM_DEVICE_VETH_PEER "peer" + +/** + * NMDeviceVeth: + */ +typedef struct _NMDeviceVethClass NMDeviceVethClass; + +NM_AVAILABLE_IN_1_30 +GType nm_device_veth_get_type(void); + +NM_AVAILABLE_IN_1_30 +const char *nm_device_veth_get_peer(NMDeviceVeth *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VETH_H__ */ diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h index def9e6ddab..86e7b304b1 100644 --- a/libnm/nm-libnm-utils.h +++ b/libnm/nm-libnm-utils.h @@ -7,6 +7,7 @@ #define __NM_LIBNM_UTILS_H__ #include "c-list/src/c-list.h" +#include "nm-device.h" #include "nm-glib-aux/nm-ref-string.h" #include "nm-glib-aux/nm-logging-fwd.h" #include "nm-types.h" @@ -817,6 +818,19 @@ struct _NMDeviceClass { /*****************************************************************************/ +struct _NMDeviceEthernetPrivate; + +struct _NMDeviceEthernet { + NMDevice parent; + struct _NMDeviceEthernetPrivate *_priv; +}; + +struct _NMDeviceEthernetClass { + NMDeviceClass parent; +}; + +/*****************************************************************************/ + struct _NMActiveConnectionPrivate; struct _NMActiveConnection { diff --git a/libnm/nm-types.h b/libnm/nm-types.h index 765d7cdae6..3445418cde 100644 --- a/libnm/nm-types.h +++ b/libnm/nm-types.h @@ -36,6 +36,7 @@ typedef struct _NMDeviceOvsPort NMDeviceOvsPort; typedef struct _NMDevicePpp NMDevicePpp; typedef struct _NMDeviceTeam NMDeviceTeam; typedef struct _NMDeviceTun NMDeviceTun; +typedef struct _NMDeviceVeth NMDeviceVeth; typedef struct _NMDeviceVlan NMDeviceVlan; typedef struct _NMDeviceVrf NMDeviceVrf; typedef struct _NMDeviceVxlan NMDeviceVxlan; diff --git a/man/nmcli.xml b/man/nmcli.xml index 88d09e777a..b0665efd69 100644 --- a/man/nmcli.xml +++ b/man/nmcli.xml @@ -1002,6 +1002,7 @@ <listitem><para><literal>team</literal></para></listitem> <listitem><para><literal>team-slave</literal> (deprecated for ethernet with master)</para></listitem> <listitem><para><literal>tun</literal></para></listitem> + <listitem><para><literal>veth</literal></para></listitem> <listitem><para><literal>vlan</literal></para></listitem> <listitem><para><literal>vpn</literal></para></listitem> <listitem><para><literal>vrf</literal></para></listitem> diff --git a/po/POTFILES.in b/po/POTFILES.in index f2718ac648..cee590c0cf 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -95,6 +95,7 @@ libnm-core/nm-setting-team-port.c libnm-core/nm-setting-team.c libnm-core/nm-setting-tun.c libnm-core/nm-setting-user.c +libnm-core/nm-setting-veth.c libnm-core/nm-setting-vlan.c libnm-core/nm-setting-vrf.c libnm-core/nm-setting-vpn.c @@ -130,6 +131,7 @@ libnm/nm-device-ovs-interface.c libnm/nm-device-ovs-port.c libnm/nm-device-team.c libnm/nm-device-tun.c +libnm/nm-device-veth.c libnm/nm-device-vlan.c libnm/nm-device-vrf.c libnm/nm-device-vxlan.c @@ -165,6 +167,7 @@ src/devices/nm-device-infiniband.c src/devices/nm-device-ip-tunnel.c src/devices/nm-device-macvlan.c src/devices/nm-device-tun.c +src/devices/nm-device-veth.c src/devices/nm-device-vlan.c src/devices/nm-device-vrf.c src/devices/nm-device-vxlan.c diff --git a/shared/nm-meta-setting.c b/shared/nm-meta-setting.c index aa779bfaef..8d29dde28a 100644 --- a/shared/nm-meta-setting.c +++ b/shared/nm-meta-setting.c @@ -46,6 +46,7 @@ #include "nm-setting-team.h" #include "nm-setting-tun.h" #include "nm-setting-user.h" +#include "nm-setting-veth.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" #include "nm-setting-vrf.h" @@ -419,6 +420,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_USER_SETTING_NAME, .get_setting_gtype = nm_setting_user_get_type, }, + [NM_META_SETTING_TYPE_VETH] = + { + .meta_type = NM_META_SETTING_TYPE_VETH, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_VETH_SETTING_NAME, + .get_setting_gtype = nm_setting_veth_get_type, + }, [NM_META_SETTING_TYPE_VLAN] = { .meta_type = NM_META_SETTING_TYPE_VLAN, diff --git a/shared/nm-meta-setting.h b/shared/nm-meta-setting.h index 72c5cfd8a0..82b387d674 100644 --- a/shared/nm-meta-setting.h +++ b/shared/nm-meta-setting.h @@ -143,6 +143,7 @@ typedef enum { NM_META_SETTING_TYPE_TEAM_PORT, NM_META_SETTING_TYPE_TUN, NM_META_SETTING_TYPE_USER, + NM_META_SETTING_TYPE_VETH, NM_META_SETTING_TYPE_VLAN, NM_META_SETTING_TYPE_VPN, NM_META_SETTING_TYPE_VRF, diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 8428a4ce52..9f149c73db 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -34,6 +34,7 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-udev-aux/nm-udev-utils.h" +#include "nm-device-veth.h" #define _NMLOG_DEVICE_TYPE NMDeviceEthernet #include "nm-device-logging.h" @@ -347,7 +348,9 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * ->check_connection_compatible(device, connection, error)) return FALSE; - if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)) { + if (nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME) + || (nm_connection_is_type(connection, NM_SETTING_VETH_SETTING_NAME) + && NM_IS_DEVICE_VETH(device))) { s_wired = nm_connection_get_setting_wired(connection); } else { s_wired = @@ -1360,6 +1363,9 @@ wake_on_lan_enable(NMDevice *device) s_wired = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRED); + if (NM_IS_DEVICE_VETH(device)) + return FALSE; + if (s_wired) { wol = nm_setting_wired_get_wake_on_lan(s_wired); password = nm_setting_wired_get_wake_on_lan_password(s_wired); @@ -1493,6 +1499,12 @@ act_stage3_ip_config_start(NMDevice * device, { NMSettingConnection *s_con; const char * connection_type; + int ifindex; + + ifindex = nm_device_get_ifindex(device); + + if (ifindex <= 0) + return NM_ACT_STAGE_RETURN_FAILURE; if (addr_family == AF_INET) { s_con = nm_device_get_applied_setting(device, NM_TYPE_SETTING_CONNECTION); @@ -1803,7 +1815,7 @@ static void link_changed(NMDevice *device, const NMPlatformLink *pllink) { NM_DEVICE_CLASS(nm_device_ethernet_parent_class)->link_changed(device, pllink); - if (pllink->initialized) + if (!NM_IS_DEVICE_VETH(device) && pllink->initialized) _update_s390_subchannels((NMDeviceEthernet *) device); } diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 49947412f0..54400c3c49 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -7,11 +7,13 @@ #include <stdlib.h> +#include "nm-core-internal.h" #include "nm-device-veth.h" #include "nm-device-private.h" #include "nm-manager.h" #include "platform/nm-platform.h" #include "nm-device-factory.h" +#include "nm-setting-veth.h" #define _NMLOG_DEVICE_TYPE NMDeviceVeth #include "nm-device-logging.h" @@ -42,9 +44,10 @@ update_properties(NMDevice *device) ifindex = nm_device_get_ifindex(device); - if (!nm_platform_link_veth_get_properties(nm_device_get_platform(device), - ifindex, - &peer_ifindex)) + if (ifindex <= 0 + || !nm_platform_link_veth_get_properties(nm_device_get_platform(device), + ifindex, + &peer_ifindex)) peer_ifindex = 0; nm_device_parent_set_ifindex(device, peer_ifindex); @@ -71,6 +74,81 @@ link_changed(NMDevice *device, const NMPlatformLink *pllink) update_properties(device); } +static gboolean +create_and_realize(NMDevice * device, + NMConnection * connection, + NMDevice * parent, + const NMPlatformLink **out_plink, + GError ** error) +{ + const char * iface = nm_device_get_iface(device); + NMSettingVeth *s_veth; + int r; + + s_veth = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VETH); + if (!s_veth) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Profile %s (%s) is not a suitable veth profile", + nm_connection_get_id(connection), + nm_connection_get_uuid(connection)); + return FALSE; + } + + r = nm_platform_link_veth_add(nm_device_get_platform(device), + iface, + nm_setting_veth_get_peer(s_veth), + out_plink); + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create veth interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ + +static NMDeviceCapabilities +get_generic_capabilities(NMDevice *device) +{ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; +} + +static gboolean +complete_connection(NMDevice * device, + NMConnection * connection, + const char * specific_object, + NMConnection *const *existing_connections, + GError ** error) +{ + NMSettingVeth *s_veth; + + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_VETH_SETTING_NAME, + existing_connections, + NULL, + _("Veth connection"), + "veth", + NULL, + TRUE); + + s_veth = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VETH); + if (!s_veth) { + s_veth = (NMSettingVeth *) nm_setting_veth_new(); + nm_connection_add_setting(connection, NM_SETTING(s_veth)); + } + + return TRUE; +} + /*****************************************************************************/ static void @@ -136,6 +214,9 @@ nm_device_veth_class_init(NMDeviceVethClass *klass) device_class->can_unmanaged_external_down = can_unmanaged_external_down; device_class->link_changed = link_changed; device_class->parent_changed_notify = parent_changed_notify; + device_class->create_and_realize = create_and_realize; + device_class->complete_connection = complete_connection; + device_class->get_generic_capabilities = get_generic_capabilities; obj_properties[PROP_PEER] = g_param_spec_string(NM_DEVICE_VETH_PEER, "", @@ -171,8 +252,10 @@ create_device(NMDeviceFactory * factory, NULL); } -NM_DEVICE_FACTORY_DEFINE_INTERNAL(VETH, - Veth, - veth, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VETH), - factory_class->create_device = create_device;); +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + VETH, + Veth, + veth, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VETH) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_VETH_SETTING_NAME), + factory_class->create_device = create_device;); |