NetworkManager/src/core/NetworkManagerUtils.h
2023-02-23 09:12:43 +01:00

328 lines
15 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2004 - 2016 Red Hat, Inc.
* Copyright (C) 2005 - 2008 Novell, Inc.
*/
#ifndef __NETWORKMANAGER_UTILS_H__
#define __NETWORKMANAGER_UTILS_H__
#include "nm-core-utils.h"
#include "libnm-glib-aux/nm-dedup-multi.h"
#include "nm-setting-ip-config.h"
#include "nm-setting-ip6-config.h"
#include "libnm-platform/nm-platform.h"
/*****************************************************************************/
const char *nm_utils_get_ip_config_method(NMConnection *connection, int addr_family);
const char *nm_utils_get_shared_wifi_permission(NMConnection *connection);
void nm_utils_ppp_ip_methods_enabled(NMConnection *connection,
gboolean *out_ip4_enabled,
gboolean *out_ip6_enabled);
void _nm_utils_complete_generic_with_params(NMPlatform *platform,
NMConnection *connection,
const char *ctype,
NMConnection *const *existing_connections,
const char *preferred_id,
const char *fallback_id_prefix,
const char *ifname_prefix,
const char *ifname,
...) G_GNUC_NULL_TERMINATED;
#define nm_utils_complete_generic_with_params(platform, \
connection, \
ctype, \
existing_connections, \
preferred_id, \
fallback_id_prefix, \
ifname_prefix, \
ifname, \
...) \
_nm_utils_complete_generic_with_params(platform, \
connection, \
ctype, \
existing_connections, \
preferred_id, \
fallback_id_prefix, \
ifname_prefix, \
ifname, \
##__VA_ARGS__, \
NULL)
static inline void
nm_utils_complete_generic(NMPlatform *platform,
NMConnection *connection,
const char *ctype,
NMConnection *const *existing_connections,
const char *preferred_id,
const char *fallback_id_prefix,
const char *ifname_prefix,
const char *ifname,
gboolean default_enable_ipv6)
{
nm_utils_complete_generic_with_params(platform,
connection,
ctype,
existing_connections,
preferred_id,
fallback_id_prefix,
ifname_prefix,
ifname,
NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD,
default_enable_ipv6
? NM_SETTING_IP6_CONFIG_METHOD_AUTO
: NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
}
typedef gboolean(NMUtilsMatchFilterFunc)(NMConnection *connection, gpointer user_data);
NMConnection *nm_utils_match_connection(NMConnection *const *connections,
NMConnection *original,
gboolean indicated,
gboolean device_has_carrier,
gint64 default_v4_metric,
gint64 default_v6_metric,
NMUtilsMatchFilterFunc match_filter_func,
gpointer match_filter_data);
int nm_match_spec_device_by_pllink(const NMPlatformLink *pllink,
const char *match_device_type,
const char *match_dhcp_plugin,
const GSList *specs,
int no_match_value);
/*****************************************************************************/
NMPlatformRoutingRule *nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule,
NMPlatformRoutingRule *out_pl);
/*****************************************************************************/
/* during shutdown, there are two relevant timeouts. One is
* NM_SHUTDOWN_TIMEOUT_MAX_MSEC which is plenty of time, that we give for all
* actions to complete. Of course, during shutdown components should hurry
* to cleanup.
*
* When we initiate shutdown, we should start killing child processes
* with SIGTERM. If they don't complete within NM_SHUTDOWN_TIMEOUT_MAX_MSEC, we send
* SIGKILL.
*
* After NM_SHUTDOWN_TIMEOUT_MAX_MSEC, NetworkManager will however not yet terminate right
* away. It iterates the mainloop for another NM_SHUTDOWN_TIMEOUT_ADDITIONAL_MSEC. This
* should give time to reap the child process (after SIGKILL).
*
* So, the maximum time we should wait before sending SIGKILL should be at most
* NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
*/
#define NM_SHUTDOWN_TIMEOUT_MAX_MSEC 5000
#define NM_SHUTDOWN_TIMEOUT_ADDITIONAL_MSEC 500
/**
* NM_SHUTDOWN_TIMEOUT_1500_MSEC: this is just 1500 msec. The special
* thing about the define is that you are guaranteed that this is not
* longer than NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
* When you perform an async operation, it must either be cancellable
* (and complete fast) or never take longer than NM_SHUTDOWN_TIMEOUT_MAX_MSEC.
* The usage of this macro makes that relation to NM_SHUTDOWN_TIMEOUT_MAX_MSEC
* explicit.
*/
#define NM_SHUTDOWN_TIMEOUT_1500_MSEC 1500
/* See NM_SHUTDOWN_TIMEOUT_1500_MSEC. */
#define NM_SHUTDOWN_TIMEOUT_5000_MSEC 5000
typedef enum {
/* There is no watched_obj argument, and the shutdown is delayed until the user
* explicitly calls unregister on the returned handle. */
NM_SHUTDOWN_WAIT_TYPE_HANDLE,
/* The watched_obj argument is a GObject, and shutdown is delayed until the object
* gets destroyed (or unregistered). */
NM_SHUTDOWN_WAIT_TYPE_OBJECT,
/* The watched_obj argument is a GCancellable, and shutdown is delayed until the object
* gets destroyed (or unregistered). Note that after NM_SHUTDOWN_TIMEOUT_MAX_MSEC, the
* cancellable will be cancelled to notify listeners about the shutdown. */
NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE,
} NMShutdownWaitType;
typedef struct _NMShutdownWaitObjHandle NMShutdownWaitObjHandle;
NMShutdownWaitObjHandle *nm_shutdown_wait_obj_register_full(gpointer watched_obj,
NMShutdownWaitType wait_type,
char *msg_reason,
gboolean free_msg_reason);
static inline NMShutdownWaitObjHandle *
nm_shutdown_wait_obj_register_object_full(gpointer watched_obj,
char *msg_reason,
gboolean free_msg_reason)
{
return nm_shutdown_wait_obj_register_full(watched_obj,
NM_SHUTDOWN_WAIT_TYPE_OBJECT,
msg_reason,
free_msg_reason);
}
#define nm_shutdown_wait_obj_register_object(watched_obj, msg_reason) \
nm_shutdown_wait_obj_register_object_full((watched_obj), ("" msg_reason ""), FALSE)
static inline NMShutdownWaitObjHandle *
nm_shutdown_wait_obj_register_handle_full(char *msg_reason, gboolean free_msg_reason)
{
return nm_shutdown_wait_obj_register_full(NULL,
NM_SHUTDOWN_WAIT_TYPE_HANDLE,
msg_reason,
free_msg_reason);
}
#define nm_shutdown_wait_obj_register_handle(msg_reason) \
nm_shutdown_wait_obj_register_handle_full(("" msg_reason ""), FALSE)
static inline NMShutdownWaitObjHandle *
nm_shutdown_wait_obj_register_cancellable_full(GCancellable *watched_obj,
char *msg_reason,
gboolean free_msg_reason)
{
return nm_shutdown_wait_obj_register_full(watched_obj,
NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE,
msg_reason,
free_msg_reason);
}
#define nm_shutdown_wait_obj_register_cancellable(watched_obj, msg_reason) \
nm_shutdown_wait_obj_register_cancellable_full((watched_obj), ("" msg_reason ""), FALSE)
void nm_shutdown_wait_obj_unregister(NMShutdownWaitObjHandle *handle);
/*****************************************************************************/
const char *nm_utils_file_is_in_path(const char *abs_filename, const char *abs_path);
/*****************************************************************************/
GPtrArray *
nm_utils_qdiscs_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, int ip_ifindex);
GPtrArray *
nm_utils_tfilters_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, int ip_ifindex);
void nm_utils_ip_route_attribute_to_platform(int addr_family,
NMIPRoute *s_route,
NMPlatformIPRoute *r,
gint64 route_table);
void nm_utils_ip_addresses_to_dbus(int addr_family,
const NMDedupMultiHeadEntry *head_entry,
const NMPObject *best_default_route,
GVariant **out_address_data,
GVariant **out_addresses);
void nm_utils_ip_routes_to_dbus(int addr_family,
const NMDedupMultiHeadEntry *head_entry,
GVariant **out_route_data,
GVariant **out_routes);
/*****************************************************************************/
typedef enum _nm_packed {
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE = 0,
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST = (1LL << 0),
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED = (1LL << 1),
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS = (1LL << 2),
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_ALL =
(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST
| NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED
| NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS),
} NMSettingsAutoconnectBlockedReason;
const char *
nm_settings_autoconnect_blocked_reason_to_string(NMSettingsAutoconnectBlockedReason reason,
char *buf,
gsize len);
/*****************************************************************************/
/* For now, all we track about a DHCP lease is the GHashTable with
* the options.
*
* We don't add a separate type for that, but we also don't want to use
* GHashTable directly (because most importantly leases should be immutable
* and passing a GHashTable pointer around neither makes it clear that
* this is a lease nor that it's immutable.
*
* Instead, add a simple opaque pointer and accessors that cast to a GHashTable.
*
* It has no overhead at run time, but gives some rudimentary type safety. */
typedef struct _NMDhcpLease NMDhcpLease;
static inline NMDhcpLease *
nm_dhcp_lease_new_from_options(GHashTable *options_take)
{
/* a NMDhcpLease is really just a GHashTable. But it's also supposed to be *immutable*.
*
* Hence, the API here takes over ownership of the reference to @options_take, that
* is to emphasize that we acquire ownership of the hash, and it should not be modified
* anymore. */
return (NMDhcpLease *) options_take;
}
static inline GHashTable *
nm_dhcp_lease_get_options(NMDhcpLease *lease)
{
return (GHashTable *) lease;
}
static inline NMDhcpLease *
nm_dhcp_lease_ref(NMDhcpLease *lease)
{
if (lease)
g_hash_table_ref((GHashTable *) lease);
return lease;
}
static inline NMDhcpLease *
nm_dhcp_lease_unref(NMDhcpLease *lease)
{
if (lease)
g_hash_table_unref((GHashTable *) lease);
return NULL;
}
static inline const char *
nm_dhcp_lease_lookup_option(NMDhcpLease *lease, const char *option)
{
nm_assert(option);
return nm_g_hash_table_lookup((GHashTable *) lease, option);
}
NM_AUTO_DEFINE_FCN(NMDhcpLease *, _nm_auto_unref_dhcplease, nm_dhcp_lease_unref);
#define nm_auto_unref_dhcplease nm_auto(_nm_auto_unref_dhcplease)
/*****************************************************************************/
NMSetting *nm_utils_platform_capture_ip_setting(NMPlatform *platform,
int addr_family,
int ifindex,
gboolean maybe_ipv6_disabled);
/*****************************************************************************/
void nm_platform_setup(NMPlatform *instance);
NMPlatform *nm_platform_get(void);
#define NM_PLATFORM_GET (nm_platform_get())
void nm_linux_platform_setup(void);
void nm_linux_platform_setup_with_tc_cache(void);
/*****************************************************************************/
#endif /* __NETWORKMANAGER_UTILS_H__ */