// SPDX-License-Identifier: LGPL-2.1+
#include "nm-default.h"
#include "nm-libnm-core-utils.h"
#include "nm-common-macros.h"
#include <linux/rtnetlink.h>
/*****************************************************************************/
const char **
nm_utils_bond_option_arp_ip_targets_split (const char *arp_ip_target)
{
return nm_utils_strsplit_set_full (arp_ip_target, ",", NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
}
void
_nm_setting_bond_remove_options_miimon (NMSettingBond *s_bond)
{
g_return_if_fail (NM_IS_SETTING_BOND (s_bond));
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_MIIMON);
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY);
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY);
}
void
_nm_setting_bond_remove_options_arp_interval (NMSettingBond *s_bond)
{
g_return_if_fail (NM_IS_SETTING_BOND (s_bond));
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_ARP_INTERVAL);
nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_ARP_IP_TARGET);
}
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
_nm_setting_bond_mode_from_string,
NMBondMode,
{ g_return_val_if_fail (name, NM_BOND_MODE_UNKNOWN); },
{ return NM_BOND_MODE_UNKNOWN; },
{ "0", NM_BOND_MODE_ROUNDROBIN },
{ "1", NM_BOND_MODE_ACTIVEBACKUP },
{ "2", NM_BOND_MODE_XOR },
{ "3", NM_BOND_MODE_BROADCAST },
{ "4", NM_BOND_MODE_8023AD },
{ "5", NM_BOND_MODE_TLB },
{ "6", NM_BOND_MODE_ALB },
{ "802.3ad", NM_BOND_MODE_8023AD },
{ "active-backup", NM_BOND_MODE_ACTIVEBACKUP },
{ "balance-alb", NM_BOND_MODE_ALB },
{ "balance-rr", NM_BOND_MODE_ROUNDROBIN },
{ "balance-tlb", NM_BOND_MODE_TLB },
{ "balance-xor", NM_BOND_MODE_XOR },
{ "broadcast", NM_BOND_MODE_BROADCAST },
);
/*****************************************************************************/
gboolean
nm_utils_vlan_priority_map_parse_str (NMVlanPriorityMap map_type,
const char *str,
gboolean allow_wildcard_to,
guint32 *out_from,
guint32 *out_to,
gboolean *out_has_wildcard_to)
{
const char *s2;
gint64 v1, v2;
nm_assert (str);
s2 = strchr (str, ':');
if (!s2) {
if (!allow_wildcard_to)
return FALSE;
v1 = _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXUINT32, -1);
v2 = -1;
} else {
gs_free char *s1_free = NULL;
gsize s1_len = (s2 - str);
s2 = nm_str_skip_leading_spaces (&s2[1]);
if ( s2[0] == '\0'
|| ( s2[0] == '*'
&& NM_STRCHAR_ALL (&s2[1], ch, g_ascii_isspace (ch)))) {
if (!allow_wildcard_to)
return FALSE;
v2 = -1;
} else {
v2 = _nm_utils_ascii_str_to_int64 (s2, 10, 0, G_MAXUINT32, -1);
if ( v2 < 0
|| (guint32) v2 > nm_utils_vlan_priority_map_get_max_prio (map_type, FALSE))
return FALSE;
}
v1 = _nm_utils_ascii_str_to_int64 (nm_strndup_a (100, str, s1_len, &s1_free),
10, 0, G_MAXUINT32, -1);
}
if ( v1 < 0
|| (guint32) v1 > nm_utils_vlan_priority_map_get_max_prio (map_type, TRUE))
return FALSE;
NM_SET_OUT (out_from, v1);
NM_SET_OUT (out_to, v2 < 0
? 0u
: (guint) v2);
NM_SET_OUT (out_has_wildcard_to, v2 < 0);
return TRUE;
}
/*****************************************************************************/
const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST] = {
[NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK - 1] = NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX,
[NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN,
[NM_CLIENT_PERMISSION_NETWORK_CONTROL - 1] = NM_AUTH_PERMISSION_NETWORK_CONTROL,
[NM_CLIENT_PERMISSION_RELOAD - 1] = NM_AUTH_PERMISSION_RELOAD,
[NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS,
[NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME,
[NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN,
[NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM - 1] = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM,
[NM_CLIENT_PERMISSION_SLEEP_WAKE - 1] = NM_AUTH_PERMISSION_SLEEP_WAKE,
[NM_CLIENT_PERMISSION_WIFI_SCAN - 1] = NM_AUTH_PERMISSION_WIFI_SCAN,
[NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_OPEN,
[NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED - 1] = NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED,
};
const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST] = {
NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX,
NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN,
NM_CLIENT_PERMISSION_NETWORK_CONTROL,
NM_CLIENT_PERMISSION_RELOAD,
NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS,
NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME,
NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN,
NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM,
NM_CLIENT_PERMISSION_SLEEP_WAKE,
NM_CLIENT_PERMISSION_WIFI_SCAN,
NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN,
NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED,
};
const char *
nm_auth_permission_to_string (NMClientPermission permission)
{
if (permission < 1)
return NULL;
if (permission > NM_CLIENT_PERMISSION_LAST)
return NULL;
return nm_auth_permission_names_by_idx[permission - 1];
}
#define AUTH_PERMISSION_PREFIX "org.freedesktop.NetworkManager."
static int
_nm_auth_permission_from_string_cmp (gconstpointer a, gconstpointer b, gpointer user_data)
{
const NMClientPermission *const p = a;
const char *const needle = b;
const char *ss = nm_auth_permission_names_by_idx[*p - 1];
nm_assert (NM_STR_HAS_PREFIX (ss, AUTH_PERMISSION_PREFIX));
nm_assert (ss[NM_STRLEN (AUTH_PERMISSION_PREFIX)] != '\0');
return strcmp (&ss[NM_STRLEN (AUTH_PERMISSION_PREFIX)], needle);
}
NMClientPermission
nm_auth_permission_from_string (const char *str)
{
gssize idx;
if (!str)
return NM_CLIENT_PERMISSION_NONE;
if (!NM_STR_HAS_PREFIX (str, AUTH_PERMISSION_PREFIX))
return NM_CLIENT_PERMISSION_NONE;
idx = nm_utils_array_find_binary_search (nm_auth_permission_sorted,
sizeof (nm_auth_permission_sorted[0]),
G_N_ELEMENTS (nm_auth_permission_sorted),
&str[NM_STRLEN (AUTH_PERMISSION_PREFIX)],
_nm_auth_permission_from_string_cmp,
NULL);
if (idx < 0)
return NM_CLIENT_PERMISSION_NONE;
return nm_auth_permission_sorted[idx];
}
/*****************************************************************************/
NMClientPermissionResult
nm_client_permission_result_from_string (const char *nm)
{
if (!nm)
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
if (nm_streq (nm, "yes"))
return NM_CLIENT_PERMISSION_RESULT_YES;
if (nm_streq (nm, "no"))
return NM_CLIENT_PERMISSION_RESULT_NO;
if (nm_streq (nm, "auth"))
return NM_CLIENT_PERMISSION_RESULT_AUTH;
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
}
const char *
nm_client_permission_result_to_string (NMClientPermissionResult permission)
{
switch (permission) {
case NM_CLIENT_PERMISSION_RESULT_YES: return "yes";
case NM_CLIENT_PERMISSION_RESULT_NO: return "no";
case NM_CLIENT_PERMISSION_RESULT_AUTH: return "auth";
case NM_CLIENT_PERMISSION_RESULT_UNKNOWN: return "unknown";
}
nm_assert_not_reached ();
return NULL;
}
NM_UTILS_STRING_TABLE_LOOKUP_DEFINE (
nm_utils_route_type_by_name,
guint8,
{ nm_assert (name); },
{ return RTN_UNSPEC; },
{ "blackhole", RTN_BLACKHOLE },
{ "broadcast", RTN_BROADCAST },
{ "local", RTN_LOCAL },
{ "multicast", RTN_MULTICAST },
{ "nat", RTN_NAT },
{ "prohibit", RTN_PROHIBIT },
{ "throw", RTN_THROW },
{ "unicast", RTN_UNICAST },
{ "unreachable", RTN_UNREACHABLE },
);
NM_UTILS_ENUM2STR_DEFINE (nm_utils_route_type2str, guint8,
NM_UTILS_ENUM2STR (RTN_BLACKHOLE, "blackhole"),
NM_UTILS_ENUM2STR (RTN_BROADCAST, "broadcast"),
NM_UTILS_ENUM2STR (RTN_LOCAL, "local"),
NM_UTILS_ENUM2STR (RTN_MULTICAST, "multicast"),
NM_UTILS_ENUM2STR (RTN_NAT, "nat"),
NM_UTILS_ENUM2STR (RTN_PROHIBIT, "prohibit"),
NM_UTILS_ENUM2STR (RTN_THROW, "throw"),
NM_UTILS_ENUM2STR (RTN_UNICAST, "unicast"),
NM_UTILS_ENUM2STR (RTN_UNREACHABLE, "unreachable"),
NM_UTILS_ENUM2STR (RTN_UNSPEC, "unspecified"),
);