diff options
Diffstat (limited to 'src/devices')
24 files changed, 763 insertions, 196 deletions
diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index dddb8342..f312b5a3 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -27,7 +27,7 @@ #include "nm-device-adsl.h" #include "devices/nm-device-factory.h" #include "platform/nm-platform.h" -#include "nm-utils/nm-udev-utils.h" +#include "nm-udev-aux/nm-udev-utils.h" /*****************************************************************************/ diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index dc85a8b2..9cd3a519 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -35,7 +35,7 @@ #include "nm-device-bt.h" #include "nm-core-internal.h" #include "platform/nm-platform.h" -#include "nm-dbus-compat.h" +#include "nm-std-aux/nm-dbus-compat.h" /*****************************************************************************/ diff --git a/src/devices/nm-acd-manager.c b/src/devices/nm-acd-manager.c index a8f7a63a..f437ce3a 100644 --- a/src/devices/nm-acd-manager.c +++ b/src/devices/nm-acd-manager.c @@ -113,6 +113,30 @@ acd_error_to_string (int error) g_return_val_if_reached (NULL); } +static int +acd_error_to_nmerr (int error, gboolean always_fail) +{ + if (error < 0) + return -nm_errno_native (error); + + if (always_fail) { + if (NM_IN_SET (error, N_ACD_E_PREEMPTED, + N_ACD_E_INVALID_ARGUMENT)) + return -NME_UNSPEC; + g_return_val_if_reached (-NME_UNSPEC); + } + + /* so, @error is either zero (indicating success) or one + * of the special status codes like N_ACD_E_*. In both cases, + * return the positive value here. */ + if (NM_IN_SET (error, _N_ACD_E_SUCCESS, + N_ACD_E_PREEMPTED, + N_ACD_E_INVALID_ARGUMENT)) + return error; + + g_return_val_if_reached (error); +} + /*****************************************************************************/ /** @@ -291,9 +315,9 @@ acd_init (NMAcdManager *self) * Start probing IP addresses for duplicates; when the probe terminates a * PROBE_TERMINATED signal is emitted. * - * Returns: %TRUE if at least one probe could be started, %FALSE otherwise + * Returns: 0 on success or a negative NetworkManager error code (NME_*). */ -gboolean +int nm_acd_manager_start_probe (NMAcdManager *self, guint timeout) { GHashTableIter iter; @@ -309,7 +333,7 @@ nm_acd_manager_start_probe (NMAcdManager *self, guint timeout) _LOGW ("couldn't init ACD for probing on interface '%s': %s", nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), acd_error_to_string (r)); - return FALSE; + return acd_error_to_nmerr (r, TRUE); } self->completed = 0; @@ -325,7 +349,7 @@ nm_acd_manager_start_probe (NMAcdManager *self, guint timeout) self->channel = g_io_channel_unix_new (fd); self->event_id = g_io_add_watch (self->channel, G_IO_IN, acd_event, self); - return success; + return success ? 0 : -NME_UNSPEC; } /** @@ -357,20 +381,23 @@ nm_acd_manager_check_address (NMAcdManager *self, in_addr_t address) * @self: a #NMAcdManager * * Start announcing addresses. + * + * Returns: a negative NetworkManager error number or zero on success. */ -void +int nm_acd_manager_announce_addresses (NMAcdManager *self) { GHashTableIter iter; AddressInfo *info; int r; + gboolean success = TRUE; r = acd_init (self); if (r) { _LOGW ("couldn't init ACD for announcing addresses on interface '%s': %s", nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), acd_error_to_string (r)); - return; + return acd_error_to_nmerr (r, TRUE); } if (self->state == STATE_INIT) { @@ -378,8 +405,10 @@ nm_acd_manager_announce_addresses (NMAcdManager *self) * start a fake probe with zero timeout and then perform * the announcement. */ g_hash_table_iter_init (&iter, self->addresses); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) - acd_probe_add (self, info, 0); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) { + if (!acd_probe_add (self, info, 0)) + success = FALSE; + } self->state = STATE_ANNOUNCING; } else if (self->state == STATE_ANNOUNCING) { char sbuf[NM_UTILS_INET_ADDRSTRLEN]; @@ -394,10 +423,13 @@ nm_acd_manager_announce_addresses (NMAcdManager *self) nm_utils_inet4_ntop (info->address, sbuf), nm_platform_link_get_name (NM_PLATFORM_GET, self->ifindex), acd_error_to_string (r)); + success = FALSE; } else _LOGD ("announcing address %s", nm_utils_inet4_ntop (info->address, sbuf)); } } + + return success ? 0 : -NME_UNSPEC; } static void diff --git a/src/devices/nm-acd-manager.h b/src/devices/nm-acd-manager.h index 75884846..08c0b798 100644 --- a/src/devices/nm-acd-manager.h +++ b/src/devices/nm-acd-manager.h @@ -36,8 +36,11 @@ NMAcdManager *nm_acd_manager_new (int ifindex, void nm_acd_manager_free (NMAcdManager *self); gboolean nm_acd_manager_add_address (NMAcdManager *self, in_addr_t address); -gboolean nm_acd_manager_start_probe (NMAcdManager *self, guint timeout); +int nm_acd_manager_start_probe (NMAcdManager *self, guint timeout); gboolean nm_acd_manager_check_address (NMAcdManager *self, in_addr_t address); -void nm_acd_manager_announce_addresses (NMAcdManager *self); +int nm_acd_manager_announce_addresses (NMAcdManager *self); + +NM_AUTO_DEFINE_FCN0 (NMAcdManager *, _nm_auto_free_acdmgr, nm_acd_manager_free); +#define nm_auto_free_acdmgr nm_auto (_nm_auto_free_acdmgr) #endif /* __NM_ACD_MANAGER__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 6dabdfe8..37159fca 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -185,20 +185,18 @@ set_arp_targets (NMDevice *device, const char *delim, const char *prefix) { - char **items, **iter, *tmp; + gs_free const char **value_v = NULL; + gsize i; - if (!value || !*value) + value_v = nm_utils_strsplit_set (value, delim); + if (!value_v) return; + for (i = 0; value_v[i]; i++) { + gs_free char *tmp = NULL; - items = g_strsplit_set (value, delim, 0); - for (iter = items; iter && *iter; iter++) { - if (*iter[0]) { - tmp = g_strdup_printf ("%s%s", prefix, *iter); - set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, tmp); - g_free (tmp); - } + tmp = g_strdup_printf ("%s%s", prefix, value_v[i]); + set_bond_attr (device, mode, NM_SETTING_BOND_OPTION_ARP_IP_TARGET, tmp); } - g_strfreev (items); } static void diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 4c8921c0..4275af91 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -37,6 +37,7 @@ _LOG_DECLARE_SELF(NMDeviceBridge); struct _NMDeviceBridge { NMDevice parent; + bool vlan_configured:1; }; struct _NMDeviceBridgeClass { @@ -267,21 +268,45 @@ commit_option (NMDevice *device, NMSetting *setting, const Option *option, gbool nm_platform_sysctl_master_set_option (nm_device_get_platform (device), ifindex, option->sysname, value); } -static void -commit_master_options (NMDevice *device, NMSettingBridge *setting) +static const NMPlatformBridgeVlan ** +setting_vlans_to_platform (GPtrArray *array) { - const Option *option; - NMSetting *s = NM_SETTING (setting); - - for (option = master_options; option->name; option++) - commit_option (device, s, option, FALSE); + NMPlatformBridgeVlan **arr; + NMPlatformBridgeVlan *p_data; + guint i; + + if (!array || !array->len) + return NULL; + + G_STATIC_ASSERT_EXPR (_nm_alignof (NMPlatformBridgeVlan *) >= _nm_alignof (NMPlatformBridgeVlan)); + arr = g_malloc ( (sizeof (NMPlatformBridgeVlan *) * (array->len + 1)) + + (sizeof (NMPlatformBridgeVlan ) * (array->len ))); + p_data = (NMPlatformBridgeVlan *) &arr[array->len + 1]; + + for (i = 0; i < array->len; i++) { + NMBridgeVlan *vlan = array->pdata[i]; + guint16 vid_start, vid_end; + + nm_bridge_vlan_get_vid_range (vlan, &vid_start, &vid_end); + + p_data[i] = (NMPlatformBridgeVlan) { + .vid_start = vid_start, + .vid_end = vid_end, + .pvid = nm_bridge_vlan_is_pvid (vlan), + .untagged = nm_bridge_vlan_is_untagged (vlan), + }; + arr[i] = &p_data[i]; + } + arr[i] = NULL; + return (const NMPlatformBridgeVlan **) arr; } static void commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) { const Option *option; - NMSetting *s, *s_clear = NULL; + NMSetting *s; + gs_unref_object NMSetting *s_clear = NULL; if (setting) s = NM_SETTING (setting); @@ -290,8 +315,6 @@ commit_slave_options (NMDevice *device, NMSettingBridgePort *setting) for (option = slave_options; option->name; option++) commit_option (device, s, option, TRUE); - - g_clear_object (&s_clear); } static void @@ -396,22 +419,112 @@ master_update_slave_connection (NMDevice *device, return TRUE; } +static gboolean +bridge_set_vlan_options (NMDevice *device, NMSettingBridge *s_bridge) +{ + NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + gconstpointer hwaddr; + size_t length; + gboolean enabled; + guint16 pvid; + NMPlatform *plat; + int ifindex; + gs_unref_ptrarray GPtrArray *vlans = NULL; + gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; + + if (self->vlan_configured) + return TRUE; + + plat = nm_device_get_platform (device); + ifindex = nm_device_get_ifindex (device); + enabled = nm_setting_bridge_get_vlan_filtering (s_bridge); + + if (!enabled) { + nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0"); + nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "1"); + nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, NULL); + return TRUE; + } + + hwaddr = nm_platform_link_get_address (plat, ifindex, &length); + g_return_val_if_fail (length == ETH_ALEN, FALSE); + if (nm_utils_hwaddr_matches (hwaddr, ETH_ALEN, nm_ip_addr_zero.addr_eth, ETH_ALEN)) { + /* We need a non-zero MAC address to set the default pvid. + * Retry later. */ + return TRUE; + } + + self->vlan_configured = TRUE; + + /* Filtering must be disabled to change the default PVID */ + if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0")) + return FALSE; + + /* Clear the default PVID so that we later can force the re-creation of + * default PVID VLANs by writing the option again. */ + if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "0")) + return FALSE; + + /* Clear all existing VLANs */ + if (!nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, NULL)) + return FALSE; + + /* Now set the default PVID. After this point the kernel creates + * a PVID VLAN on each port, including the bridge itself. */ + pvid = nm_setting_bridge_get_vlan_default_pvid (s_bridge); + if (pvid) { + char value[32]; + + nm_sprintf_buf (value, "%u", pvid); + if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", value)) + return FALSE; + } + + /* Create VLANs only after setting the default PVID, so that + * any PVID VLAN overrides the bridge's default PVID. */ + g_object_get (s_bridge, NM_SETTING_BRIDGE_VLANS, &vlans, NULL); + plat_vlans = setting_vlans_to_platform (vlans); + if ( plat_vlans + && !nm_platform_link_set_bridge_vlans (plat, ifindex, FALSE, plat_vlans)) + return FALSE; + + if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "1")) + return FALSE; + + return TRUE; +} + static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) { NMActStageReturn ret; - NMConnection *connection = nm_device_get_applied_connection (device); + NMConnection *connection; + NMSetting *s_bridge; + const Option *option; - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); + NM_DEVICE_BRIDGE (device)->vlan_configured = FALSE; ret = NM_DEVICE_CLASS (nm_device_bridge_parent_class)->act_stage1_prepare (device, out_failure_reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE)) + connection = nm_device_get_applied_connection (device); + g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); + s_bridge = (NMSetting *) nm_connection_get_setting_bridge (connection); + g_return_val_if_fail (s_bridge, NM_ACT_STAGE_RETURN_FAILURE); + + if (!nm_device_hw_addr_set_cloned (device, connection, FALSE)) { + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); return NM_ACT_STAGE_RETURN_FAILURE; + } - commit_master_options (device, nm_connection_get_setting_bridge (connection)); + for (option = master_options; option->name; option++) + commit_option (device, s_bridge, option, FALSE); + + if (!bridge_set_vlan_options (device, (NMSettingBridge *) s_bridge)) { + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -457,12 +570,43 @@ enslave_slave (NMDevice *device, gboolean configure) { NMDeviceBridge *self = NM_DEVICE_BRIDGE (device); + NMConnection *master_connection; + NMSettingBridge *s_bridge; + NMSettingBridgePort *s_port; if (configure) { if (!nm_platform_link_enslave (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave))) return FALSE; - commit_slave_options (slave, nm_connection_get_setting_bridge_port (connection)); + master_connection = nm_device_get_applied_connection (device); + nm_assert (master_connection); + s_bridge = nm_connection_get_setting_bridge (master_connection); + nm_assert (s_bridge); + s_port = nm_connection_get_setting_bridge_port (connection); + + bridge_set_vlan_options (device, s_bridge); + + if (nm_setting_bridge_get_vlan_filtering (s_bridge)) { + gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; + gs_unref_ptrarray GPtrArray *vlans = NULL; + + if (s_port) + g_object_get (s_port, NM_SETTING_BRIDGE_PORT_VLANS, &vlans, NULL); + + plat_vlans = setting_vlans_to_platform (vlans); + + /* Since the link was just enslaved, there are no existing VLANs + * (except for the default one) and so there's no need to flush. */ + + if ( plat_vlans + && !nm_platform_link_set_bridge_vlans (nm_device_get_platform (slave), + nm_device_get_ifindex (slave), + TRUE, + plat_vlans)) + return FALSE; + } + + commit_slave_options (slave, s_port); _LOGI (LOGD_BRIDGE, "attached bridge port %s", nm_device_get_ip_iface (slave)); diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 24c99f76..170c7e28 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -48,7 +48,7 @@ #include "nm-device-factory.h" #include "nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-utils/nm-udev-utils.h" +#include "nm-udev-aux/nm-udev-utils.h" #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceEthernet); diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 6e2372ab..dd98e92f 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -168,7 +168,8 @@ NMIPConfig *nm_device_ip_config_new (NMDevice *self, int addr_family); /*****************************************************************************/ gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self, - const char *property_name); + const char *property_name, + guint32 max_mtu); guint32 nm_device_get_configured_mtu_from_connection (NMDevice *device, GType setting_type, diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c index a9eb1ab4..f8c7d1c3 100644 --- a/src/devices/nm-device-wireguard.c +++ b/src/devices/nm-device-wireguard.c @@ -23,7 +23,7 @@ #include "nm-setting-wireguard.h" #include "nm-core-internal.h" -#include "nm-utils/nm-secret-utils.h" +#include "nm-glib-aux/nm-secret-utils.h" #include "nm-device-private.h" #include "platform/nm-platform.h" #include "platform/nmp-object.h" diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7514fa78..bd4fbcc3 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -36,17 +36,18 @@ #include <linux/rtnetlink.h> #include <linux/pkt_sched.h> -#include "nm-utils/nm-dedup-multi.h" -#include "nm-utils/nm-random-utils.h" -#include "nm-utils/unaligned.h" +#include "nm-std-aux/unaligned.h" +#include "nm-glib-aux/nm-dedup-multi.h" +#include "nm-glib-aux/nm-random-utils.h" -#include "nm-ethtool-utils.h" -#include "nm-common-macros.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" +#include "nm-libnm-core-intern/nm-common-macros.h" #include "nm-device-private.h" #include "NetworkManagerUtils.h" #include "nm-manager.h" #include "platform/nm-platform.h" #include "platform/nmp-object.h" +#include "platform/nmp-rules-manager.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" #include "dhcp/nm-dhcp-manager.h" @@ -1545,8 +1546,7 @@ _set_ip_ifindex (NMDevice *self, priv->ip_ifindex, priv->ip_iface); - if (nm_platform_check_kernel_support (platform, - NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) + if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) nm_platform_link_set_user_ipv6ll_enabled (platform, priv->ip_ifindex, TRUE); if (!nm_platform_link_is_up (platform, priv->ip_ifindex)) @@ -2787,8 +2787,10 @@ nm_device_check_connectivity_update_interval (NMDevice *self) } static void -concheck_update_state (NMDevice *self, int addr_family, - NMConnectivityState state, gboolean allow_periodic_bump) +concheck_update_state (NMDevice *self, + int addr_family, + NMConnectivityState state, + gboolean allow_periodic_bump) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); const gboolean IS_IPv4 = (addr_family == AF_INET); @@ -2821,6 +2823,14 @@ concheck_update_state (NMDevice *self, int addr_family, state = NM_CONNECTIVITY_LIMITED; } else state = NM_CONNECTIVITY_NONE; + } else if (state == NM_CONNECTIVITY_LIMITED) { + /* NMConnectivity cannot distinguish between NONE and LIMITED connectivity. In both + * cases, it just failed to fetch the URL. + * + * NMDevice coerces a LIMITED state to NONE here, if the logical state of the device + * is disconnected. */ + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) + state = NM_CONNECTIVITY_NONE; } if (priv->concheck_x[IS_IPv4].state == state) { @@ -4319,8 +4329,7 @@ realize_start_setup (NMDevice *self, if (priv->firmware_version) _notify (self, PROP_FIRMWARE_VERSION); - if (nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) + if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled (nm_device_get_platform (self), priv->ifindex); if (nm_platform_link_supports_sriov (nm_device_get_platform (self), priv->ifindex)) @@ -5064,7 +5073,6 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection = nm_device_get_applied_connection (self); - NMDeviceState new_state; const char *master_status; g_return_if_fail (priv->master); @@ -5073,16 +5081,17 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) && priv->state <= NM_DEVICE_STATE_ACTIVATED) { switch (nm_device_state_reason_check (reason)) { case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: - new_state = NM_DEVICE_STATE_FAILED; master_status = "failed"; break; case NM_DEVICE_STATE_REASON_USER_REQUESTED: - new_state = NM_DEVICE_STATE_DEACTIVATING; reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; master_status = "deactivated by user request"; break; + case NM_DEVICE_STATE_REASON_CONNECTION_REMOVED: + reason = NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED; + master_status = "deactivated because master was removed"; + break; default: - new_state = NM_DEVICE_STATE_DISCONNECTED; master_status = "deactivated"; break; } @@ -5093,7 +5102,7 @@ nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) /* Cancel any pending activation sources */ _cancel_activation (self); - nm_device_queue_state (self, new_state, reason); + nm_device_queue_state (self, NM_DEVICE_STATE_DEACTIVATING, reason); } else _LOGI (LOGD_DEVICE, "released from master device %s", nm_device_get_iface (priv->master)); @@ -5304,7 +5313,8 @@ nm_device_autoconnect_allowed (NMDevice *self) if (priv->state < NM_DEVICE_STATE_DISCONNECTED) return FALSE; } else { - /* Unrealized devices can always autoconnect. */ + if (!nm_device_check_unrealized_device_managed (self)) + return FALSE; } /* The 'autoconnect-allowed' signal is emitted on a device to allow @@ -6403,6 +6413,84 @@ lldp_init (NMDevice *self, gboolean restart) } } +/* set-mode can be: + * - TRUE: sync with new rules. + * - FALSE: sync, but remove all rules (== flush) + * - DEFAULT: forget about all the rules that we previously tracked, + * but don't actually remove them. This is when quitting NM + * we want to keep the rules. + * The problem is, after restart of NM, the rule manager will + * no longer remember that NM added these rules and treat them + * as externally added ones. Don't restart NetworkManager if + * you care about that. + */ +static void +_routing_rules_sync (NMDevice *self, + NMTernary set_mode) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMPRulesManager *rules_manager = nm_netns_get_rules_manager (nm_device_get_netns (self)); + gboolean untrack_only_dirty = FALSE; + gboolean keep_deleted_rules; + gpointer user_tag; + + user_tag = priv; + + if (set_mode == NM_TERNARY_TRUE) { + NMConnection *applied_connection; + NMSettingIPConfig *s_ip; + guint i, num; + int is_ipv4; + + untrack_only_dirty = TRUE; + nmp_rules_manager_set_dirty (rules_manager, user_tag); + + applied_connection = nm_device_get_applied_connection (self); + + for (is_ipv4 = 0; applied_connection && is_ipv4 < 2; is_ipv4++) { + int addr_family = is_ipv4 ? AF_INET : AF_INET6; + + s_ip = nm_connection_get_setting_ip_config (applied_connection, addr_family); + if (!s_ip) + continue; + + num = nm_setting_ip_config_get_num_routing_rules (s_ip); + for (i = 0; i < num; i++) { + NMPlatformRoutingRule plrule; + NMIPRoutingRule *rule; + + rule = nm_setting_ip_config_get_routing_rule (s_ip, i); + nm_ip_routing_rule_to_platform (rule, &plrule); + nmp_rules_manager_track (rules_manager, + &plrule, + 10, + user_tag); + } + } + } + + nmp_rules_manager_untrack_all (rules_manager, user_tag, !untrack_only_dirty); + + keep_deleted_rules = FALSE; + if (set_mode == NM_TERNARY_DEFAULT) { + /* when exiting NM, we leave the device up and the rules configured. + * We just all nmp_rules_manager_sync() to forget about the synced rules, + * but we don't actually delete them. + * + * FIXME: that is a problem after restart of NetworkManager, because these + * rules will look like externally added, and NM will no longer remove + * them. + * To fix that, we could during "assume" mark the rules of the profile + * as owned (and "added" by the device). The problem with that is that it + * wouldn't cover rules that devices add by internal decision (not because + * of a setting in the profile, e.g. WireGuard could setup policy routing). + * Maybe it would be better to remember these orphaned rules at exit in a + * file and track them after restart again. */ + keep_deleted_rules = TRUE; + } + nmp_rules_manager_sync (rules_manager, keep_deleted_rules); +} + static gboolean tc_commit (NMDevice *self) { @@ -6514,6 +6602,8 @@ activate_stage2_device_config (NMDevice *self) } } + _routing_rules_sync (self, NM_TERNARY_TRUE); + if (!nm_device_sys_iface_state_is_external_or_assume (self)) { if (!nm_device_bring_up (self, FALSE, &no_firmware)) { if (no_firmware) @@ -6747,7 +6837,8 @@ ipv4_dad_start (NMDevice *self, NMIP4Config **configs, AcdCallback cb) NMDedupMultiIter ipconf_iter; AcdData *data; guint timeout; - gboolean ret, addr_found; + gboolean addr_found; + int r; const guint8 *hwaddr_arr; size_t length; guint i; @@ -6801,9 +6892,8 @@ ipv4_dad_start (NMDevice *self, NMIP4Config **configs, AcdCallback cb) nm_acd_manager_add_address (acd_manager, address->address); } - ret = nm_acd_manager_start_probe (acd_manager, timeout); - - if (!ret) { + r = nm_acd_manager_start_probe (acd_manager, timeout); + if (r < 0) { _LOGW (LOGD_DEVICE, "acd probe failed"); /* DAD could not be started, signal success */ @@ -8830,12 +8920,13 @@ linklocal6_start (NMDevice *self) gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self, - const char *property_name) + const char *property_name, + guint32 max_mtu) { return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, property_name, self, - 0, G_MAXUINT32, -1); + 0, max_mtu, -1); } guint32 @@ -8848,6 +8939,7 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self, NMSetting *setting; gint64 mtu_default; guint32 mtu = 0; + guint32 max_mtu = G_MAXUINT32; nm_assert (NM_IS_DEVICE (self)); nm_assert (out_source); @@ -8870,6 +8962,7 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self, if (setting) mtu = nm_setting_infiniband_get_mtu (NM_SETTING_INFINIBAND (setting)); global_property_name = NM_CON_DEFAULT ("infiniband.mtu"); + max_mtu = NM_INFINIBAND_MAX_MTU; } else if (setting_type == NM_TYPE_SETTING_IP_TUNNEL) { if (setting) mtu = nm_setting_ip_tunnel_get_mtu (NM_SETTING_IP_TUNNEL (setting)); @@ -8881,13 +8974,12 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self, } else g_return_val_if_reached (0); - if (mtu) { *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return mtu; } - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, global_property_name); + mtu_default = nm_device_get_configured_mtu_from_connection_default (self, global_property_name, max_mtu); if (mtu_default >= 0) { *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return (guint32) mtu_default; @@ -9140,8 +9232,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in * addresses as /128. The reason for the /128 is to prevent the kernel * from adding a prefix route for this address. */ ifa_flags = 0; - if (nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) { + if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { ifa_flags |= IFA_F_NOPREFIXROUTE; if (NM_IN_SET (priv->ndisc_use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) @@ -9173,8 +9264,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in rdata->routes_n, nm_device_get_route_table (self, AF_INET6, TRUE), nm_device_get_route_metric (self, AF_INET6), - nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_RTA_PREF)); + nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); if (priv->ac_ip6_config.current) { nm_ip6_config_reset_routes_ndisc ((NMIP6Config *) priv->ac_ip6_config.current, rdata->gateways, @@ -9183,8 +9273,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in rdata->routes_n, nm_device_get_route_table (self, AF_INET6, TRUE), nm_device_get_route_metric (self, AF_INET6), - nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_RTA_PREF)); + nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); } } @@ -9372,8 +9461,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) priv->ndisc_use_tempaddr = use_tempaddr; if ( NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) - && !nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_EXTENDED_IFA_FLAGS)) { + && !nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { _LOGW (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for " "IPv6 private addresses. This feature is not available"); } @@ -9480,8 +9568,7 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int ifindex = nm_device_get_ip_ifindex (self); - if (!nm_platform_check_kernel_support (nm_device_get_platform (self), - NM_PLATFORM_KERNEL_SUPPORT_USER_IPV6LL)) + if (!nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) return; priv->ipv6ll_handle = enable; @@ -9854,7 +9941,7 @@ nm_device_activate_stage3_ip6_start (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActStageReturn ret; NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - NMIP6Config *ip6_config = NULL; + gs_unref_object NMIP6Config *ip6_config = NULL; g_assert (priv->ip_state_6 == NM_DEVICE_IP_STATE_WAIT); @@ -13424,6 +13511,32 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self, _set_unmanaged_flags (self, flags, set_op, TRUE, FALSE, reason); } +/** + * nm_device_check_unrealized_device_managed: + * + * Checks if a unrealized device is managed from user settings + * or user configuration. + */ +gboolean +nm_device_check_unrealized_device_managed (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + nm_assert (!nm_device_is_real (self)); + + if (!nm_config_data_get_device_config_boolean (NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, + self, + TRUE, + TRUE)) + return FALSE; + + if (nm_device_spec_match_list (self, nm_settings_get_unmanaged_specs (priv->settings))) + return FALSE; + + return TRUE; +} + void nm_device_set_unmanaged_by_user_settings (NMDevice *self) { @@ -14345,6 +14458,11 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean } } + _routing_rules_sync (self, + cleanup_type == CLEANUP_TYPE_KEEP + ? NM_TERNARY_DEFAULT + : NM_TERNARY_FALSE); + if (ifindex > 0) nm_platform_ip4_dev_route_blacklist_set (nm_device_get_platform (self), ifindex, NULL); @@ -15879,17 +15997,22 @@ nm_device_spec_match_list_full (NMDevice *self, const GSList *specs, int no_matc { NMDeviceClass *klass; NMMatchSpecMatchType m; + const char *hw_address = NULL; + gboolean is_fake; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); klass = NM_DEVICE_GET_CLASS (self); + hw_address = nm_device_get_permanent_hw_address_full (self, + !nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT), + &is_fake); m = nm_match_spec_device (specs, nm_device_get_iface (self), nm_device_get_type_description (self), nm_device_get_driver (self), nm_device_get_driver_version (self), - nm_device_get_permanent_hw_address (self), + is_fake ? NULL : hw_address, klass->get_s390_subchannels ? klass->get_s390_subchannels (self) : NULL, nm_dhcp_manager_get_config (nm_dhcp_manager_get ())); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 45c9dda0..d11c33ab 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -691,6 +691,8 @@ void nm_device_set_unmanaged_by_user_udev (NMDevice *self); void nm_device_set_unmanaged_by_user_conf (NMDevice *self); void nm_device_set_unmanaged_by_quitting (NMDevice *device); +gboolean nm_device_check_unrealized_device_managed (NMDevice *self); + gboolean nm_device_is_nm_owned (NMDevice *device); gboolean nm_device_has_capability (NMDevice *self, NMDeviceCapabilities caps); diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c index cb3b5907..831054ba 100644 --- a/src/devices/nm-lldp-listener.c +++ b/src/devices/nm-lldp-listener.c @@ -24,7 +24,9 @@ #include <net/ethernet.h> +#include "nm-std-aux/unaligned.h" #include "platform/nm-platform.h" +#include "nm-glib-aux/nm-c-list.h" #include "nm-utils.h" #include "systemd/nm-sd.h" @@ -40,6 +42,8 @@ typedef enum { LLDP_ATTR_TYPE_NONE, LLDP_ATTR_TYPE_UINT32, LLDP_ATTR_TYPE_STRING, + LLDP_ATTR_TYPE_VARDICT, + LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS, } LldpAttrType; typedef enum { @@ -49,12 +53,18 @@ typedef enum { LLDP_ATTR_ID_SYSTEM_NAME, LLDP_ATTR_ID_SYSTEM_DESCRIPTION, LLDP_ATTR_ID_SYSTEM_CAPABILITIES, + LLDP_ATTR_ID_MANAGEMENT_ADDRESSES, LLDP_ATTR_ID_IEEE_802_1_PVID, LLDP_ATTR_ID_IEEE_802_1_PPVID, LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, + LLDP_ATTR_ID_IEEE_802_1_PPVIDS, LLDP_ATTR_ID_IEEE_802_1_VID, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, - _LLDP_PROP_ID_COUNT, + LLDP_ATTR_ID_IEEE_802_1_VLANS, + LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF, + LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI, + LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE, + _LLDP_ATTR_ID_COUNT, } LldpAttrId; typedef struct { @@ -62,6 +72,8 @@ typedef struct { union { guint32 v_uint32; char *v_string; + GVariant *v_variant; + CList v_variant_list; }; } LldpAttrData; @@ -109,7 +121,7 @@ typedef struct { bool valid:1; - LldpAttrData attrs[_LLDP_PROP_ID_COUNT]; + LldpAttrData attrs[_LLDP_ATTR_ID_COUNT]; GVariant *variant; } LldpNeighbor; @@ -155,35 +167,26 @@ ether_addr_equal (const struct ether_addr *a1, const struct ether_addr *a2) return memcmp (a1, a2, ETH_ALEN) == 0; } -static guint32 -_access_uint8 (const void *data) -{ - return *((const guint8 *) data); -} - -static guint32 -_access_uint16 (const void *data) -{ - guint16 v; - - memcpy (&v, data, sizeof (v)); - return ntohs (v); -} - /*****************************************************************************/ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_lldp_attr_id_to_name, LldpAttrId, NM_UTILS_LOOKUP_DEFAULT_WARN (NULL), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_PORT_DESCRIPTION, NM_LLDP_ATTR_PORT_DESCRIPTION), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_NAME, NM_LLDP_ATTR_SYSTEM_NAME), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_DESCRIPTION, NM_LLDP_ATTR_SYSTEM_DESCRIPTION), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_CAPABILITIES, NM_LLDP_ATTR_SYSTEM_CAPABILITIES), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PVID, NM_LLDP_ATTR_IEEE_802_1_PVID), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID, NM_LLDP_ATTR_IEEE_802_1_PPVID), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VID, NM_LLDP_ATTR_IEEE_802_1_VID), - NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME), - NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_PROP_ID_COUNT), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_PORT_DESCRIPTION, NM_LLDP_ATTR_PORT_DESCRIPTION), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_NAME, NM_LLDP_ATTR_SYSTEM_NAME), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_DESCRIPTION, NM_LLDP_ATTR_SYSTEM_DESCRIPTION), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_SYSTEM_CAPABILITIES, NM_LLDP_ATTR_SYSTEM_CAPABILITIES), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_MANAGEMENT_ADDRESSES, NM_LLDP_ATTR_MANAGEMENT_ADDRESSES), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PVID, NM_LLDP_ATTR_IEEE_802_1_PVID), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID, NM_LLDP_ATTR_IEEE_802_1_PPVID), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVIDS, NM_LLDP_ATTR_IEEE_802_1_PPVIDS), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VID, NM_LLDP_ATTR_IEEE_802_1_VID), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLANS, NM_LLDP_ATTR_IEEE_802_1_VLANS), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF, NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI, NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI), + NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE,NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE), + NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_ATTR_ID_COUNT), ); _NM_UTILS_LOOKUP_DEFINE (static, _lldp_attr_id_to_type, LldpAttrId, LldpAttrType, @@ -192,12 +195,18 @@ _NM_UTILS_LOOKUP_DEFINE (static, _lldp_attr_id_to_type, LldpAttrId, LldpAttrType NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_SYSTEM_NAME, LLDP_ATTR_TYPE_STRING), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_SYSTEM_DESCRIPTION, LLDP_ATTR_TYPE_STRING), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_SYSTEM_CAPABILITIES, LLDP_ATTR_TYPE_UINT32), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_MANAGEMENT_ADDRESSES, LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_PVID, LLDP_ATTR_TYPE_UINT32), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID, LLDP_ATTR_TYPE_UINT32), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, LLDP_ATTR_TYPE_UINT32), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVIDS, LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VID, LLDP_ATTR_TYPE_UINT32), NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, LLDP_ATTR_TYPE_STRING), - NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_PROP_ID_COUNT), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLANS, LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF, LLDP_ATTR_TYPE_VARDICT), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI, LLDP_ATTR_TYPE_VARDICT), + NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE, LLDP_ATTR_TYPE_UINT32), + NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_ATTR_ID_COUNT), ); static void @@ -216,13 +225,8 @@ _lldp_attr_set_str (LldpAttrData *pdata, LldpAttrId attr_id, const char *v_strin } static void -_lldp_attr_set_str_ptr (LldpAttrData *pdata, LldpAttrId attr_id, const void *str, gsize len) +_lldp_attr_take_str_ptr (LldpAttrData *pdata, LldpAttrId attr_id, char *str) { - const char *s = str; - const char *tmp; - gsize len0 = len; - gs_free char *str_free = NULL; - nm_assert (pdata); nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_STRING); @@ -233,23 +237,7 @@ _lldp_attr_set_str_ptr (LldpAttrData *pdata, LldpAttrId attr_id, const void *str return; pdata->attr_type = LLDP_ATTR_TYPE_STRING; - - /* truncate at first NUL, including removing trailing NULs*/ - tmp = memchr (s, '\0', len); - if (tmp) - len = tmp - s; - - if (!len) { - pdata->v_string = g_strdup (""); - return; - } - - if (len0 <= len || s[len] != '\0') { - /* hmpf, g_strescape needs a trailing NUL. Need to clone */ - s = str_free = g_strndup (s, len); - } - - pdata->v_string = g_strescape (s, NULL); + pdata->v_string = str; } static void @@ -267,6 +255,44 @@ _lldp_attr_set_uint32 (LldpAttrData *pdata, LldpAttrId attr_id, guint32 v_uint32 pdata->v_uint32 = v_uint32; } +static void +_lldp_attr_set_vardict (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *variant) +{ + + nm_assert (pdata); + nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_VARDICT); + + pdata = &pdata[attr_id]; + + /* we ignore duplicate fields silently */ + if (pdata->attr_type != LLDP_ATTR_TYPE_NONE) { + if (g_variant_is_floating (variant)) + g_variant_unref (variant); + return; + } + + pdata->attr_type = LLDP_ATTR_TYPE_VARDICT; + pdata->v_variant = g_variant_ref_sink (variant); +} + +static void +_lldp_attr_add_vardict (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *variant) +{ + nm_assert (pdata); + nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS); + + g_variant_ref_sink (variant); + pdata = &pdata[attr_id]; + + if (pdata->attr_type == LLDP_ATTR_TYPE_NONE) { + c_list_init (&pdata->v_variant_list); + pdata->attr_type = LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS; + } else + nm_assert (pdata->attr_type == LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS); + + c_list_link_tail (&pdata->v_variant_list, &nm_c_list_elem_new_stale (variant)->lst); +} + /*****************************************************************************/ static guint @@ -312,13 +338,28 @@ static void lldp_neighbor_free (LldpNeighbor *neighbor) { LldpAttrId attr_id; + LldpAttrType attr_type; if (neighbor) { g_free (neighbor->chassis_id); g_free (neighbor->port_id); - for (attr_id = 0; attr_id < _LLDP_PROP_ID_COUNT; attr_id++) { - if (neighbor->attrs[attr_id].attr_type == LLDP_ATTR_TYPE_STRING) + for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) { + attr_type = neighbor->attrs[attr_id].attr_type; + + switch (attr_type) { + case LLDP_ATTR_TYPE_STRING: g_free (neighbor->attrs[attr_id].v_string); + break; + case LLDP_ATTR_TYPE_VARDICT: + g_variant_unref (neighbor->attrs[attr_id].v_variant); + break; + case LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS: + nm_c_list_elem_free_all (&neighbor->attrs[attr_id].v_variant_list, + (GDestroyNotify) g_variant_unref); + break; + default: + ; + } } g_clear_pointer (&neighbor->variant, g_variant_unref); g_slice_free (LldpNeighbor, neighbor); @@ -346,7 +387,7 @@ lldp_neighbor_equal (LldpNeighbor *a, LldpNeighbor *b) || !nm_streq0 (a->port_id, b->port_id)) return FALSE; - for (attr_id = 0; attr_id < _LLDP_PROP_ID_COUNT; attr_id++) { + for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) { if (a->attrs[attr_id].attr_type != b->attrs[attr_id].attr_type) return FALSE; switch (a->attrs[attr_id].attr_type) { @@ -367,6 +408,75 @@ lldp_neighbor_equal (LldpNeighbor *a, LldpNeighbor *b) return TRUE; } +static GVariant * +parse_management_address_tlv (uint8_t *data, gsize len) +{ + GVariantDict dict; + GVariant *variant; + gsize addr_len, oid_len; + + /* 802.1AB-2009 - Figure 8-11 + * + * - TLV type / length (2 bytes) + * - address string length (1 byte) + * - address subtype (1 byte) + * - address (1 to 31 bytes) + * - interface number subtype (1 byte) + * - interface number (4 bytes) + * - OID string length (1 byte) + * - OID (0 to 128 bytes) + */ + + if (len < 11) + goto err; + + nm_assert ((data[0] >> 1) == SD_LLDP_TYPE_MGMT_ADDRESS); + nm_assert ((((data[0] & 1) << 8) + data[1]) + 2 == len); + + data += 2; + len -= 2; + addr_len = *data; /* length of (address subtype + address) */ + + if (addr_len < 2 || addr_len > 32) + goto err; + if (len < ( 1 /* address stringth length */ + + addr_len /* address subtype + address */ + + 5 /* interface */ + + 1)) /* oid */ + goto err; + + g_variant_dict_init (&dict, NULL); + + data++; + len--; + g_variant_dict_insert (&dict, "address-subtype", "u", (guint32) *data); + variant = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, data + 1, addr_len - 1, 1); + g_variant_dict_insert_value (&dict, "address", variant); + + data += addr_len; + len -= addr_len; + g_variant_dict_insert (&dict, "interface-number-subtype", "u", (guint32) *data); + + data++; + len--; + g_variant_dict_insert (&dict, "interface-number", "u", unaligned_read_be32 (data)); + + data += 4; + len -= 4; + oid_len = *data; + + if (len < (1 + oid_len)) + goto err; + + data++; + variant = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, data, oid_len, 1); + g_variant_dict_insert_value (&dict, "object-id", variant); + return g_variant_dict_end (&dict); +err: + g_variant_dict_clear (&dict); + return NULL; +} + static LldpNeighbor * lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error) { @@ -468,7 +578,29 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error) } do { guint8 oui[3]; - guint8 subtype; + guint8 type, subtype; + GVariant *variant; + + if (sd_lldp_neighbor_tlv_get_type (neighbor_sd, &type) < 0) + continue; + + if (sd_lldp_neighbor_tlv_get_raw (neighbor_sd, (void *) &data8, &len) < 0) + continue; + + switch (type) { + case SD_LLDP_TYPE_MGMT_ADDRESS: + variant = parse_management_address_tlv (data8, len); + if (variant) { + _lldp_attr_add_vardict (neigh->attrs, + LLDP_ATTR_ID_MANAGEMENT_ADDRESSES, + variant); + } + continue; + case SD_LLDP_TYPE_PRIVATE: + break; + default: + continue; + } r = sd_lldp_neighbor_tlv_get_oui (neighbor_sd, oui, &subtype); if (r < 0) { @@ -479,18 +611,12 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error) goto out; } - if (!( memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0 - && NM_IN_SET (subtype, - SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID, - SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID, - SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME))) - continue; - - if (sd_lldp_neighbor_tlv_get_raw (neighbor_sd, (void *) &data8, &len) < 0) + if ( memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) != 0 + && memcmp (oui, SD_LLDP_OUI_802_3, sizeof (oui)) != 0) continue; /* skip over leading TLV, OUI and subtype */ -#ifdef WITH_MORE_ASSERTS +#if NM_MORE_ASSERTS > 5 { guint8 check_hdr[] = { 0xfe | (((len - 2) >> 8) & 0x01), ((len - 2) & 0xFF), @@ -507,25 +633,37 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error) data8 += 6; len -= 6; - /*if (memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0)*/ - { + if (memcmp (oui, SD_LLDP_OUI_802_1, sizeof (oui)) == 0) { + GVariantDict dict; + switch (subtype) { case SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID: if (len != 2) continue; _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PVID, - _access_uint16 (data8)); + unaligned_read_be16 (data8)); break; case SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID: if (len != 3) continue; _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, - _access_uint8 (&data8[0])); + data8[0]); _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID, - _access_uint16 (&data8[1])); + unaligned_read_be16 (&data8[1])); + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "ppvid", "u", (guint32) unaligned_read_be16 (&data8[1])); + g_variant_dict_insert (&dict, "flags", "u", (guint32) data8[0]); + + _lldp_attr_add_vardict (neigh->attrs, + LLDP_ATTR_ID_IEEE_802_1_PPVIDS, + g_variant_dict_end (&dict)); break; case SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: { int l; + guint32 vid; + const char *name; + char *name_to_free; if (len <= 3) continue; @@ -536,14 +674,62 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error) if (l > 32) continue; - _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID, - _access_uint16 (&data8[0])); - _lldp_attr_set_str_ptr (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, - &data8[3], l); + name = nm_utils_buf_utf8safe_escape (&data8[3], l, 0, &name_to_free); + vid = unaligned_read_be16 (&data8[0]); + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "vid", "u", vid); + g_variant_dict_insert (&dict, "name", "s", name); + + _lldp_attr_add_vardict (neigh->attrs, + LLDP_ATTR_ID_IEEE_802_1_VLANS, + g_variant_dict_end (&dict)); + + _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID, vid); + _lldp_attr_take_str_ptr (neigh->attrs, + LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, + name_to_free ?: g_strdup (name)); break; } default: - g_assert_not_reached (); + continue; + } + } else if (memcmp (oui, SD_LLDP_OUI_802_3, sizeof (oui)) == 0) { + GVariantDict dict; + + switch (subtype) { + case SD_LLDP_OUI_802_3_SUBTYPE_MAC_PHY_CONFIG_STATUS: + if (len != 5) + continue; + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "autoneg", "u", (guint32) data8[0]); + g_variant_dict_insert (&dict, "pmd-autoneg-cap", "u", (guint32) unaligned_read_be16 (&data8[1])); + g_variant_dict_insert (&dict, "operational-mau-type", "u", (guint32) unaligned_read_be16 (&data8[3])); + + _lldp_attr_set_vardict (neigh->attrs, + LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF, + g_variant_dict_end (&dict)); + break; + case SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI: + if (len != 3) + continue; + + g_variant_dict_init (&dict, NULL); + g_variant_dict_insert (&dict, "mdi-power-support", "u", (guint32) data8[0]); + g_variant_dict_insert (&dict, "pse-power-pair", "u", (guint32) data8[1]); + g_variant_dict_insert (&dict, "power-class", "u", (guint32) data8[2]); + + _lldp_attr_set_vardict (neigh->attrs, + LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI, + g_variant_dict_end (&dict)); + break; + case SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE: + if (len != 2) + continue; + _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE, + unaligned_read_be16 (data8)); + break; } } } while (sd_lldp_neighbor_tlv_next (neighbor_sd) > 0); @@ -593,7 +779,7 @@ lldp_neighbor_to_variant (LldpNeighbor *neigh) g_variant_new_string (dest_str)); } - for (attr_id = 0; attr_id < _LLDP_PROP_ID_COUNT; attr_id++) { + for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) { const LldpAttrData *data = &neigh->attrs[attr_id]; nm_assert (NM_IN_SET (data->attr_type, _lldp_attr_id_to_type (attr_id), LLDP_ATTR_TYPE_NONE)); @@ -608,7 +794,26 @@ lldp_neighbor_to_variant (LldpNeighbor *neigh) _lldp_attr_id_to_name (attr_id), g_variant_new_string (data->v_string)); break; - default: + case LLDP_ATTR_TYPE_VARDICT: + g_variant_builder_add (&builder, "{sv}", + _lldp_attr_id_to_name (attr_id), + data->v_variant); + break; + case LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS: { + NMCListElem *elem; + GVariantBuilder builder2; + + g_variant_builder_init (&builder2, G_VARIANT_TYPE ("aa{sv}")); + + c_list_for_each_entry (elem, &data->v_variant_list, lst) + g_variant_builder_add_value (&builder2, elem->data); + + g_variant_builder_add (&builder, "{sv}", + _lldp_attr_id_to_name (attr_id), + g_variant_builder_end (&builder2)); + break; + } + case LLDP_ATTR_TYPE_NONE: break; } } diff --git a/src/devices/ovs/nm-device-ovs-port.c b/src/devices/ovs/nm-device-ovs-port.c index b96eba68..35eb739f 100644 --- a/src/devices/ovs/nm-device-ovs-port.c +++ b/src/devices/ovs/nm-device-ovs-port.c @@ -20,6 +20,7 @@ #include "nm-default.h" #include "nm-device-ovs-port.h" +#include "nm-device-ovs-interface.h" #include "nm-ovsdb.h" #include "devices/nm-device-private.h" @@ -141,6 +142,11 @@ 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)); + + /* Open VSwitch is going to delete this one. We must ignore what happens + * next with the interface. */ + if (NM_IS_DEVICE_OVS_INTERFACE (slave)) + nm_device_update_from_platform_link (slave, NULL); } /*****************************************************************************/ diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c index 766c650b..2124b2a0 100644 --- a/src/devices/ovs/nm-ovs-factory.c +++ b/src/devices/ovs/nm-ovs-factory.c @@ -132,7 +132,7 @@ ovsdb_device_removed (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type && device_state < NM_DEVICE_STATE_DEACTIVATING) { nm_device_state_changed (device, NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_REMOVED); + NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED); } else if (device_state == NM_DEVICE_STATE_UNMANAGED) { nm_device_unrealize (device, TRUE, NULL); } diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c index 9d73c3ac..5b50f840 100644 --- a/src/devices/ovs/nm-ovsdb.c +++ b/src/devices/ovs/nm-ovsdb.c @@ -24,7 +24,7 @@ #include <gmodule.h> #include <gio/gunixsocketaddress.h> -#include "nm-utils/nm-jansson.h" +#include "nm-glib-aux/nm-jansson.h" #include "devices/nm-device.h" #include "platform/nm-platform.h" #include "nm-core-internal.h" diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 38a6dd8c..287f4d1b 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -30,14 +30,14 @@ #include <teamdctl.h> #include <stdlib.h> -#include "nm-utils/nm-jansson.h" +#include "nm-glib-aux/nm-jansson.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" #include "platform/nm-platform.h" #include "nm-config.h" #include "nm-core-internal.h" #include "nm-ip4-config.h" -#include "nm-dbus-compat.h" +#include "nm-std-aux/nm-dbus-compat.h" #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceTeam); @@ -408,8 +408,10 @@ teamd_dbus_appeared (GDBusConnection *connection, success = teamd_read_config (device); if (success) nm_device_activate_schedule_stage2_device_config (device); - else if (!nm_device_sys_iface_state_is_external_or_assume (device)) + else if (!nm_device_sys_iface_state_is_external_or_assume (device)) { + teamd_cleanup (device, TRUE); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED); + } } } diff --git a/src/devices/tests/test-acd.c b/src/devices/tests/test-acd.c index aff71825..8b52ee2c 100644 --- a/src/devices/tests/test-acd.c +++ b/src/devices/tests/test-acd.c @@ -111,8 +111,8 @@ acd_manager_probe_terminated (NMAcdManager *acd_manager, gpointer user_data) static void test_acd_common (test_fixture *fixture, TestInfo *info) { - NMAcdManager *manager; - GMainLoop *loop; + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; int i; const guint WAIT_TIME_OPTIMISTIC = 50; guint wait_time; @@ -120,6 +120,7 @@ test_acd_common (test_fixture *fixture, TestInfo *info) .probe_terminated_callback = acd_manager_probe_terminated, .user_data_destroy = (GDestroyNotify) g_main_loop_unref, }; + int r; if (_skip_acd_test ()) return; @@ -131,8 +132,10 @@ test_acd_common (test_fixture *fixture, TestInfo *info) wait_time = WAIT_TIME_OPTIMISTIC; again: + nm_clear_pointer (&loop, g_main_loop_unref); loop = g_main_loop_new (NULL, FALSE); + nm_clear_pointer (&manager, nm_acd_manager_free); manager = nm_acd_manager_new (fixture->ifindex0, fixture->hwaddr0, fixture->hwaddr0_len, @@ -148,9 +151,10 @@ again: 24, 0, 3600, 1800, 0, NULL); } - g_assert (nm_acd_manager_start_probe (manager, wait_time)); + r = nm_acd_manager_start_probe (manager, wait_time); + g_assert_cmpint (r, ==, 0); + g_assert (nmtst_main_loop_run (loop, 2000)); - g_main_loop_unref (loop); for (i = 0; info->addresses[i]; i++) { gboolean val; @@ -164,7 +168,6 @@ again: /* probably we just had a glitch and the system took longer than * expected. Re-verify with a large timeout this time. */ wait_time = 1000; - nm_clear_pointer (&manager, nm_acd_manager_free); goto again; } @@ -172,8 +175,6 @@ again: i, nm_utils_inet4_ntop (info->addresses[i], sbuf), info->expected_result[i] ? "detect no duplicated" : "detect a duplicate"); } - - nm_acd_manager_free (manager); } static void @@ -199,8 +200,9 @@ test_acd_probe_2 (test_fixture *fixture, gconstpointer user_data) static void test_acd_announce (test_fixture *fixture, gconstpointer user_data) { - NMAcdManager *manager; - GMainLoop *loop; + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + int r; if (_skip_acd_test ()) return; @@ -216,11 +218,9 @@ test_acd_announce (test_fixture *fixture, gconstpointer user_data) g_assert (nm_acd_manager_add_address (manager, ADDR2)); loop = g_main_loop_new (NULL, FALSE); - nm_acd_manager_announce_addresses (manager); + r = nm_acd_manager_announce_addresses (manager); + g_assert_cmpint (r, ==, 0); g_assert (!nmtst_main_loop_run (loop, 200)); - g_main_loop_unref (loop); - - nm_acd_manager_free (manager); } static void diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c index 7227d082..7b135f58 100644 --- a/src/devices/tests/test-lldp.c +++ b/src/devices/tests/test-lldp.c @@ -231,8 +231,10 @@ TEST_RECV_FRAME_DEFINE (_test_recv_data1_frame0, static void _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) { - GVariant *neighbors, *attr; + GVariant *neighbors, *attr, *child; gs_unref_variant GVariant *neighbor = NULL; + guint v_uint = 0; + const char *v_str = NULL; neighbors = nm_lldp_listener_get_neighbors (listener); nmtst_assert_variant_is_of_type (neighbors, G_VARIANT_TYPE ("aa{sv}")); @@ -242,7 +244,7 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:30:F9:AD:A0", SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/1"); g_assert (neighbor); - g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 10); + g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 16); attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); nmtst_assert_variant_string (attr, NM_LLDP_DEST_NEAREST_BRIDGE); @@ -270,11 +272,49 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) nmtst_assert_variant_uint32 (attr, 20); nm_clear_g_variant (&attr); - /* unsupported: Management Address */ - /* unsupported: IEEE 802.3 - Power Via MDI */ - /* unsupported: IEEE 802.3 - MAC/PHY Configuration/Status */ + /* Management Address */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, G_VARIANT_TYPE ("aa{sv}")); + g_assert (attr); + g_assert_cmpuint (g_variant_n_children (attr), ==, 1); + child = g_variant_get_child_value (attr, 0); + g_assert (child); + g_variant_lookup (child, "interface-number", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 1001); + g_variant_lookup (child, "interface-number-subtype", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 2); + g_variant_lookup (child, "address-subtype", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 6); + nm_clear_g_variant (&child); + nm_clear_g_variant (&attr); + + /* IEEE 802.3 - Power Via MDI */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, G_VARIANT_TYPE_VARDICT); + g_assert (attr); + g_variant_lookup (attr, "mdi-power-support", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 7); + g_variant_lookup (attr, "pse-power-pair", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 1); + g_variant_lookup (attr, "power-class", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 0); + nm_clear_g_variant (&attr); + + /* IEEE 802.3 - MAC/PHY Configuration/Status */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, G_VARIANT_TYPE_VARDICT); + g_assert (attr); + g_variant_lookup (attr, "autoneg", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 3); + g_variant_lookup (attr, "pmd-autoneg-cap", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 0x6c00); + g_variant_lookup (attr, "operational-mau-type", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 16); + nm_clear_g_variant (&attr); + /* unsupported: IEEE 802.3 - Link Aggregation */ - /* unsupported: IEEE 802.3 - Maximum Frame Size*/ + + /* Maximum Frame Size */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32 (attr, 1522); + nm_clear_g_variant (&attr); /* IEEE 802.1 - Port VLAN ID */ attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PVID, G_VARIANT_TYPE_UINT32); @@ -289,6 +329,18 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) nmtst_assert_variant_uint32 (attr, 1); nm_clear_g_variant (&attr); + /* new PPVID attributes */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVIDS, G_VARIANT_TYPE ("aa{sv}")); + g_assert_cmpuint (g_variant_n_children (attr), ==, 1); + child = g_variant_get_child_value (attr, 0); + g_assert (child); + g_variant_lookup (child, "ppvid", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 0); + g_variant_lookup (child, "flags", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 1); + nm_clear_g_variant (&child); + nm_clear_g_variant (&attr); + /* IEEE 802.1 - VLAN Name */ attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, G_VARIANT_TYPE_STRING); nmtst_assert_variant_string (attr, "v2-0488-03-0505"); @@ -297,6 +349,18 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener) nmtst_assert_variant_uint32 (attr, 488); nm_clear_g_variant (&attr); + /* new VLAN attributes */ + attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLANS, G_VARIANT_TYPE ("aa{sv}")); + g_assert_cmpuint (g_variant_n_children (attr), ==, 1); + child = g_variant_get_child_value (attr, 0); + g_assert (child); + g_variant_lookup (child, "vid", "u", &v_uint); + g_assert_cmpint (v_uint, ==, 488); + g_variant_lookup (child, "name", "&s", &v_str); + g_assert_cmpstr (v_str, ==, "v2-0488-03-0505"); + nm_clear_g_variant (&child); + nm_clear_g_variant (&attr); + /* unsupported: IEEE 802.1 - Protocol Identity */ } diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index dcc161d2..da7d0685 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -22,7 +22,7 @@ #include "nm-device-iwd.h" -#include "nm-common-macros.h" +#include "nm-libnm-core-intern/nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-utils.h" @@ -39,7 +39,7 @@ #include "nm-config.h" #include "nm-iwd-manager.h" #include "nm-dbus-manager.h" -#include "nm-dbus-compat.h" +#include "nm-std-aux/nm-dbus-compat.h" #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceIwd); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 64869672..3a58c620 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -28,7 +28,7 @@ #include "nm-device-wifi-p2p.h" #include "nm-wifi-ap.h" -#include "nm-common-macros.h" +#include "nm-libnm-core-intern/nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-dbus-manager.h" diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index d668f0d8..494fca32 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -29,7 +29,7 @@ #include "nm-manager.h" #include "nm-device-iwd.h" #include "nm-wifi-utils.h" -#include "nm-utils/nm-random-utils.h" +#include "nm-glib-aux/nm-random-utils.h" #include "settings/nm-settings.h" /*****************************************************************************/ diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 1cb549b0..ffdc61a6 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -679,19 +679,6 @@ complete_connection (NMModem *_self, } if (MODEM_CAPS_3GPP (modem_caps)) { - NMSettingGsm *s_gsm; - - s_gsm = nm_connection_get_setting_gsm (connection); - if (!s_gsm) { - /* Need a GSM setting at least */ - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_SETTING, - _("GSM mobile broadband connection requires a 'gsm' setting")); - g_prefix_error (error, "%s: ", NM_SETTING_GSM_SETTING_NAME); - return FALSE; - } - nm_utils_complete_generic (NM_PLATFORM_GET, connection, NM_SETTING_GSM_SETTING_NAME, diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index fac14d69..4be089c0 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -32,7 +32,7 @@ #define sd_booted() FALSE #endif -#include "nm-dbus-compat.h" +#include "nm-std-aux/nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 2217f2a2..17794229 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -885,7 +885,7 @@ nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source) } property_name = NM_IS_SETTING_GSM (setting) ? "gsm.mtu" : "cdma.mtu"; - mtu_default = nm_device_get_configured_mtu_from_connection_default (self, property_name); + mtu_default = nm_device_get_configured_mtu_from_connection_default (self, property_name, G_MAXUINT32); if (mtu_default >= 0) { *out_source = NM_DEVICE_MTU_SOURCE_CONNECTION; return (guint32) mtu_default; |