diff options
Diffstat (limited to 'src/platform')
27 files changed, 1375 insertions, 4727 deletions
diff --git a/src/platform/linux/nl802154.h b/src/platform/linux/nl802154.h deleted file mode 100644 index ddcee128..00000000 --- a/src/platform/linux/nl802154.h +++ /dev/null @@ -1,452 +0,0 @@ -#ifndef __NL802154_H -#define __NL802154_H -/* - * 802.15.4 netlink interface public header - * - * Copyright 2014 Alexander Aring <aar@pengutronix.de> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#define NL802154_GENL_NAME "nl802154" - -enum nl802154_commands { -/* don't change the order or add anything between, this is ABI! */ -/* currently we don't shipping this file via uapi, ignore the above one */ - NL802154_CMD_UNSPEC, - - NL802154_CMD_GET_WPAN_PHY, /* can dump */ - NL802154_CMD_SET_WPAN_PHY, - NL802154_CMD_NEW_WPAN_PHY, - NL802154_CMD_DEL_WPAN_PHY, - - NL802154_CMD_GET_INTERFACE, /* can dump */ - NL802154_CMD_SET_INTERFACE, - NL802154_CMD_NEW_INTERFACE, - NL802154_CMD_DEL_INTERFACE, - - NL802154_CMD_SET_CHANNEL, - - NL802154_CMD_SET_PAN_ID, - NL802154_CMD_SET_SHORT_ADDR, - - NL802154_CMD_SET_TX_POWER, - NL802154_CMD_SET_CCA_MODE, - NL802154_CMD_SET_CCA_ED_LEVEL, - - NL802154_CMD_SET_MAX_FRAME_RETRIES, - - NL802154_CMD_SET_BACKOFF_EXPONENT, - NL802154_CMD_SET_MAX_CSMA_BACKOFFS, - - NL802154_CMD_SET_LBT_MODE, - - NL802154_CMD_SET_ACKREQ_DEFAULT, - - NL802154_CMD_SET_WPAN_PHY_NETNS, - - /* add new commands above here */ - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - NL802154_CMD_SET_SEC_PARAMS, - NL802154_CMD_GET_SEC_KEY, /* can dump */ - NL802154_CMD_NEW_SEC_KEY, - NL802154_CMD_DEL_SEC_KEY, - NL802154_CMD_GET_SEC_DEV, /* can dump */ - NL802154_CMD_NEW_SEC_DEV, - NL802154_CMD_DEL_SEC_DEV, - NL802154_CMD_GET_SEC_DEVKEY, /* can dump */ - NL802154_CMD_NEW_SEC_DEVKEY, - NL802154_CMD_DEL_SEC_DEVKEY, - NL802154_CMD_GET_SEC_LEVEL, /* can dump */ - NL802154_CMD_NEW_SEC_LEVEL, - NL802154_CMD_DEL_SEC_LEVEL, -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - - /* used to define NL802154_CMD_MAX below */ - __NL802154_CMD_AFTER_LAST, - NL802154_CMD_MAX = __NL802154_CMD_AFTER_LAST - 1 -}; - -enum nl802154_attrs { -/* don't change the order or add anything between, this is ABI! */ -/* currently we don't shipping this file via uapi, ignore the above one */ - NL802154_ATTR_UNSPEC, - - NL802154_ATTR_WPAN_PHY, - NL802154_ATTR_WPAN_PHY_NAME, - - NL802154_ATTR_IFINDEX, - NL802154_ATTR_IFNAME, - NL802154_ATTR_IFTYPE, - - NL802154_ATTR_WPAN_DEV, - - NL802154_ATTR_PAGE, - NL802154_ATTR_CHANNEL, - - NL802154_ATTR_PAN_ID, - NL802154_ATTR_SHORT_ADDR, - - NL802154_ATTR_TX_POWER, - - NL802154_ATTR_CCA_MODE, - NL802154_ATTR_CCA_OPT, - NL802154_ATTR_CCA_ED_LEVEL, - - NL802154_ATTR_MAX_FRAME_RETRIES, - - NL802154_ATTR_MAX_BE, - NL802154_ATTR_MIN_BE, - NL802154_ATTR_MAX_CSMA_BACKOFFS, - - NL802154_ATTR_LBT_MODE, - - NL802154_ATTR_GENERATION, - - NL802154_ATTR_CHANNELS_SUPPORTED, - NL802154_ATTR_SUPPORTED_CHANNEL, - - NL802154_ATTR_EXTENDED_ADDR, - - NL802154_ATTR_WPAN_PHY_CAPS, - - NL802154_ATTR_SUPPORTED_COMMANDS, - - NL802154_ATTR_ACKREQ_DEFAULT, - - NL802154_ATTR_PAD, - - NL802154_ATTR_PID, - NL802154_ATTR_NETNS_FD, - - /* add attributes here, update the policy in nl802154.c */ - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - NL802154_ATTR_SEC_ENABLED, - NL802154_ATTR_SEC_OUT_LEVEL, - NL802154_ATTR_SEC_OUT_KEY_ID, - NL802154_ATTR_SEC_FRAME_COUNTER, - - NL802154_ATTR_SEC_LEVEL, - NL802154_ATTR_SEC_DEVICE, - NL802154_ATTR_SEC_DEVKEY, - NL802154_ATTR_SEC_KEY, -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - - __NL802154_ATTR_AFTER_LAST, - NL802154_ATTR_MAX = __NL802154_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_iftype { - /* for backwards compatibility TODO */ - NL802154_IFTYPE_UNSPEC = -1, - - NL802154_IFTYPE_NODE, - NL802154_IFTYPE_MONITOR, - NL802154_IFTYPE_COORD, - - /* keep last */ - NUM_NL802154_IFTYPES, - NL802154_IFTYPE_MAX = NUM_NL802154_IFTYPES - 1 -}; - -/** - * enum nl802154_wpan_phy_capability_attr - wpan phy capability attributes - * - * @__NL802154_CAP_ATTR_INVALID: attribute number 0 is reserved - * @NL802154_CAP_ATTR_CHANNELS: a nested attribute for nl802154_channel_attr - * @NL802154_CAP_ATTR_TX_POWERS: a nested attribute for - * nl802154_wpan_phy_tx_power - * @NL802154_CAP_ATTR_MIN_CCA_ED_LEVEL: minimum value for cca_ed_level - * @NL802154_CAP_ATTR_MAX_CCA_ED_LEVEL: maxmimum value for cca_ed_level - * @NL802154_CAP_ATTR_CCA_MODES: nl802154_cca_modes flags - * @NL802154_CAP_ATTR_CCA_OPTS: nl802154_cca_opts flags - * @NL802154_CAP_ATTR_MIN_MINBE: minimum of minbe value - * @NL802154_CAP_ATTR_MAX_MINBE: maximum of minbe value - * @NL802154_CAP_ATTR_MIN_MAXBE: minimum of maxbe value - * @NL802154_CAP_ATTR_MAX_MINBE: maximum of maxbe value - * @NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS: minimum of csma backoff value - * @NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS: maximum of csma backoffs value - * @NL802154_CAP_ATTR_MIN_FRAME_RETRIES: minimum of frame retries value - * @NL802154_CAP_ATTR_MAX_FRAME_RETRIES: maximum of frame retries value - * @NL802154_CAP_ATTR_IFTYPES: nl802154_iftype flags - * @NL802154_CAP_ATTR_LBT: nl802154_supported_bool_states flags - * @NL802154_CAP_ATTR_MAX: highest cap attribute currently defined - * @__NL802154_CAP_ATTR_AFTER_LAST: internal use - */ -enum nl802154_wpan_phy_capability_attr { - __NL802154_CAP_ATTR_INVALID, - - NL802154_CAP_ATTR_IFTYPES, - - NL802154_CAP_ATTR_CHANNELS, - NL802154_CAP_ATTR_TX_POWERS, - - NL802154_CAP_ATTR_CCA_ED_LEVELS, - NL802154_CAP_ATTR_CCA_MODES, - NL802154_CAP_ATTR_CCA_OPTS, - - NL802154_CAP_ATTR_MIN_MINBE, - NL802154_CAP_ATTR_MAX_MINBE, - - NL802154_CAP_ATTR_MIN_MAXBE, - NL802154_CAP_ATTR_MAX_MAXBE, - - NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS, - NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS, - - NL802154_CAP_ATTR_MIN_FRAME_RETRIES, - NL802154_CAP_ATTR_MAX_FRAME_RETRIES, - - NL802154_CAP_ATTR_LBT, - - /* keep last */ - __NL802154_CAP_ATTR_AFTER_LAST, - NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_cca_modes - cca modes - * - * @__NL802154_CCA_INVALID: cca mode number 0 is reserved - * @NL802154_CCA_ENERGY: Energy above threshold - * @NL802154_CCA_CARRIER: Carrier sense only - * @NL802154_CCA_ENERGY_CARRIER: Carrier sense with energy above threshold - * @NL802154_CCA_ALOHA: CCA shall always report an idle medium - * @NL802154_CCA_UWB_SHR: UWB preamble sense based on the SHR of a frame - * @NL802154_CCA_UWB_MULTIPLEXED: UWB preamble sense based on the packet with - * the multiplexed preamble - * @__NL802154_CCA_ATTR_AFTER_LAST: Internal - * @NL802154_CCA_ATTR_MAX: Maximum CCA attribute number - */ -enum nl802154_cca_modes { - __NL802154_CCA_INVALID, - NL802154_CCA_ENERGY, - NL802154_CCA_CARRIER, - NL802154_CCA_ENERGY_CARRIER, - NL802154_CCA_ALOHA, - NL802154_CCA_UWB_SHR, - NL802154_CCA_UWB_MULTIPLEXED, - - /* keep last */ - __NL802154_CCA_ATTR_AFTER_LAST, - NL802154_CCA_ATTR_MAX = __NL802154_CCA_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_cca_opts - additional options for cca modes - * - * @NL802154_CCA_OPT_ENERGY_CARRIER_OR: NL802154_CCA_ENERGY_CARRIER with OR - * @NL802154_CCA_OPT_ENERGY_CARRIER_AND: NL802154_CCA_ENERGY_CARRIER with AND - */ -enum nl802154_cca_opts { - NL802154_CCA_OPT_ENERGY_CARRIER_AND, - NL802154_CCA_OPT_ENERGY_CARRIER_OR, - - /* keep last */ - __NL802154_CCA_OPT_ATTR_AFTER_LAST, - NL802154_CCA_OPT_ATTR_MAX = __NL802154_CCA_OPT_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_supported_bool_states - bool states for bool capability entry - * - * @NL802154_SUPPORTED_BOOL_FALSE: indicates to set false - * @NL802154_SUPPORTED_BOOL_TRUE: indicates to set true - * @__NL802154_SUPPORTED_BOOL_INVALD: reserved - * @NL802154_SUPPORTED_BOOL_BOTH: indicates to set true and false - * @__NL802154_SUPPORTED_BOOL_AFTER_LAST: Internal - * @NL802154_SUPPORTED_BOOL_MAX: highest value for bool states - */ -enum nl802154_supported_bool_states { - NL802154_SUPPORTED_BOOL_FALSE, - NL802154_SUPPORTED_BOOL_TRUE, - /* to handle them in a mask */ - __NL802154_SUPPORTED_BOOL_INVALD, - NL802154_SUPPORTED_BOOL_BOTH, - - /* keep last */ - __NL802154_SUPPORTED_BOOL_AFTER_LAST, - NL802154_SUPPORTED_BOOL_MAX = __NL802154_SUPPORTED_BOOL_AFTER_LAST - 1 -}; - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - -enum nl802154_dev_addr_modes { - NL802154_DEV_ADDR_NONE, - __NL802154_DEV_ADDR_INVALID, - NL802154_DEV_ADDR_SHORT, - NL802154_DEV_ADDR_EXTENDED, - - /* keep last */ - __NL802154_DEV_ADDR_AFTER_LAST, - NL802154_DEV_ADDR_MAX = __NL802154_DEV_ADDR_AFTER_LAST - 1 -}; - -enum nl802154_dev_addr_attrs { - NL802154_DEV_ADDR_ATTR_UNSPEC, - - NL802154_DEV_ADDR_ATTR_PAN_ID, - NL802154_DEV_ADDR_ATTR_MODE, - NL802154_DEV_ADDR_ATTR_SHORT, - NL802154_DEV_ADDR_ATTR_EXTENDED, - NL802154_DEV_ADDR_ATTR_PAD, - - /* keep last */ - __NL802154_DEV_ADDR_ATTR_AFTER_LAST, - NL802154_DEV_ADDR_ATTR_MAX = __NL802154_DEV_ADDR_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_key_id_modes { - NL802154_KEY_ID_MODE_IMPLICIT, - NL802154_KEY_ID_MODE_INDEX, - NL802154_KEY_ID_MODE_INDEX_SHORT, - NL802154_KEY_ID_MODE_INDEX_EXTENDED, - - /* keep last */ - __NL802154_KEY_ID_MODE_AFTER_LAST, - NL802154_KEY_ID_MODE_MAX = __NL802154_KEY_ID_MODE_AFTER_LAST - 1 -}; - -enum nl802154_key_id_attrs { - NL802154_KEY_ID_ATTR_UNSPEC, - - NL802154_KEY_ID_ATTR_MODE, - NL802154_KEY_ID_ATTR_INDEX, - NL802154_KEY_ID_ATTR_IMPLICIT, - NL802154_KEY_ID_ATTR_SOURCE_SHORT, - NL802154_KEY_ID_ATTR_SOURCE_EXTENDED, - NL802154_KEY_ID_ATTR_PAD, - - /* keep last */ - __NL802154_KEY_ID_ATTR_AFTER_LAST, - NL802154_KEY_ID_ATTR_MAX = __NL802154_KEY_ID_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_seclevels { - NL802154_SECLEVEL_NONE, - NL802154_SECLEVEL_MIC32, - NL802154_SECLEVEL_MIC64, - NL802154_SECLEVEL_MIC128, - NL802154_SECLEVEL_ENC, - NL802154_SECLEVEL_ENC_MIC32, - NL802154_SECLEVEL_ENC_MIC64, - NL802154_SECLEVEL_ENC_MIC128, - - /* keep last */ - __NL802154_SECLEVEL_AFTER_LAST, - NL802154_SECLEVEL_MAX = __NL802154_SECLEVEL_AFTER_LAST - 1 -}; - -enum nl802154_frames { - NL802154_FRAME_BEACON, - NL802154_FRAME_DATA, - NL802154_FRAME_ACK, - NL802154_FRAME_CMD, - - /* keep last */ - __NL802154_FRAME_AFTER_LAST, - NL802154_FRAME_MAX = __NL802154_FRAME_AFTER_LAST - 1 -}; - -enum nl802154_cmd_frames { - __NL802154_CMD_FRAME_INVALID, - NL802154_CMD_FRAME_ASSOC_REQUEST, - NL802154_CMD_FRAME_ASSOC_RESPONSE, - NL802154_CMD_FRAME_DISASSOC_NOTIFY, - NL802154_CMD_FRAME_DATA_REQUEST, - NL802154_CMD_FRAME_PAN_ID_CONFLICT_NOTIFY, - NL802154_CMD_FRAME_ORPHAN_NOTIFY, - NL802154_CMD_FRAME_BEACON_REQUEST, - NL802154_CMD_FRAME_COORD_REALIGNMENT, - NL802154_CMD_FRAME_GTS_REQUEST, - - /* keep last */ - __NL802154_CMD_FRAME_AFTER_LAST, - NL802154_CMD_FRAME_MAX = __NL802154_CMD_FRAME_AFTER_LAST - 1 -}; - -enum nl802154_seclevel_attrs { - NL802154_SECLEVEL_ATTR_UNSPEC, - - NL802154_SECLEVEL_ATTR_LEVELS, - NL802154_SECLEVEL_ATTR_FRAME, - NL802154_SECLEVEL_ATTR_CMD_FRAME, - NL802154_SECLEVEL_ATTR_DEV_OVERRIDE, - - /* keep last */ - __NL802154_SECLEVEL_ATTR_AFTER_LAST, - NL802154_SECLEVEL_ATTR_MAX = __NL802154_SECLEVEL_ATTR_AFTER_LAST - 1 -}; - -/* TODO what is this? couldn't find in mib */ -enum { - NL802154_DEVKEY_IGNORE, - NL802154_DEVKEY_RESTRICT, - NL802154_DEVKEY_RECORD, - - /* keep last */ - __NL802154_DEVKEY_AFTER_LAST, - NL802154_DEVKEY_MAX = __NL802154_DEVKEY_AFTER_LAST - 1 -}; - -enum nl802154_dev { - NL802154_DEV_ATTR_UNSPEC, - - NL802154_DEV_ATTR_FRAME_COUNTER, - NL802154_DEV_ATTR_PAN_ID, - NL802154_DEV_ATTR_SHORT_ADDR, - NL802154_DEV_ATTR_EXTENDED_ADDR, - NL802154_DEV_ATTR_SECLEVEL_EXEMPT, - NL802154_DEV_ATTR_KEY_MODE, - NL802154_DEV_ATTR_PAD, - - /* keep last */ - __NL802154_DEV_ATTR_AFTER_LAST, - NL802154_DEV_ATTR_MAX = __NL802154_DEV_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_devkey { - NL802154_DEVKEY_ATTR_UNSPEC, - - NL802154_DEVKEY_ATTR_FRAME_COUNTER, - NL802154_DEVKEY_ATTR_EXTENDED_ADDR, - NL802154_DEVKEY_ATTR_ID, - NL802154_DEVKEY_ATTR_PAD, - - /* keep last */ - __NL802154_DEVKEY_ATTR_AFTER_LAST, - NL802154_DEVKEY_ATTR_MAX = __NL802154_DEVKEY_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_key { - NL802154_KEY_ATTR_UNSPEC, - - NL802154_KEY_ATTR_ID, - NL802154_KEY_ATTR_USAGE_FRAMES, - NL802154_KEY_ATTR_USAGE_CMDS, - NL802154_KEY_ATTR_BYTES, - - /* keep last */ - __NL802154_KEY_ATTR_AFTER_LAST, - NL802154_KEY_ATTR_MAX = __NL802154_KEY_ATTR_AFTER_LAST - 1 -}; - -#define NL802154_KEY_SIZE 16 -#define NL802154_CMD_FRAME_NR_IDS 256 - -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - -#endif /* __NL802154_H */ diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 82f9e2fb..f8f4627e 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -602,6 +602,12 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) return NM_PLATFORM_ERROR_SUCCESS; } +static gboolean +link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) +{ + return TRUE; +} + static const char * link_get_udi (NMPlatform *platform, int ifindex) { @@ -887,6 +893,12 @@ wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) return FALSE; } +static GByteArray * +wifi_get_ssid (NMPlatform *platform, int ifindex) +{ + return NULL; +} + static guint32 wifi_get_frequency (NMPlatform *platform, int ifindex) { @@ -1410,6 +1422,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->link_set_address = link_set_address; platform_class->link_set_mtu = link_set_mtu; + platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; platform_class->link_get_driver_info = link_get_driver_info; @@ -1429,6 +1442,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->wifi_get_capabilities = wifi_get_capabilities; platform_class->wifi_get_bssid = wifi_get_bssid; + platform_class->wifi_get_ssid = wifi_get_ssid; platform_class->wifi_get_frequency = wifi_get_frequency; platform_class->wifi_get_quality = wifi_get_quality; platform_class->wifi_get_rate = wifi_get_rate; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e73d5d8c..9bd662a1 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 - 2018 Red Hat, Inc. + * Copyright (C) 2012 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -44,18 +44,15 @@ #include "nm-core-internal.h" #include "nm-setting-vlan.h" -#include "nm-utils/nm-secret-utils.h" #include "nm-netlink.h" #include "nm-core-utils.h" #include "nmp-object.h" #include "nmp-netns.h" #include "nm-platform-utils.h" #include "nm-platform-private.h" -#include "wifi/nm-wifi-utils.h" -#include "wifi/nm-wifi-utils-wext.h" -#include "wpan/nm-wpan-utils.h" +#include "wifi/wifi-utils.h" +#include "wifi/wifi-utils-wext.h" #include "nm-utils/unaligned.h" -#include "nm-utils/nm-io-utils.h" #include "nm-utils/nm-udev-utils.h" /*****************************************************************************/ @@ -157,13 +154,6 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1)); /*****************************************************************************/ -/* Appeared in in kernel prior to 3.13 dated 19 January, 2014 */ -#ifndef ARPHRD_6LOWPAN -#define ARPHRD_6LOWPAN 825 -#endif - -/*****************************************************************************/ - #define IFLA_MACSEC_UNSPEC 0 #define IFLA_MACSEC_SCI 1 #define IFLA_MACSEC_PORT 2 @@ -183,79 +173,63 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1)); /*****************************************************************************/ -#define WG_CMD_GET_DEVICE 0 -#define WG_CMD_SET_DEVICE 1 - -#define WGDEVICE_A_UNSPEC 0 -#define WGDEVICE_A_IFINDEX 1 -#define WGDEVICE_A_IFNAME 2 -#define WGDEVICE_A_PRIVATE_KEY 3 -#define WGDEVICE_A_PUBLIC_KEY 4 -#define WGDEVICE_A_FLAGS 5 -#define WGDEVICE_A_LISTEN_PORT 6 -#define WGDEVICE_A_FWMARK 7 -#define WGDEVICE_A_PEERS 8 -#define WGDEVICE_A_MAX 8 - -#define WGPEER_A_UNSPEC 0 -#define WGPEER_A_PUBLIC_KEY 1 -#define WGPEER_A_PRESHARED_KEY 2 -#define WGPEER_A_FLAGS 3 -#define WGPEER_A_ENDPOINT 4 -#define WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL 5 -#define WGPEER_A_LAST_HANDSHAKE_TIME 6 -#define WGPEER_A_RX_BYTES 7 -#define WGPEER_A_TX_BYTES 8 -#define WGPEER_A_ALLOWEDIPS 9 -#define WGPEER_A_MAX 9 - -#define WGALLOWEDIP_A_UNSPEC 0 -#define WGALLOWEDIP_A_FAMILY 1 -#define WGALLOWEDIP_A_IPADDR 2 -#define WGALLOWEDIP_A_CIDR_MASK 3 -#define WGALLOWEDIP_A_MAX 3 +#define _NMLOG_PREFIX_NAME "platform-linux" +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG2_DOMAIN LOGD_PLATFORM +#define _NMLOG(level, ...) _LOG ( level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG2(level, ...) _LOG ( level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) +#define _NMLOG2_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) -/*****************************************************************************/ +#define _LOG_print(__level, __domain, __errsv, self, ...) \ + G_STMT_START { \ + char __prefix[32]; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ + NMPlatform *const __self = (self); \ + \ + if (__self && nm_platform_get_log_with_ptr (__self)) { \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log (__level, __domain, __errsv, NULL, NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ + __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + } G_STMT_END -/* Redefine VF enums and structures that are not available on older kernels. */ - -#define IFLA_VF_UNSPEC 0 -#define IFLA_VF_MAC 1 -#define IFLA_VF_VLAN 2 -#define IFLA_VF_TX_RATE 3 -#define IFLA_VF_SPOOFCHK 4 -#define IFLA_VF_LINK_STATE 5 -#define IFLA_VF_RATE 6 -#define IFLA_VF_RSS_QUERY_EN 7 -#define IFLA_VF_STATS 8 -#define IFLA_VF_TRUST 9 -#define IFLA_VF_IB_NODE_GUID 10 -#define IFLA_VF_IB_PORT_GUID 11 -#define IFLA_VF_VLAN_LIST 12 - -#define IFLA_VF_VLAN_INFO_UNSPEC 0 -#define IFLA_VF_VLAN_INFO 1 - -/* valid for TRUST, SPOOFCHK, LINK_STATE, RSS_QUERY_EN */ -struct _ifla_vf_setting { - guint32 vf; - guint32 setting; -}; +#define _LOG(level, domain, self, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled (__level, __domain)) { \ + _LOG_print (__level, __domain, 0, self, __VA_ARGS__); \ + } \ + } G_STMT_END -struct _ifla_vf_rate { - guint32 vf; - guint32 min_tx_rate; - guint32 max_tx_rate; -}; +#define _LOG_err(errsv, level, domain, self, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled (__level, __domain)) { \ + int __errsv = (errsv); \ + \ + /* The %m format specifier (GNU extension) would alread allow you to specify the error + * message conveniently (and nm_log would get that right too). But we don't want to depend + * on that, so instead append the message at the end. + * Currently users are expected not to use %m in the format string. */ \ + _LOG_print (__level, __domain, __errsv, self, \ + _NM_UTILS_MACRO_FIRST (__VA_ARGS__) ": %s (%d)" \ + _NM_UTILS_MACRO_REST (__VA_ARGS__), \ + g_strerror (__errsv), __errsv); \ + } \ + } G_STMT_END -struct _ifla_vf_vlan_info { - guint32 vf; - guint32 vlan; /* 0 - 4095, 0 disables VLAN filter */ - guint32 qos; - guint16 vlan_proto; /* VLAN protocol, either 802.1Q or 802.1ad */ -}; +#define LOG_FMT_IP_TUNNEL "adding %s '%s' parent %u local %s remote %s" -/*****************************************************************************/ +/****************************************************************** + * Forward declarations and enums + ******************************************************************/ typedef enum { INFINIBAND_ACTION_CREATE_CHILD, @@ -333,133 +307,6 @@ typedef enum { WAIT_FOR_NL_RESPONSE_RESULT_FAILED_SETNS, } WaitForNlResponseResult; -typedef enum { - DELAYED_ACTION_RESPONSE_TYPE_VOID = 0, - DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS = 1, - DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET = 2, -} DelayedActionWaitForNlResponseType; - -typedef struct { - guint32 seq_number; - WaitForNlResponseResult seq_result; - DelayedActionWaitForNlResponseType response_type; - gint64 timeout_abs_ns; - WaitForNlResponseResult *out_seq_result; - char **out_errmsg; - union { - int *out_refresh_all_in_progress; - NMPObject **out_route_get; - gpointer out_data; - } response; -} DelayedActionWaitForNlResponseData; - -/*****************************************************************************/ - -typedef struct { - struct nl_sock *genl; - - struct nl_sock *nlh; - guint32 nlh_seq_next; -#if NM_MORE_LOGGING - guint32 nlh_seq_last_handled; -#endif - guint32 nlh_seq_last_seen; - GIOChannel *event_channel; - guint event_id; - - bool pruning[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; - - bool sysctl_get_warned; - GHashTable *sysctl_get_prev_values; - - NMUdevClient *udev_client; - - struct { - /* which delayed actions are scheduled, as marked in @flags. - * Some types have additional arguments in the fields below. */ - DelayedActionType flags; - - /* counter that a refresh all action is in progress, separated - * by type. */ - int refresh_all_in_progress[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; - - GPtrArray *list_master_connected; - GPtrArray *list_refresh_link; - GArray *list_wait_for_nl_response; - - int is_handling; - } delayed_action; -} NMLinuxPlatformPrivate; - -struct _NMLinuxPlatform { - NMPlatform parent; - NMLinuxPlatformPrivate _priv; -}; - -struct _NMLinuxPlatformClass { - NMPlatformClass parent; -}; - -G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) - -#define NM_LINUX_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMLinuxPlatform, NM_IS_LINUX_PLATFORM, NMPlatform) - -/*****************************************************************************/ - -#define _NMLOG_PREFIX_NAME "platform-linux" -#define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG2_DOMAIN LOGD_PLATFORM -#define _NMLOG(level, ...) _LOG ( level, _NMLOG_DOMAIN, platform, __VA_ARGS__) -#define _NMLOG_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG_DOMAIN, platform, __VA_ARGS__) -#define _NMLOG2(level, ...) _LOG ( level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) -#define _NMLOG2_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) - -#define _LOG_print(__level, __domain, __errsv, self, ...) \ - G_STMT_START { \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - NMPlatform *const __self = (self); \ - \ - if (__self && nm_platform_get_log_with_ptr (__self)) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, __domain, __errsv, NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } G_STMT_END - -#define _LOG(level, domain, self, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - const NMLogDomain __domain = (domain); \ - \ - if (nm_logging_enabled (__level, __domain)) { \ - _LOG_print (__level, __domain, 0, self, __VA_ARGS__); \ - } \ - } G_STMT_END - -#define _LOG_err(errsv, level, domain, self, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - const NMLogDomain __domain = (domain); \ - \ - if (nm_logging_enabled (__level, __domain)) { \ - int __errsv = (errsv); \ - \ - /* The %m format specifier (GNU extension) would alread allow you to specify the error - * message conveniently (and nm_log would get that right too). But we don't want to depend - * on that, so instead append the message at the end. - * Currently users are expected not to use %m in the format string. */ \ - _LOG_print (__level, __domain, __errsv, self, \ - _NM_UTILS_MACRO_FIRST (__VA_ARGS__) ": %s (%d)" \ - _NM_UTILS_MACRO_REST (__VA_ARGS__), \ - g_strerror (__errsv), __errsv); \ - } \ - } G_STMT_END - -/*****************************************************************************/ - static void delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data); static gboolean delayed_action_handle_all (NMPlatform *platform, gboolean read_netlink); static void do_request_link_no_delayed_actions (NMPlatform *platform, int ifindex, const char *name); @@ -470,7 +317,6 @@ static void cache_on_change (NMPlatform *platform, const NMPObject *obj_new); static void cache_prune_all (NMPlatform *platform); static gboolean event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks); -static struct nl_sock *_genl_sock (NMLinuxPlatform *platform); /*****************************************************************************/ @@ -687,8 +533,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" }, { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" }, { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" }, - { NM_LINK_TYPE_WPAN, "wpan", NULL, NULL }, - { NM_LINK_TYPE_6LOWPAN, "6lowpan", NULL, NULL }, { NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" }, { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL }, @@ -696,8 +540,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL }, { NM_LINK_TYPE_IFB, "ifb", "ifb", NULL }, { NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL }, - { NM_LINK_TYPE_IP6GRE, "ip6gre", "ip6gre", NULL }, - { NM_LINK_TYPE_IP6GRETAP, "ip6gretap", "ip6gretap", NULL }, { NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL }, { NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL }, { NM_LINK_TYPE_MACSEC, "macsec", "macsec", NULL }, @@ -710,7 +552,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_VETH, "veth", "veth", NULL }, { NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" }, { NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" }, - { NM_LINK_TYPE_WIREGUARD, "wireguard", "wireguard", "wireguard" }, { NM_LINK_TYPE_BRIDGE, "bridge", "bridge", "bridge" }, { NM_LINK_TYPE_BOND, "bond", "bond", "bond" }, @@ -884,21 +725,19 @@ _addrtime_get_lifetimes (guint32 timestamp, /*****************************************************************************/ static const NMPObject * -_lookup_cached_link (const NMPCache *cache, - int ifindex, - gboolean *completed_from_cache, - const NMPObject **link_cached) +_lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_from_cache, const NMPObject **link_cached) { const NMPObject *obj; nm_assert (completed_from_cache && link_cached); if (!*completed_from_cache) { - obj = ifindex > 0 && cache - ? nmp_cache_lookup_link (cache, ifindex) - : NULL; + obj = ifindex > 0 && cache ? nmp_cache_lookup_link (cache, ifindex) : NULL; - *link_cached = obj; + if (obj && obj->_link.netlink.is_in_netlink) + *link_cached = obj; + else + *link_cached = NULL; *completed_from_cache = TRUE; } return *link_cached; @@ -916,9 +755,7 @@ _linktype_read_devtype (int dirfd) nm_assert (dirfd >= 0); - if (nm_utils_file_get_contents (dirfd, "uevent", 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "uevent", 1*1024*1024, &contents, NULL, NULL) < 0) return NULL; for (cont = contents; cont; cont = end) { end = strpbrk (cont, "\r\n"); @@ -969,7 +806,6 @@ _linktype_get_type (NMPlatform *platform, * when moving interfce to other netns). Thus here there is a tiny potential * of messing stuff up. */ if ( obj - && obj->_link.netlink.is_in_netlink && !NM_IN_SET (obj->link.type, NM_LINK_TYPE_UNKNOWN, NM_LINK_TYPE_NONE) && nm_streq (ifname, obj->link.name) && ( !kind @@ -1005,10 +841,6 @@ _linktype_get_type (NMPlatform *platform, return NM_LINK_TYPE_IP6TNL; else if (arptype == ARPHRD_PPP) return NM_LINK_TYPE_PPP; - else if (arptype == ARPHRD_IEEE802154) - return NM_LINK_TYPE_WPAN; - else if (arptype == ARPHRD_6LOWPAN) - return NM_LINK_TYPE_6LOWPAN; { NMPUtilsEthtoolDriverInfo driver_info; @@ -1053,7 +885,7 @@ _linktype_get_type (NMPlatform *platform, } /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ - if (nm_wifi_utils_is_wifi (dirfd, ifname_verified)) + if (wifi_utils_is_wifi (dirfd, ifname_verified)) return NM_LINK_TYPE_WIFI; } @@ -1121,21 +953,18 @@ _nl_addattr_l (struct nlmsghdr *n, * NMPObject/netlink functions ******************************************************************/ -#define _check_addr_or_return_val(tb, attr, addr_len, ret_val) \ +#define _check_addr_or_errout(tb, attr, addr_len) \ ({ \ const struct nlattr *__t = (tb)[(attr)]; \ \ if (__t) { \ if (nla_len (__t) != (addr_len)) { \ - return ret_val; \ + goto errout; \ } \ } \ !!__t; \ }) -#define _check_addr_or_return_null(tb, attr, addr_len) \ - _check_addr_or_return_val (tb, attr, addr_len, NULL) - /*****************************************************************************/ /* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */ @@ -1162,19 +991,20 @@ _parse_af_inet6 (NMPlatform *platform, gboolean token_valid = FALSE; gboolean addr_gen_mode_valid = FALSE; guint8 i6_addr_gen_mode_inv = 0; + gboolean success = FALSE; err = nla_parse_nested (tb, IFLA_INET6_MAX, attr, policy); if (err < 0) - return FALSE; + goto errout; if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4) - return FALSE; + goto errout; if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8) - return FALSE; + goto errout; if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8) - return FALSE; + goto errout; - if (_check_addr_or_return_val (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr), FALSE)) { + if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) { nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr)); token_valid = TRUE; } @@ -1190,11 +1020,12 @@ _parse_af_inet6 (NMPlatform *platform, if (i6_addr_gen_mode_inv == 0) { /* an inverse addrgenmode of zero is unexpected. We need to reserve zero * to signal "unset". */ - return FALSE; + goto errout; } addr_gen_mode_valid = TRUE; } + success = TRUE; if (token_valid) { *out_token_valid = token_valid; nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token); @@ -1203,7 +1034,8 @@ _parse_af_inet6 (NMPlatform *platform, *out_addr_gen_mode_valid = addr_gen_mode_valid; *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; } - return TRUE; +errout: + return success; } /*****************************************************************************/ @@ -1227,23 +1059,15 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data) int err; NMPObject *obj; NMPlatformLnkGre *props; - gboolean is_tap; - - if (!info_data || !kind) - return NULL; - if (nm_streq (kind, "gretap")) - is_tap = TRUE; - else if (nm_streq (kind, "gre")) - is_tap = FALSE; - else + if (!info_data || g_strcmp0 (kind, "gre")) return NULL; err = nla_parse_nested (tb, IFLA_GRE_MAX, info_data, policy); if (err < 0) return NULL; - obj = nmp_object_new (is_tap ? NMP_OBJECT_TYPE_LNK_GRETAP : NMP_OBJECT_TYPE_LNK_GRE, NULL); + obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_GRE, NULL); props = &obj->lnk_gre; props->parent_ifindex = tb[IFLA_GRE_LINK] ? nla_get_u32 (tb[IFLA_GRE_LINK]) : 0; @@ -1256,7 +1080,6 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data) props->tos = tb[IFLA_GRE_TOS] ? nla_get_u8 (tb[IFLA_GRE_TOS]) : 0; props->ttl = tb[IFLA_GRE_TTL] ? nla_get_u8 (tb[IFLA_GRE_TTL]) : 0; props->path_mtu_discovery = !tb[IFLA_GRE_PMTUDISC] || !!nla_get_u8 (tb[IFLA_GRE_PMTUDISC]); - props->is_tap = is_tap; return obj; } @@ -1377,79 +1200,6 @@ _parse_lnk_ip6tnl (const char *kind, struct nlattr *info_data) return obj; } -static NMPObject * -_parse_lnk_ip6gre (const char *kind, struct nlattr *info_data) -{ - static const struct nla_policy policy[IFLA_GRE_MAX + 1] = { - [IFLA_GRE_LINK] = { .type = NLA_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_IKEY] = { .type = NLA_U32 }, - [IFLA_GRE_OKEY] = { .type = NLA_U32 }, - [IFLA_GRE_LOCAL] = { .type = NLA_UNSPEC, - .minlen = sizeof (struct in6_addr)}, - [IFLA_GRE_REMOTE] = { .type = NLA_UNSPEC, - .minlen = sizeof (struct in6_addr)}, - [IFLA_GRE_TTL] = { .type = NLA_U8 }, - [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 }, - [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 }, - [IFLA_GRE_FLAGS] = { .type = NLA_U32 }, - }; - struct nlattr *tb[IFLA_GRE_MAX + 1]; - int err; - NMPObject *obj; - NMPlatformLnkIp6Tnl *props; - guint32 flowinfo; - gboolean is_tap; - - if (!info_data || !kind) - return NULL; - - if (nm_streq (kind, "ip6gre")) - is_tap = FALSE; - else if (nm_streq (kind, "ip6gretap")) - is_tap = TRUE; - else - return NULL; - - err = nla_parse_nested (tb, IFLA_GRE_MAX, info_data, policy); - if (err < 0) - return NULL; - - obj = nmp_object_new (is_tap ? NMP_OBJECT_TYPE_LNK_IP6GRETAP : NMP_OBJECT_TYPE_LNK_IP6GRE, NULL); - props = &obj->lnk_ip6tnl; - props->is_gre = TRUE; - props->is_tap = is_tap; - - if (tb[IFLA_GRE_LINK]) - props->parent_ifindex = nla_get_u32 (tb[IFLA_GRE_LINK]); - if (tb[IFLA_GRE_IFLAGS]) - props->input_flags = ntohs (nla_get_u16 (tb[IFLA_GRE_IFLAGS])); - if (tb[IFLA_GRE_OFLAGS]) - props->output_flags = ntohs (nla_get_u16 (tb[IFLA_GRE_OFLAGS])); - if (tb[IFLA_GRE_IKEY]) - props->input_key = ntohl (nla_get_u32 (tb[IFLA_GRE_IKEY])); - if (tb[IFLA_GRE_OKEY]) - props->output_key = ntohl (nla_get_u32 (tb[IFLA_GRE_OKEY])); - if (tb[IFLA_GRE_LOCAL]) - memcpy (&props->local, nla_data (tb[IFLA_GRE_LOCAL]), sizeof (props->local)); - if (tb[IFLA_GRE_REMOTE]) - memcpy (&props->remote, nla_data (tb[IFLA_GRE_REMOTE]), sizeof (props->remote)); - if (tb[IFLA_GRE_TTL]) - props->ttl = nla_get_u8 (tb[IFLA_GRE_TTL]); - if (tb[IFLA_GRE_ENCAP_LIMIT]) - props->encap_limit = nla_get_u8 (tb[IFLA_GRE_ENCAP_LIMIT]); - if (tb[IFLA_GRE_FLOWINFO]) { - flowinfo = ntohl (nla_get_u32 (tb[IFLA_GRE_FLOWINFO])); - props->flow_label = flowinfo & IP6_FLOWINFO_FLOWLABEL_MASK; - props->tclass = (flowinfo & IP6_FLOWINFO_TCLASS_MASK) >> IP6_FLOWINFO_TCLASS_SHIFT; - } - if (tb[IFLA_GRE_FLAGS]) - props->flags = nla_get_u32 (tb[IFLA_GRE_FLAGS]); - - return obj; -} - /*****************************************************************************/ static NMPObject * @@ -1913,378 +1663,6 @@ _parse_lnk_vxlan (const char *kind, struct nlattr *info_data) /*****************************************************************************/ -static gboolean -_wireguard_update_from_allowed_ips_nla (NMPWireGuardAllowedIP *allowed_ip, - struct nlattr *nlattr) -{ - static const struct nla_policy policy[WGALLOWEDIP_A_MAX + 1] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .minlen = sizeof (struct in_addr) }, - [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 }, - }; - struct nlattr *tb[WGALLOWEDIP_A_MAX + 1]; - int family; - int addr_len; - - if (nla_parse_nested (tb, WGALLOWEDIP_A_MAX, nlattr, policy) < 0) - return FALSE; - - if (!tb[WGALLOWEDIP_A_FAMILY]) - return FALSE; - - family = nla_get_u16 (tb[WGALLOWEDIP_A_FAMILY]); - if (family == AF_INET) - addr_len = sizeof (in_addr_t); - else if (family == AF_INET6) - addr_len = sizeof (struct in6_addr); - else - return FALSE; - - _check_addr_or_return_val (tb, WGALLOWEDIP_A_IPADDR, addr_len, FALSE); - - memset (allowed_ip, 0, sizeof (NMPWireGuardAllowedIP)); - - allowed_ip->family = family; - nm_assert ((int) allowed_ip->family == family); - - if (tb[WGALLOWEDIP_A_IPADDR]) - nla_memcpy (&allowed_ip->addr, tb[WGALLOWEDIP_A_IPADDR], addr_len); - if (tb[WGALLOWEDIP_A_CIDR_MASK]) - allowed_ip->mask = nla_get_u8 (tb[WGALLOWEDIP_A_CIDR_MASK]); - - return TRUE; -} - -typedef struct { - CList lst; - NMPWireGuardPeer data; -} WireGuardPeerConstruct; - -static gboolean -_wireguard_update_from_peers_nla (CList *peers, - GArray **p_allowed_ips, - struct nlattr *peer_attr) -{ - static const struct nla_policy policy[WGPEER_A_MAX + 1] = { - [WGPEER_A_PUBLIC_KEY] = { .minlen = NMP_WIREGUARD_PUBLIC_KEY_LEN }, - [WGPEER_A_PRESHARED_KEY] = { }, - [WGPEER_A_FLAGS] = { .type = NLA_U32 }, - [WGPEER_A_ENDPOINT] = { }, - [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, - [WGPEER_A_LAST_HANDSHAKE_TIME] = { }, - [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, - }; - WireGuardPeerConstruct *peer_c; - struct nlattr *tb[WGPEER_A_MAX + 1]; - - if (nla_parse_nested (tb, WGPEER_A_MAX, peer_attr, policy) < 0) - return FALSE; - - if (!tb[WGPEER_A_PUBLIC_KEY]) - return FALSE; - - /* a peer with the same public key as last peer is just a continuation for extra AllowedIPs */ - peer_c = c_list_last_entry (peers, WireGuardPeerConstruct, lst); - if ( peer_c - && !memcmp (nla_data (tb[WGPEER_A_PUBLIC_KEY]), peer_c->data.public_key, NMP_WIREGUARD_PUBLIC_KEY_LEN)) { - G_STATIC_ASSERT_EXPR (NMP_WIREGUARD_PUBLIC_KEY_LEN == sizeof (peer_c->data.public_key)); - /* this message is a continuation of the previous peer. - * Only parse WGPEER_A_ALLOWEDIPS below. */ - } - else { - /* otherwise, start a new peer */ - peer_c = g_slice_new0 (WireGuardPeerConstruct); - c_list_link_tail (peers, &peer_c->lst); - - nla_memcpy (&peer_c->data.public_key, tb[WGPEER_A_PUBLIC_KEY], sizeof (peer_c->data.public_key)); - - if (tb[WGPEER_A_PRESHARED_KEY]) { - nla_memcpy (&peer_c->data.preshared_key, tb[WGPEER_A_PRESHARED_KEY], sizeof (peer_c->data.preshared_key)); - /* FIXME(netlink-bzero-secret) */ - nm_explicit_bzero (nla_data (tb[WGPEER_A_PRESHARED_KEY]), - nla_len (tb[WGPEER_A_PRESHARED_KEY])); - } - if (tb[WGPEER_A_ENDPOINT]) { - const struct sockaddr *addr = nla_data (tb[WGPEER_A_ENDPOINT]); - unsigned short family; - - G_STATIC_ASSERT (sizeof (addr->sa_family) == sizeof (family)); - memcpy (&family, &addr->sa_family, sizeof (addr->sa_family)); - - if ( family == AF_INET - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in)) { - const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr; - - peer_c->data.endpoint_family = AF_INET; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr4->sin_port); - peer_c->data.endpoint_addr.addr4 = unaligned_read_ne32 (&addr4->sin_addr.s_addr); - memcpy (&peer_c->data.endpoint_addr.addr4, &addr4->sin_addr.s_addr, 4); - } else if ( family == AF_INET6 - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in6)) { - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr; - - peer_c->data.endpoint_family = AF_INET6; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr6->sin6_port); - memcpy (&peer_c->data.endpoint_addr.addr6, &addr6->sin6_addr, 16); - } - } - if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) - peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); - if (tb[WGPEER_A_LAST_HANDSHAKE_TIME]) - nla_memcpy (&peer_c->data.last_handshake_time, tb[WGPEER_A_LAST_HANDSHAKE_TIME], sizeof (peer_c->data.last_handshake_time)); - if (tb[WGPEER_A_RX_BYTES]) - peer_c->data.rx_bytes = nla_get_u64 (tb[WGPEER_A_RX_BYTES]); - if (tb[WGPEER_A_TX_BYTES]) - peer_c->data.tx_bytes = nla_get_u64 (tb[WGPEER_A_TX_BYTES]); - } - - if (tb[WGPEER_A_ALLOWEDIPS]) { - struct nlattr *attr; - int rem; - GArray *allowed_ips = *p_allowed_ips; - - nla_for_each_nested (attr, tb[WGPEER_A_ALLOWEDIPS], rem) { - if (!allowed_ips) { - allowed_ips = g_array_new (FALSE, FALSE, sizeof (NMPWireGuardAllowedIP)); - *p_allowed_ips = allowed_ips; - g_array_set_size (allowed_ips, 1); - } else - g_array_set_size (allowed_ips, allowed_ips->len + 1); - - if (!_wireguard_update_from_allowed_ips_nla (&g_array_index (allowed_ips, - NMPWireGuardAllowedIP, - allowed_ips->len - 1), - attr)) { - /* we ignore the error of parsing one allowed-ip. */ - g_array_set_size (allowed_ips, allowed_ips->len - 1); - continue; - } - - if (!peer_c->data._construct_idx_end) - peer_c->data._construct_idx_start = allowed_ips->len - 1; - peer_c->data._construct_idx_end = allowed_ips->len; - } - } - - return TRUE; -} - -typedef struct { - const int ifindex; - NMPObject *obj; - CList peers; - GArray *allowed_ips; -} WireGuardParseData; - -static int -_wireguard_get_device_cb (struct nl_msg *msg, void *arg) -{ - static const struct nla_policy policy[WGDEVICE_A_MAX + 1] = { - [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .maxlen = IFNAMSIZ }, - [WGDEVICE_A_PRIVATE_KEY] = { }, - [WGDEVICE_A_PUBLIC_KEY] = { }, - [WGDEVICE_A_FLAGS] = { .type = NLA_U32 }, - [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, - [WGDEVICE_A_PEERS] = { .type = NLA_NESTED }, - }; - WireGuardParseData *parse_data = arg; - struct nlattr *tb[WGDEVICE_A_MAX + 1]; - int nlerr; - - nlerr = genlmsg_parse (nlmsg_hdr (msg), 0, tb, WGDEVICE_A_MAX, policy); - if (nlerr < 0) - return NL_SKIP; - - if (tb[WGDEVICE_A_IFINDEX]) { - int ifindex; - - ifindex = (int) nla_get_u32 (tb[WGDEVICE_A_IFINDEX]); - if ( ifindex <= 0 - || parse_data->ifindex != ifindex) - return NL_SKIP; - } else { - if (!parse_data->obj) - return NL_SKIP; - } - - if (parse_data->obj) { - /* we already have an object instance. This means the netlink message - * is a continuation, only providing more WGDEVICE_A_PEERS data below. */ - } else { - NMPObject *obj; - NMPlatformLnkWireGuard *props; - - obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_WIREGUARD, NULL); - props = &obj->lnk_wireguard; - - if (tb[WGDEVICE_A_PRIVATE_KEY]) { - nla_memcpy (props->private_key, tb[WGDEVICE_A_PRIVATE_KEY], sizeof (props->private_key)); - /* FIXME(netlink-bzero-secret): extend netlink library to wipe memory. For now, - * just hack it here (yes, this does not cover all places where the - * private key was copied). */ - nm_explicit_bzero (nla_data (tb[WGDEVICE_A_PRIVATE_KEY]), - nla_len (tb[WGDEVICE_A_PRIVATE_KEY])); - } - if (tb[WGDEVICE_A_PUBLIC_KEY]) - nla_memcpy (props->public_key, tb[WGDEVICE_A_PUBLIC_KEY], sizeof (props->public_key)); - if (tb[WGDEVICE_A_LISTEN_PORT]) - props->listen_port = nla_get_u16 (tb[WGDEVICE_A_LISTEN_PORT]); - if (tb[WGDEVICE_A_FWMARK]) - props->fwmark = nla_get_u32 (tb[WGDEVICE_A_FWMARK]); - - parse_data->obj = obj; - } - - if (tb[WGDEVICE_A_PEERS]) { - struct nlattr *attr; - int rem; - - nla_for_each_nested (attr, tb[WGDEVICE_A_PEERS], rem) { - if (!_wireguard_update_from_peers_nla (&parse_data->peers, &parse_data->allowed_ips, attr)) { - /* we ignore the error of parsing one peer. - * _wireguard_update_from_peers_nla() leaves the @peers array in the - * desired state. */ - } - } - } - - return NL_OK; -} - -static const NMPObject * -_wireguard_read_info (NMPlatform *platform /* used only as logging context */, - struct nl_sock *genl, - int wireguard_family_id, - int ifindex) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - NMPObject *obj = NULL; - WireGuardPeerConstruct *peer_c; - WireGuardPeerConstruct *peer_c_safe; - gs_unref_array GArray *allowed_ips = NULL; - WireGuardParseData parse_data = { - .ifindex = ifindex, - }; - guint i; - - nm_assert (genl); - nm_assert (wireguard_family_id >= 0); - nm_assert (ifindex > 0); - - msg = nlmsg_alloc (); - - if (!genlmsg_put (msg, - NL_AUTO_PORT, - NL_AUTO_SEQ, - wireguard_family_id, - 0, - NLM_F_DUMP, - WG_CMD_GET_DEVICE, - 1)) - return NULL; - - NLA_PUT_U32 (msg, WGDEVICE_A_IFINDEX, (guint32) ifindex); - - if (nl_send_auto (genl, msg) < 0) - return NULL; - - c_list_init (&parse_data.peers); - - /* we ignore errors, and return whatever we could successfully - * parse. */ - nl_recvmsgs (genl, - &((const struct nl_cb) { - .valid_cb = _wireguard_get_device_cb, - .valid_arg = (gpointer) &parse_data, - })); - - /* unpack: transfer ownership */ - obj = parse_data.obj; - allowed_ips = parse_data.allowed_ips; - - if (!obj) { - while ((peer_c = c_list_first_entry (&parse_data.peers, WireGuardPeerConstruct, lst))) { - c_list_unlink_stale (&peer_c->lst); - nm_explicit_bzero (&peer_c->data.preshared_key, sizeof (peer_c->data.preshared_key)); - g_slice_free (WireGuardPeerConstruct, peer_c); - } - return NULL; - } - - /* we receive peers/allowed-ips possibly in separate netlink messages. Hence, while - * parsing the dump, we don't know upfront how many peers/allowed-ips we will receive. - * - * We solve that, by collecting all peers with a CList. It's done this way, - * because a GArray would require growing the array, but we want to bzero() - * the preshared-key of each peer while reallocating. The CList apprach avoids - * that. - * - * For allowed-ips, we instead track one GArray, which are all appended - * there. The realloc/resize of the GArray is fine there. However, - * while we build the GArray, we don't yet have the final pointers. - * Hence, while constructing, we track the indexes with peer->_construct_idx_* - * fields. These indexes must be convered to actual pointers blow. - * - * This is all done during parsing. In the final NMPObjectLnkWireGuard we - * don't want the CList anymore and repackage the NMPObject tightly. The - * reason is, that NMPObject instances are immutable and long-living. Spend - * a bit effort below during construction to obtain a most suitable representation - * in this regard. */ - obj->_lnk_wireguard.peers_len = c_list_length (&parse_data.peers); - obj->_lnk_wireguard.peers = obj->_lnk_wireguard.peers_len > 0 - ? g_new (NMPWireGuardPeer, obj->_lnk_wireguard.peers_len) - : NULL; - - /* duplicate allowed_ips instead of using the pointer. The GArray possibly has more - * space allocated then we need, and we want to get rid of this excess buffer. - * Note that NMPObject instance is possibly put into the cache and long-living. */ - obj->_lnk_wireguard._allowed_ips_buf_len = allowed_ips ? allowed_ips->len : 0u; - obj->_lnk_wireguard._allowed_ips_buf = obj->_lnk_wireguard._allowed_ips_buf_len > 0 - ? (NMPWireGuardAllowedIP *) nm_memdup (allowed_ips->data, - sizeof (NMPWireGuardAllowedIP) * allowed_ips->len) - : NULL; - - i = 0; - c_list_for_each_entry_safe (peer_c, peer_c_safe, &parse_data.peers, lst) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &obj->_lnk_wireguard.peers[i++]; - - *peer = peer_c->data; - - c_list_unlink_stale (&peer_c->lst); - nm_explicit_bzero (&peer_c->data.preshared_key, sizeof (peer_c->data.preshared_key)); - g_slice_free (WireGuardPeerConstruct, peer_c); - - if (peer->_construct_idx_end != 0) { - guint len; - - nm_assert (obj->_lnk_wireguard._allowed_ips_buf); - nm_assert (peer->_construct_idx_end > peer->_construct_idx_start); - nm_assert (peer->_construct_idx_start < obj->_lnk_wireguard._allowed_ips_buf_len); - nm_assert (peer->_construct_idx_end <= obj->_lnk_wireguard._allowed_ips_buf_len); - - len = peer->_construct_idx_end - peer->_construct_idx_start; - peer->allowed_ips = &obj->_lnk_wireguard._allowed_ips_buf[peer->_construct_idx_start]; - peer->allowed_ips_len = len; - } else { - nm_assert (!peer->_construct_idx_start); - nm_assert (!peer->_construct_idx_end); - peer->allowed_ips = NULL; - peer->allowed_ips_len = 0; - } - } - - return obj; - -nla_put_failure: - g_return_val_if_reached (NULL); -} - -/*****************************************************************************/ - /* Copied and heavily modified from libnl3's link_msg_parser(). */ static NMPObject * _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr *nlh, gboolean id_only) @@ -2329,39 +1707,37 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr const char *nl_info_kind = NULL; int err; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; gboolean completed_from_cache_val = FALSE; gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL; const NMPObject *link_cached = NULL; - const NMPObject *lnk_data = NULL; + NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean lnk_data_complete_from_cache = TRUE; - gboolean need_ext_data = FALSE; gboolean af_inet6_token_valid = FALSE; gboolean af_inet6_addr_gen_mode_valid = FALSE; if (!nlmsg_valid_hdr (nlh, sizeof (*ifi))) return NULL; - ifi = nlmsg_data (nlh); + ifi = nlmsg_data(nlh); if (ifi->ifi_family != AF_UNSPEC) return NULL; - if (ifi->ifi_index <= 0) - return NULL; obj = nmp_object_new_link (ifi->ifi_index); if (id_only) - return g_steal_pointer (&obj); + goto id_only_handled; err = nlmsg_parse (nlh, sizeof (*ifi), tb, IFLA_MAX, policy); if (err < 0) - return NULL; + goto errout; if (!tb[IFLA_IFNAME]) - return NULL; + goto errout; nla_strlcpy(obj->link.name, tb[IFLA_IFNAME], IFNAMSIZ); if (!obj->link.name[0]) - return NULL; + goto errout; if (!tb[IFLA_MTU]) { /* Kernel has two places that send RTM_GETLINK messages: @@ -2376,14 +1752,14 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr * To some extent this is a hack and correct approach is to * merge objects per-field. */ - return NULL; + goto errout; } obj->link.mtu = nla_get_u32 (tb[IFLA_MTU]); if (tb[IFLA_LINKINFO]) { err = nla_parse_nested (li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], policy_link_info); if (err < 0) - return NULL; + goto errout; if (li[IFLA_INFO_KIND]) nl_info_kind = nla_get_string (li[IFLA_INFO_KIND]); @@ -2462,7 +1838,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr switch (obj->link.type) { case NM_LINK_TYPE_GRE: - case NM_LINK_TYPE_GRETAP: lnk_data = _parse_lnk_gre (nl_info_kind, nl_info_data); break; case NM_LINK_TYPE_INFINIBAND: @@ -2471,10 +1846,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case NM_LINK_TYPE_IP6TNL: lnk_data = _parse_lnk_ip6tnl (nl_info_kind, nl_info_data); break; - case NM_LINK_TYPE_IP6GRE: - case NM_LINK_TYPE_IP6GRETAP: - lnk_data = _parse_lnk_ip6gre (nl_info_kind, nl_info_data); - break; case NM_LINK_TYPE_IPIP: lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data); break; @@ -2497,15 +1868,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case NM_LINK_TYPE_VXLAN: lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data); break; - case NM_LINK_TYPE_WIFI: - case NM_LINK_TYPE_OLPC_MESH: - case NM_LINK_TYPE_WPAN: - need_ext_data = TRUE; - lnk_data_complete_from_cache = FALSE; - break; - case NM_LINK_TYPE_WIREGUARD: - lnk_data_complete_from_cache = TRUE; - break; default: lnk_data_complete_from_cache = FALSE; break; @@ -2513,14 +1875,12 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr if ( completed_from_cache && ( lnk_data_complete_from_cache - || need_ext_data || address_complete_from_cache || !af_inet6_token_valid || !af_inet6_addr_gen_mode_valid || !tb[IFLA_STATS64])) { _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); - if ( link_cached - && link_cached->_link.netlink.is_in_netlink) { + if (link_cached) { if ( lnk_data_complete_from_cache && link_cached->link.type == obj->link.type && link_cached->_link.netlink.lnk @@ -2533,16 +1893,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr * Also, sometimes the info-data is missing for updates. In this case * we want to keep the previously received lnk_data. */ nmp_object_unref (lnk_data); - lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk); + lnk_data = (NMPObject *) nmp_object_ref (link_cached->_link.netlink.lnk); } - - if ( need_ext_data - && link_cached->link.type == obj->link.type - && link_cached->_link.ext_data) { - /* Prefer reuse of existing ext_data object */ - obj->_link.ext_data = g_object_ref (link_cached->_link.ext_data); - } - if (address_complete_from_cache) obj->link.addr = link_cached->link.addr; if (!af_inet6_token_valid) @@ -2560,71 +1912,12 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr obj->_link.netlink.lnk = lnk_data; - if ( need_ext_data - && obj->_link.ext_data == NULL) { - switch (obj->link.type) { - case NM_LINK_TYPE_WIFI: - obj->_link.ext_data = (GObject *) nm_wifi_utils_new (ifi->ifi_index, - _genl_sock (NM_LINUX_PLATFORM (platform)), - TRUE); - break; - case NM_LINK_TYPE_OLPC_MESH: -#if HAVE_WEXT - /* The kernel driver now uses nl80211, but we force use of WEXT because - * the cfg80211 interactions are not quite ready to support access to - * mesh control through nl80211 just yet. - */ - obj->_link.ext_data = (GObject *) nm_wifi_utils_wext_new (ifi->ifi_index, FALSE); -#endif - break; - case NM_LINK_TYPE_WPAN: - obj->_link.ext_data = (GObject *) nm_wpan_utils_new (ifi->ifi_index, - _genl_sock (NM_LINUX_PLATFORM (platform)), - TRUE); - break; - default: - g_assert_not_reached (); - } - } - - if (obj->link.type == NM_LINK_TYPE_WIREGUARD) { - const NMPObject *lnk_data_new = NULL; - struct nl_sock *genl = NM_LINUX_PLATFORM_GET_PRIVATE (platform)->genl; - - /* The WireGuard kernel module does not yet send link update - * notifications, so we don't actually update the cache. For - * now, always refetch link data here. */ - - _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); - if ( link_cached - && link_cached->_link.netlink.is_in_netlink - && link_cached->link.type == NM_LINK_TYPE_WIREGUARD) - obj->_link.wireguard_family_id = link_cached->_link.wireguard_family_id; - else - obj->_link.wireguard_family_id = -1; - - if (obj->_link.wireguard_family_id < 0) - obj->_link.wireguard_family_id = genl_ctrl_resolve (genl, "wireguard"); - - if (obj->_link.wireguard_family_id >= 0) { - lnk_data_new = _wireguard_read_info (platform, - genl, - obj->_link.wireguard_family_id, - obj->link.ifindex); - } - - if ( lnk_data_new - && obj->_link.netlink.lnk - && nmp_object_equal (obj->_link.netlink.lnk, lnk_data_new)) - nmp_object_unref (lnk_data_new); - else { - nmp_object_unref (obj->_link.netlink.lnk); - obj->_link.netlink.lnk = lnk_data_new; - } - } - obj->_link.netlink.is_in_netlink = TRUE; - return g_steal_pointer (&obj); +id_only_handled: + obj_result = obj; + obj = NULL; +errout: + return obj_result; } /* Copied and heavily modified from libnl3's addr_msg_parser(). */ @@ -2641,6 +1934,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) int err; gboolean is_v4; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; int addr_len; guint32 lifetime, preferred, timestamp; @@ -2649,19 +1943,19 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) ifa = nlmsg_data(nlh); if (!NM_IN_SET (ifa->ifa_family, AF_INET, AF_INET6)) - return NULL; + goto errout; is_v4 = ifa->ifa_family == AF_INET; err = nlmsg_parse (nlh, sizeof(*ifa), tb, IFA_MAX, policy); if (err < 0) - return NULL; + goto errout; addr_len = is_v4 ? sizeof (in_addr_t) : sizeof (struct in6_addr); if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128)) - return NULL; + goto errout; /*****************************************************************/ @@ -2670,8 +1964,8 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) obj->ip_address.ifindex = ifa->ifa_index; obj->ip_address.plen = ifa->ifa_prefixlen; - _check_addr_or_return_null (tb, IFA_ADDRESS, addr_len); - _check_addr_or_return_null (tb, IFA_LOCAL, addr_len); + _check_addr_or_errout (tb, IFA_ADDRESS, addr_len); + _check_addr_or_errout (tb, IFA_LOCAL, addr_len); if (is_v4) { /* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they * are effectively 0.0.0.0 (all-zero). */ @@ -2735,7 +2029,10 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) &obj->ip_address.lifetime, &obj->ip_address.preferred); - return g_steal_pointer (&obj); + obj_result = obj; + obj = NULL; +errout: + return obj_result; } /* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */ @@ -2758,6 +2055,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) int err; gboolean is_v4; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; int addr_len; struct { gboolean is_present; @@ -2776,14 +2074,14 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) *****************************************************************/ if (!NM_IN_SET (rtm->rtm_family, AF_INET, AF_INET6)) - return NULL; + goto errout; if (rtm->rtm_type != RTN_UNICAST) - return NULL; + goto errout; err = nlmsg_parse (nlh, sizeof (struct rtmsg), tb, RTA_MAX, policy); if (err < 0) - return NULL; + goto errout; /*****************************************************************/ @@ -2793,7 +2091,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) : sizeof (struct in6_addr); if (rtm->rtm_dst_len > (is_v4 ? 32 : 128)) - return NULL; + goto errout; /***************************************************************** * parse nexthops. Only handle routes with one nh. @@ -2809,7 +2107,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (nh.is_present) { /* we don't support multipath routes. */ - return NULL; + goto errout; } nh.is_present = TRUE; @@ -2823,9 +2121,9 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) rtnh->rtnh_len - sizeof (*rtnh), policy); if (err < 0) - return NULL; + goto errout; - if (_check_addr_or_return_null (ntb, RTA_GATEWAY, addr_len)) + if (_check_addr_or_errout (ntb, RTA_GATEWAY, addr_len)) memcpy (&nh.gateway, nla_data (ntb[RTA_GATEWAY]), addr_len); } @@ -2842,7 +2140,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (tb[RTA_OIF]) ifindex = nla_get_u32 (tb[RTA_OIF]); - if (_check_addr_or_return_null (tb, RTA_GATEWAY, addr_len)) + if (_check_addr_or_errout (tb, RTA_GATEWAY, addr_len)) memcpy (&gateway, nla_data (tb[RTA_GATEWAY]), addr_len); if (!nh.is_present) { @@ -2856,10 +2154,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) * verify that it is a duplicate and ignore old-style nexthop. */ if ( nh.ifindex != ifindex || memcmp (&nh.gateway, &gateway, addr_len) != 0) - return NULL; + goto errout; } } else if (!nh.is_present) - return NULL; + goto errout; /*****************************************************************/ @@ -2878,7 +2176,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) err = nla_parse_nested (mtb, RTAX_MAX, tb[RTA_METRICS], rtax_policy); if (err < 0) - return NULL; + goto errout; if (mtb[RTAX_LOCK]) lock = nla_get_u32 (mtb[RTAX_LOCK]); @@ -2906,7 +2204,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip_route.ifindex = nh.ifindex; - if (_check_addr_or_return_null (tb, RTA_DST, addr_len)) + if (_check_addr_or_errout (tb, RTA_DST, addr_len)) memcpy (obj->ip_route.network_ptr, nla_data (tb[RTA_DST]), addr_len); obj->ip_route.plen = rtm->rtm_dst_len; @@ -2922,7 +2220,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (is_v4) obj->ip4_route.scope_inv = nm_platform_route_scope_inv (rtm->rtm_scope); - if (_check_addr_or_return_null (tb, RTA_PREFSRC, addr_len)) { + if (_check_addr_or_errout (tb, RTA_PREFSRC, addr_len)) { if (is_v4) memcpy (&obj->ip4_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len); else @@ -2933,7 +2231,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip4_route.tos = rtm->rtm_tos; else { if (tb[RTA_SRC]) { - _check_addr_or_return_null (tb, RTA_SRC, addr_len); + _check_addr_or_errout (tb, RTA_SRC, addr_len); memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len); } obj->ip6_route.src_plen = rtm->rtm_src_len; @@ -2963,7 +2261,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip_route.r_rtm_flags = rtm->rtm_flags; obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); - return g_steal_pointer (&obj); + obj_result = obj; + obj = NULL; +errout: + return obj_result; } static NMPObject * @@ -3640,16 +2941,103 @@ nla_put_failure: g_return_val_if_reached (NULL); } -/*****************************************************************************/ +/****************************************************************** + * NMPlatform types and functions + ******************************************************************/ + +typedef enum { + DELAYED_ACTION_RESPONSE_TYPE_VOID = 0, + DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS = 1, + DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET = 2, +} DelayedActionWaitForNlResponseType; + +typedef struct { + guint32 seq_number; + WaitForNlResponseResult seq_result; + DelayedActionWaitForNlResponseType response_type; + gint64 timeout_abs_ns; + WaitForNlResponseResult *out_seq_result; + char **out_errmsg; + union { + gint *out_refresh_all_in_progess; + NMPObject **out_route_get; + gpointer out_data; + } response; +} DelayedActionWaitForNlResponseData; + +typedef struct { + struct nl_sock *nlh; + guint32 nlh_seq_next; +#ifdef NM_MORE_LOGGING + guint32 nlh_seq_last_handled; +#endif + guint32 nlh_seq_last_seen; + GIOChannel *event_channel; + guint event_id; + + bool pruning[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; + + bool sysctl_get_warned; + GHashTable *sysctl_get_prev_values; + + NMUdevClient *udev_client; + + struct { + /* which delayed actions are scheduled, as marked in @flags. + * Some types have additional arguments in the fields below. */ + DelayedActionType flags; + + /* counter that a refresh all action is in progress, separated + * by type. */ + gint refresh_all_in_progess[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; + + GPtrArray *list_master_connected; + GPtrArray *list_refresh_link; + GArray *list_wait_for_nl_response; + + gint is_handling; + } delayed_action; + + GHashTable *wifi_data; +} NMLinuxPlatformPrivate; + +struct _NMLinuxPlatform { + NMPlatform parent; + NMLinuxPlatformPrivate _priv; +}; + +struct _NMLinuxPlatformClass { + NMPlatformClass parent; +}; -static struct nl_sock * -_genl_sock (NMLinuxPlatform *platform) +G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) + +#define NM_LINUX_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMLinuxPlatform, NM_IS_LINUX_PLATFORM, NMPlatform) + +NMPlatform * +nm_linux_platform_new (gboolean log_with_ptr, gboolean netns_support) { - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + gboolean use_udev = FALSE; + + if ( nmp_netns_is_initial () + && access ("/sys", W_OK) == 0) + use_udev = TRUE; - return priv->genl; + return g_object_new (NM_TYPE_LINUX_PLATFORM, + NM_PLATFORM_LOG_WITH_PTR, log_with_ptr, + NM_PLATFORM_USE_UDEV, use_udev, + NM_PLATFORM_NETNS_SUPPORT, netns_support, + NULL); +} + +void +nm_linux_platform_setup (void) +{ + nm_platform_setup (nm_linux_platform_new (FALSE, FALSE)); } +/*****************************************************************************/ + #define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ G_STMT_START { \ const char *const _pathid = (pathid); \ @@ -3676,9 +3064,7 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *pathid, int dirfd, c char *contents; gs_free char *value_escaped = g_strescape (value, NULL); - if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, &error) < 0) { + if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, &contents, NULL, &error) < 0) { _LOGD ("sysctl: setting '%s' to '%s' (current value cannot be read: %s)", pathid, value_escaped, error->message); g_clear_error (&error); return; @@ -3895,9 +3281,7 @@ sysctl_get (NMPlatform *platform, const char *pathid, int dirfd, const char *pat pathid = path; } - if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, &error) < 0) { + if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, &contents, NULL, &error) < 0) { /* We assume FAILED means EOPNOTSUP */ if ( g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) || g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NODEV) @@ -4068,7 +3452,7 @@ delayed_action_refresh_all_in_progress (NMPlatform *platform, DelayedActionType if (NM_FLAGS_ANY (priv->delayed_action.flags, action_type)) return TRUE; - if (priv->delayed_action.refresh_all_in_progress[delayed_action_refresh_all_to_idx (action_type)] > 0) + if (priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (action_type)] > 0) return TRUE; return FALSE; @@ -4098,10 +3482,10 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, case DELAYED_ACTION_RESPONSE_TYPE_VOID: break; case DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS: - if (data->response.out_refresh_all_in_progress) { - nm_assert (*data->response.out_refresh_all_in_progress > 0); - *data->response.out_refresh_all_in_progress -= 1; - data->response.out_refresh_all_in_progress = NULL; + if (data->response.out_refresh_all_in_progess) { + nm_assert (*data->response.out_refresh_all_in_progess > 0); + *data->response.out_refresh_all_in_progess -= 1; + data->response.out_refresh_all_in_progess = NULL; } break; case DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET: @@ -4126,7 +3510,7 @@ delayed_action_wait_for_nl_response_complete_check (NMPlatform *platform, guint i; guint32 next_seq_number = 0; gint64 next_timeout_abs_ns = 0; - int now_ns = 0; + gint now_ns = 0; for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; ) { const DelayedActionWaitForNlResponseData *data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, i); @@ -4548,10 +3932,7 @@ cache_on_change (NMPlatform *platform, if ( !obj_new->_link.netlink.lnk && NM_IN_SET (obj_new->link.type, NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, NM_LINK_TYPE_INFINIBAND, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVLAN, @@ -4824,11 +4205,11 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio const NMPClass *klass = nmp_class_from_type (obj_type); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; int nle; - int *out_refresh_all_in_progress; + gint *out_refresh_all_in_progess; - out_refresh_all_in_progress = &priv->delayed_action.refresh_all_in_progress[delayed_action_refresh_all_to_idx (iflags)]; - nm_assert (*out_refresh_all_in_progress >= 0); - *out_refresh_all_in_progress += 1; + out_refresh_all_in_progess = &priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (iflags)]; + nm_assert (*out_refresh_all_in_progess >= 0); + *out_refresh_all_in_progess += 1; /* clear any delayed action that request a refresh of this object type. */ priv->delayed_action.flags &= ~iflags; @@ -4862,9 +4243,9 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio if (nle < 0) continue; - if (_nl_send_nlmsg (platform, nlmsg, NULL, NULL, DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS, out_refresh_all_in_progress) < 0) { - nm_assert (*out_refresh_all_in_progress > 0); - *out_refresh_all_in_progress -= 1; + if (_nl_send_nlmsg (platform, nlmsg, NULL, NULL, DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS, out_refresh_all_in_progess) < 0) { + nm_assert (*out_refresh_all_in_progess > 0); + *out_refresh_all_in_progess -= 1; } } } @@ -4893,10 +4274,10 @@ event_seq_check_refresh_all (NMPlatform *platform, guint32 seq_number) data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, i); if ( data->response_type == DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS - && data->response.out_refresh_all_in_progress + && data->response.out_refresh_all_in_progess && data->seq_number == priv->nlh_seq_last_seen) { - *data->response.out_refresh_all_in_progress -= 1; - data->response.out_refresh_all_in_progress = NULL; + *data->response.out_refresh_all_in_progess -= 1; + data->response.out_refresh_all_in_progess = NULL; break; } } @@ -4937,7 +4318,7 @@ event_seq_check (NMPlatform *platform, guint32 seq_number, WaitForNlResponseResu } } -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING if (seq_number != priv->nlh_seq_last_handled) _LOGt ("netlink: recvmsg: unwaited sequence number %u", seq_number); priv->nlh_seq_last_handled = seq_number; @@ -5360,9 +4741,6 @@ retry: } else if (NM_IN_SET (-((int) seq_result), ENODEV)) { log_level = LOGL_DEBUG; result = NM_PLATFORM_ERROR_NOT_FOUND; - } else if (-((int) seq_result) == EAFNOSUPPORT) { - log_level = LOGL_DEBUG; - result = NM_PLATFORM_ERROR_OPNOTSUPP; } else { log_level = LOGL_WARN; result = NM_PLATFORM_ERROR_UNSPECIFIED; @@ -5463,6 +4841,8 @@ link_set_netns (NMPlatform *platform, { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: move link %d to network namespace with fd %d", ifindex, netns_fd); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5651,6 +5031,7 @@ static NMPlatformError link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + gs_free char *mac = NULL; const ChangeLinkData d = { .set_address = { .address = address, @@ -5661,6 +5042,10 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size if (!address || !length) g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + _LOGD ("link: change %d: address: %s (%lu bytes)", ifindex, + (mac = nm_utils_hwaddr_ntoa (address, length)), + (unsigned long) length); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5682,6 +5067,8 @@ link_set_name (NMPlatform *platform, int ifindex, const char *name) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: change %d: name: %s", ifindex, name); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5717,6 +5104,8 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: change %d: mtu: %u", ifindex, (unsigned) mtu); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5734,18 +5123,16 @@ nla_put_failure: } static gboolean -link_set_sriov_params (NMPlatform *platform, - int ifindex, - guint num_vfs, - int autoprobe) +link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) { nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_close int dirfd = -1; - gboolean current_autoprobe; - guint total, current_num; + int total, current; char ifname[IFNAMSIZ]; char buf[64]; + _LOGD ("link: change %d: num VFs: %u", ifindex, num_vfs); + if (!nm_platform_netns_push (platform, &netns)) return FALSE; @@ -5753,69 +5140,46 @@ link_set_sriov_params (NMPlatform *platform, if (!dirfd) return FALSE; - total = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_totalvfs"), - 10, 0, G_MAXUINT, 0); - if (errno) + total = nm_platform_sysctl_get_int32 (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_totalvfs"), + -1); + if (total < 1) return FALSE; if (num_vfs > total) { _LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs); num_vfs = total; } - /* - * Take special care when setting new values: - * - don't touch anything if the right values are already set - * - to change the number of VFs or autoprobe we need to destroy existing VFs - * - the autoprobe setting is irrelevant when numvfs is zero - */ - current_num = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_numvfs"), - 10, 0, G_MAXUINT, 0); - current_autoprobe = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_drivers_autoprobe"), - 10, 0, G_MAXUINT, 0); - if ( current_num == num_vfs - && (autoprobe == -1 || current_autoprobe == autoprobe)) + current = nm_platform_sysctl_get_int32 (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_numvfs"), + -1); + if (current == num_vfs) return TRUE; - if (current_num != 0) { - /* We need to destroy all other VFs before changing any value */ + if (current != 0) { + /* We need to destroy all other VFs before changing the value */ if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), "0")) { - _LOGW ("link: couldn't reset SR-IOV num_vfs: %s", strerror (errno)); + _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", 0, strerror (errno)); return FALSE; } + if (num_vfs == 0) + return TRUE; } - if (num_vfs == 0) - return TRUE; - - if ( autoprobe >= 0 - && current_autoprobe != autoprobe - && !nm_platform_sysctl_set (NM_PLATFORM_GET, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_drivers_autoprobe"), - nm_sprintf_buf (buf, "%d", autoprobe))) { - _LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", autoprobe, strerror (errno)); - return FALSE; - } - + /* Finally, set the desired value */ if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), - nm_sprintf_buf (buf, "%u", num_vfs))) { + nm_sprintf_buf (buf, "%d", num_vfs))) { _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", num_vfs, strerror (errno)); return FALSE; } @@ -5823,101 +5187,6 @@ link_set_sriov_params (NMPlatform *platform, return TRUE; } -static gboolean -link_set_sriov_vfs (NMPlatform *platform, int ifindex, const NMPlatformVF *const *vfs) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *list, *info, *vlan_list; - guint i; - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - 0, - ifindex, - NULL, - 0, - 0); - if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); - - if (!(list = nla_nest_start (nlmsg, IFLA_VFINFO_LIST))) - goto nla_put_failure; - - for (i = 0; vfs[i]; i++) { - const NMPlatformVF *vf = vfs[i]; - - if (!(info = nla_nest_start (nlmsg, IFLA_VF_INFO))) - goto nla_put_failure; - - if (vf->spoofchk >= 0) { - struct _ifla_vf_setting ivs = { 0 }; - - ivs.vf = vf->index; - ivs.setting = vf->spoofchk; - NLA_PUT (nlmsg, IFLA_VF_SPOOFCHK, sizeof (ivs), &ivs); - } - - if (vf->trust >= 0) { - struct _ifla_vf_setting ivs = { 0 }; - - ivs.vf = vf->index; - ivs.setting = vf->trust; - NLA_PUT (nlmsg, IFLA_VF_TRUST, sizeof (ivs), &ivs); - } - - if (vf->mac.len) { - struct ifla_vf_mac ivm = { 0 }; - - ivm.vf = vf->index; - memcpy (ivm.mac, vf->mac.data, vf->mac.len); - NLA_PUT (nlmsg, IFLA_VF_MAC, sizeof (ivm), &ivm); - } - - if (vf->min_tx_rate || vf->max_tx_rate) { - struct _ifla_vf_rate ivr = { 0 }; - - ivr.vf = vf->index; - ivr.min_tx_rate = vf->min_tx_rate; - ivr.max_tx_rate = vf->max_tx_rate; - NLA_PUT (nlmsg, IFLA_VF_RATE, sizeof (ivr), &ivr); - } - - /* Kernel only supports one VLAN per VF now. If this - * changes in the future, we need to figure out how to - * clear existing VLANs and set new ones in one message - * with the new API.*/ - if (vf->num_vlans > 1) { - _LOGW ("multiple VLANs per VF are not supported at the moment"); - return FALSE; - } else { - struct _ifla_vf_vlan_info ivvi = { 0 }; - - if (!(vlan_list = nla_nest_start (nlmsg, IFLA_VF_VLAN_LIST))) - goto nla_put_failure; - - ivvi.vf = vf->index; - if (vf->num_vlans == 1) { - ivvi.vlan = vf->vlans[0].id; - ivvi.qos = vf->vlans[0].qos; - ivvi.vlan_proto = htons (vf->vlans[0].proto_ad ? ETH_P_8021AD : ETH_P_8021Q); - } else { - /* Clear existing VLAN */ - ivvi.vlan = 0; - ivvi.qos = 0; - ivvi.vlan_proto = htons (ETH_P_8021Q); - } - - NLA_PUT (nlmsg, IFLA_VF_VLAN_INFO, sizeof (ivvi), &ivvi); - nla_nest_end (nlmsg, vlan_list); - } - nla_nest_end (nlmsg, info); - } - nla_nest_end (nlmsg, list); - - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; -nla_put_failure: - g_return_val_if_reached (FALSE); -} - static char * link_get_physical_port_id (NMPlatform *platform, int ifindex) { @@ -5944,7 +5213,7 @@ link_get_dev_id (NMPlatform *platform, int ifindex) 16, 0, G_MAXUINT16, 0); } -static gboolean +static int vlan_add (NMPlatform *platform, const char *name, int parent, @@ -5960,6 +5229,10 @@ vlan_add (NMPlatform *platform, G_STATIC_ASSERT (NM_VLAN_FLAG_MVRP == (guint32) VLAN_FLAG_MVRP); vlan_flags &= (guint32) NM_VLAN_FLAGS_ALL; + + _LOGD ("link: add vlan '%s', parent %d, vlan id %d, flags %X", + name, parent, vlan_id, (unsigned) vlan_flags); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -5986,7 +5259,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_gre_add (NMPlatform *platform, const char *name, const NMPlatformLnkGre *props, @@ -5995,6 +5268,14 @@ link_gre_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "gre", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6008,7 +5289,7 @@ link_gre_add (NMPlatform *platform, if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) goto nla_put_failure; - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->is_tap ? "gretap" : "gre"); + NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "gre"); if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA))) goto nla_put_failure; @@ -6022,20 +5303,18 @@ link_gre_add (NMPlatform *platform, NLA_PUT_U8 (nlmsg, IFLA_GRE_PMTUDISC, !!props->path_mtu_discovery); NLA_PUT_U32 (nlmsg, IFLA_GRE_IKEY, htonl (props->input_key)); NLA_PUT_U32 (nlmsg, IFLA_GRE_OKEY, htonl (props->output_key)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); + NLA_PUT_U32 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); + NLA_PUT_U32 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, - name, nlmsg, out_link); + return do_add_link_with_lookup (platform, NM_LINK_TYPE_GRE, name, nlmsg, out_link); nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_ip6tnl_add (NMPlatform *platform, const char *name, const NMPlatformLnkIp6Tnl *props, @@ -6044,9 +5323,15 @@ link_ip6tnl_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; guint32 flowinfo; - g_return_val_if_fail (!props->is_gre, FALSE); + _LOGD (LOG_FMT_IP_TUNNEL, + "ip6tnl", + name, + props->parent_ifindex, + nm_utils_inet6_ntop (&props->local, NULL), + nm_utils_inet6_ntop (&props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6091,69 +5376,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean -link_ip6gre_add (NMPlatform *platform, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *info; - struct nlattr *data; - guint32 flowinfo; - - g_return_val_if_fail (props->is_gre, FALSE); - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE | NLM_F_EXCL, - 0, - name, - 0, - 0); - if (!nlmsg) - return FALSE; - - if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) - goto nla_put_failure; - - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->is_tap ? "ip6gretap" : "ip6gre"); - - if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA))) - goto nla_put_failure; - - if (props->parent_ifindex) - NLA_PUT_U32 (nlmsg, IFLA_GRE_LINK, props->parent_ifindex); - - NLA_PUT_U32 (nlmsg, IFLA_GRE_IKEY, htonl (props->input_key)); - NLA_PUT_U32 (nlmsg, IFLA_GRE_OKEY, htonl (props->output_key)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); - - if (memcmp (&props->local, &in6addr_any, sizeof (in6addr_any))) - NLA_PUT (nlmsg, IFLA_GRE_LOCAL, sizeof (props->local), &props->local); - if (memcmp (&props->remote, &in6addr_any, sizeof (in6addr_any))) - NLA_PUT (nlmsg, IFLA_GRE_REMOTE, sizeof (props->remote), &props->remote); - - NLA_PUT_U8 (nlmsg, IFLA_GRE_TTL, props->ttl); - NLA_PUT_U8 (nlmsg, IFLA_GRE_ENCAP_LIMIT, props->encap_limit); - - flowinfo = props->flow_label & IP6_FLOWINFO_FLOWLABEL_MASK; - flowinfo |= (props->tclass << IP6_FLOWINFO_TCLASS_SHIFT) - & IP6_FLOWINFO_TCLASS_MASK; - NLA_PUT_U32 (nlmsg, IFLA_GRE_FLOWINFO, htonl (flowinfo)); - NLA_PUT_U32 (nlmsg, IFLA_GRE_FLAGS, props->flags); - - nla_nest_end (nlmsg, data); - nla_nest_end (nlmsg, info); - - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - name, nlmsg, out_link); -nla_put_failure: - g_return_val_if_reached (FALSE); -} - -static gboolean +static int link_ipip_add (NMPlatform *platform, const char *name, const NMPlatformLnkIpIp *props, @@ -6162,6 +5385,14 @@ link_ipip_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "ipip", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6196,7 +5427,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_macsec_add (NMPlatform *platform, const char *name, int parent, @@ -6207,6 +5438,11 @@ link_macsec_add (NMPlatform *platform, struct nlattr *info; struct nlattr *data; + _LOGD ("adding macsec '%s' parent %u sci %llx", + name, + parent, + (unsigned long long) props->sci); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6253,7 +5489,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_macvlan_add (NMPlatform *platform, const char *name, int parent, @@ -6264,6 +5500,12 @@ link_macvlan_add (NMPlatform *platform, struct nlattr *info; struct nlattr *data; + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", + name, + parent, + props->mode); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6296,7 +5538,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_sit_add (NMPlatform *platform, const char *name, const NMPlatformLnkSit *props, @@ -6305,6 +5547,14 @@ link_sit_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "sit", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6408,6 +5658,9 @@ link_vxlan_add (NMPlatform *platform, g_return_val_if_fail (props, FALSE); + _LOGD ("link: add vxlan '%s', parent %d, vxlan id %d", + name, props->parent_ifindex, props->id); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6465,41 +5718,6 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean -link_6lowpan_add (NMPlatform *platform, - const char *name, - int parent, - const NMPlatformLink **out_link) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *info; - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE | NLM_F_EXCL, - 0, - name, - 0, - 0); - if (!nlmsg) - return FALSE; - - NLA_PUT_U32 (nlmsg, IFLA_LINK, parent); - - if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) - goto nla_put_failure; - - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "lowpan"); - - nla_nest_end (nlmsg, info); - - return do_add_link_with_lookup (platform, - NM_LINK_TYPE_6LOWPAN, - name, nlmsg, out_link); -nla_put_failure: - g_return_val_if_reached (FALSE); -} - - static void _vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map, gboolean reset_all, @@ -6594,6 +5812,9 @@ link_vlan_change (NMPlatform *platform, guint new_n_egress_map = 0; gs_free NMVlanQosMapping *new_ingress_map = NULL; gs_free NMVlanQosMapping *new_egress_map = NULL; + char s_flags[64]; + char s_ingress[256]; + char s_egress[256]; obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex); if ( !obj_cache @@ -6624,6 +5845,26 @@ link_vlan_change (NMPlatform *platform, &new_egress_map, &new_n_egress_map); + _LOGD ("link: change %d: vlan:%s%s%s", + ifindex, + flags_mask + ? nm_sprintf_buf (s_flags, " flags 0x%x/0x%x", (unsigned) flags_set, (unsigned) flags_mask) + : "", + new_n_ingress_map + ? nm_platform_vlan_qos_mapping_to_string (" ingress-qos-map", + new_ingress_map, + new_n_ingress_map, + s_ingress, + sizeof (s_ingress)) + : "", + new_n_egress_map + ? nm_platform_vlan_qos_mapping_to_string (" egress-qos-map", + new_egress_map, + new_n_egress_map, + s_egress, + sizeof (s_egress)) + : ""); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -6650,6 +5891,8 @@ link_enslave (NMPlatform *platform, int master, int slave) nm_auto_nlmsg struct nl_msg *nlmsg = NULL; int ifindex = slave; + _LOGD ("link: change %d: enslave: master %d", slave, master); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -6737,26 +5980,43 @@ infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) /*****************************************************************************/ -static GObject * -get_ext_data (NMPlatform *platform, int ifindex) +static WifiData * +wifi_get_wifi_data (NMPlatform *platform, int ifindex) { - const NMPObject *obj; + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + const NMPlatformLink *pllink; + WifiData *wifi_data; + + wifi_data = g_hash_table_lookup (priv->wifi_data, GINT_TO_POINTER (ifindex)); + pllink = nm_platform_link_get (platform, ifindex); + + if (!wifi_data) { + if (pllink) { + if (pllink->type == NM_LINK_TYPE_WIFI) + wifi_data = wifi_utils_init (ifindex, TRUE); + else if (pllink->type == NM_LINK_TYPE_OLPC_MESH) { + /* The kernel driver now uses nl80211, but we force use of WEXT because + * the cfg80211 interactions are not quite ready to support access to + * mesh control through nl80211 just yet. + */ +#if HAVE_WEXT + wifi_data = wifi_wext_init (ifindex, FALSE); +#endif + } - obj = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex); - if (!obj) - return NULL; + if (wifi_data) + g_hash_table_insert (priv->wifi_data, GINT_TO_POINTER (ifindex), wifi_data); + } + } - return obj->_link.ext_data; + return wifi_data; } - -/*****************************************************************************/ - #define WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, retval) \ nm_auto_pop_netns NMPNetns *netns = NULL; \ - NMWifiUtils *wifi_data; \ + WifiData *wifi_data; \ if (!nm_platform_netns_push (platform, &netns)) \ return retval; \ - wifi_data = NM_WIFI_UTILS (get_ext_data (platform, ifindex)); \ + wifi_data = wifi_get_wifi_data (platform, ifindex); \ if (!wifi_data) \ return retval; @@ -6765,7 +6025,7 @@ wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabiliti { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); if (caps) - *caps = nm_wifi_utils_get_caps (wifi_data); + *caps = wifi_utils_get_caps (wifi_data); return TRUE; } @@ -6773,70 +6033,63 @@ static gboolean wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_bssid (wifi_data, bssid); + return wifi_utils_get_bssid (wifi_data, bssid); } static guint32 wifi_get_frequency (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_get_freq (wifi_data); + return wifi_utils_get_freq (wifi_data); } static gboolean wifi_get_quality (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_qual (wifi_data); + return wifi_utils_get_qual (wifi_data); } static guint32 wifi_get_rate (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_rate (wifi_data); + return wifi_utils_get_rate (wifi_data); } static NM80211Mode wifi_get_mode (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, NM_802_11_MODE_UNKNOWN); - return nm_wifi_utils_get_mode (wifi_data); + return wifi_utils_get_mode (wifi_data); } static void wifi_set_mode (NMPlatform *platform, int ifindex, NM80211Mode mode) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_set_mode (wifi_data, mode); + wifi_utils_set_mode (wifi_data, mode); } static void wifi_set_powersave (NMPlatform *platform, int ifindex, guint32 powersave) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_set_powersave (wifi_data, powersave); + wifi_utils_set_powersave (wifi_data, powersave); } static guint32 wifi_find_frequency (NMPlatform *platform, int ifindex, const guint32 *freqs) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_find_freq (wifi_data, freqs); + return wifi_utils_find_freq (wifi_data, freqs); } static void wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean running) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_indicate_addressing_running (wifi_data, running); -} - -static NMSettingWirelessWakeOnWLan -wifi_get_wake_on_wlan (NMPlatform *platform, int ifindex) -{ - WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_wake_on_wlan (wifi_data); + wifi_utils_indicate_addressing_running (wifi_data, running); } static gboolean @@ -6844,7 +6097,7 @@ wifi_set_wake_on_wlan (NMPlatform *platform, int ifindex, NMSettingWirelessWakeOnWLan wowl) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_wake_on_wlan (wifi_data, wowl); + return wifi_utils_set_wake_on_wlan (wifi_data, wowl); } /*****************************************************************************/ @@ -6895,56 +6148,21 @@ static guint32 mesh_get_channel (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_get_mesh_channel (wifi_data); + return wifi_utils_get_mesh_channel (wifi_data); } static gboolean mesh_set_channel (NMPlatform *platform, int ifindex, guint32 channel) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_mesh_channel (wifi_data, channel); + return wifi_utils_set_mesh_channel (wifi_data, channel); } static gboolean mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_mesh_ssid (wifi_data, ssid, len); -} - -/*****************************************************************************/ - -#define WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, retval) \ - NMWpanUtils *wpan_data = NM_WPAN_UTILS (get_ext_data (platform, ifindex)); \ - if (!wpan_data) \ - return retval; - -static guint16 -wpan_get_pan_id (NMPlatform *platform, int ifindex) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, G_MAXINT16); - return nm_wpan_utils_get_pan_id (wpan_data); -} - -static gboolean -wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, FALSE); - return nm_wpan_utils_set_pan_id (wpan_data, pan_id); -} - -static guint16 -wpan_get_short_addr (NMPlatform *platform, int ifindex) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, G_MAXINT16); - return nm_wpan_utils_get_short_addr (wpan_data); -} - -static gboolean -wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, FALSE); - return nm_wpan_utils_set_short_addr (wpan_data, short_addr); + return wifi_utils_set_mesh_ssid (wifi_data, ssid, len); } /*****************************************************************************/ @@ -6961,12 +6179,12 @@ link_get_wake_on_lan (NMPlatform *platform, int ifindex) if (type == NM_LINK_TYPE_ETHERNET) return nmp_utils_ethtool_get_wake_on_lan (ifindex); else if (type == NM_LINK_TYPE_WIFI) { - NMWifiUtils *wifi_data = NM_WIFI_UTILS (get_ext_data (platform, ifindex)); + WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); if (!wifi_data) return FALSE; - return nm_wifi_utils_get_wake_on_wlan (wifi_data) != NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; + return wifi_utils_get_wowlan (wifi_data); } else return FALSE; } @@ -7780,14 +6998,6 @@ handle_udev_event (NMUdevClient *udev_client, /*****************************************************************************/ -void -nm_linux_platform_setup (void) -{ - nm_platform_setup (nm_linux_platform_new (FALSE, FALSE)); -} - -/*****************************************************************************/ - static void nm_linux_platform_init (NMLinuxPlatform *self) { @@ -7796,6 +7006,7 @@ nm_linux_platform_init (NMLinuxPlatform *self) priv->delayed_action.list_master_connected = g_ptr_array_new (); priv->delayed_action.list_refresh_link = g_ptr_array_new (); priv->delayed_action.list_wait_for_nl_response = g_array_new (FALSE, TRUE, sizeof (DelayedActionWaitForNlResponseData)); + priv->wifi_data = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) wifi_utils_unref); } static void @@ -7825,18 +7036,6 @@ constructed (GObject *_object) nmp_netns_get_current () == nmp_netns_get_initial () ? "/main" : "")), nm_platform_get_use_udev (platform) ? "use" : "no"); - - priv->genl = nl_socket_alloc (); - g_assert (priv->genl); - - nle = nl_connect (priv->genl, NETLINK_GENERIC); - if (nle) { - _LOGE ("unable to connect the generic netlink socket \"%s\" (%d)", - nl_geterror (nle), -nle); - nl_socket_free (priv->genl); - priv->genl = NULL; - } - priv->nlh = nl_socket_alloc (); g_assert (priv->nlh); @@ -7928,22 +7127,6 @@ constructed (GObject *_object) } } -NMPlatform * -nm_linux_platform_new (gboolean log_with_ptr, gboolean netns_support) -{ - gboolean use_udev = FALSE; - - if ( nmp_netns_is_initial () - && access ("/sys", W_OK) == 0) - use_udev = TRUE; - - return g_object_new (NM_TYPE_LINUX_PLATFORM, - NM_PLATFORM_LOG_WITH_PTR, log_with_ptr, - NM_PLATFORM_USE_UDEV, use_udev, - NM_PLATFORM_NETNS_SUPPORT, netns_support, - NULL); -} - static void dispose (GObject *object) { @@ -7971,12 +7154,12 @@ finalize (GObject *object) g_ptr_array_unref (priv->delayed_action.list_refresh_link); g_array_unref (priv->delayed_action.list_wait_for_nl_response); - nl_socket_free (priv->genl); - g_source_remove (priv->event_id); g_io_channel_unref (priv->event_channel); nl_socket_free (priv->nlh); + g_hash_table_unref (priv->wifi_data); + if (priv->sysctl_get_prev_values) { sysctl_clear_cache_list = g_slist_remove (sysctl_clear_cache_list, object); g_hash_table_destroy (priv->sysctl_get_prev_values); @@ -8022,8 +7205,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_permanent_address = link_get_permanent_address; platform_class->link_set_mtu = link_set_mtu; platform_class->link_set_name = link_set_name; - platform_class->link_set_sriov_params = link_set_sriov_params; - platform_class->link_set_sriov_vfs = link_set_sriov_vfs; + platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; platform_class->link_get_physical_port_id = link_get_physical_port_id; platform_class->link_get_dev_id = link_get_dev_id; @@ -8056,27 +7238,19 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->wifi_set_powersave = wifi_set_powersave; platform_class->wifi_find_frequency = wifi_find_frequency; platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running; - platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan; platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan; platform_class->mesh_get_channel = mesh_get_channel; platform_class->mesh_set_channel = mesh_set_channel; platform_class->mesh_set_ssid = mesh_set_ssid; - platform_class->wpan_get_pan_id = wpan_get_pan_id; - platform_class->wpan_set_pan_id = wpan_set_pan_id; - platform_class->wpan_get_short_addr = wpan_get_short_addr; - platform_class->wpan_set_short_addr = wpan_set_short_addr; - platform_class->link_gre_add = link_gre_add; platform_class->link_ip6tnl_add = link_ip6tnl_add; - platform_class->link_ip6gre_add = link_ip6gre_add; platform_class->link_macsec_add = link_macsec_add; platform_class->link_macvlan_add = link_macvlan_add; platform_class->link_ipip_add = link_ipip_add; platform_class->link_sit_add = link_sit_add; platform_class->link_tun_add = link_tun_add; - platform_class->link_6lowpan_add = link_6lowpan_add; platform_class->object_delete = object_delete; platform_class->ip4_address_add = ip4_address_add; diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c index 3e2ad911..4cb19780 100644 --- a/src/platform/nm-netlink.c +++ b/src/platform/nm-netlink.c @@ -52,6 +52,7 @@ struct nl_msg { struct ucred nm_creds; struct nlmsghdr * nm_nlh; size_t nm_size; + int nm_refcnt; }; struct nl_sock { @@ -83,18 +84,18 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_geterror, int, ) const char * -nl_geterror (int nlerr) +nl_geterror (int err) { const char *s; - nlerr = nl_errno (nlerr); + err = nl_errno (err); - if (nlerr >= _NLE_BASE) { - s = _geterror (nlerr); + if (err >= _NLE_BASE) { + s = _geterror (err); if (s) return s; } - return g_strerror (nlerr); + return g_strerror (err); } /*****************************************************************************/ @@ -251,13 +252,27 @@ nlmsg_reserve (struct nl_msg *n, size_t len, int pad) n->nm_nlh->nlmsg_len += tlen; if (tlen > len) - memset (buf + len, 0, tlen - len); + memset(buf + len, 0, tlen - len); return buf; } /*****************************************************************************/ +static int + get_default_page_size (void) +{ + static int val = 0; + int v; + + if (G_UNLIKELY (val == 0)) { + v = getpagesize (); + g_assert (v > 0); + val = v; + } + return val; +} + struct nlattr * nla_reserve (struct nl_msg *msg, int attrtype, int attrlen) { @@ -267,38 +282,22 @@ nla_reserve (struct nl_msg *msg, int attrtype, int attrlen) if (attrlen < 0) return NULL; - tlen = NLMSG_ALIGN (msg->nm_nlh->nlmsg_len) + nla_total_size (attrlen); + tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen); if (tlen > msg->nm_size) return NULL; - nla = (struct nlattr *) nlmsg_tail (msg->nm_nlh); + nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh); nla->nla_type = attrtype; - nla->nla_len = nla_attr_size (attrlen); + nla->nla_len = nla_attr_size(attrlen); if (attrlen) - memset ((unsigned char *) nla + nla->nla_len, 0, nla_padlen (attrlen)); + memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen)); msg->nm_nlh->nlmsg_len = tlen; return nla; } -/*****************************************************************************/ - -static int -get_default_page_size (void) -{ - static int val = 0; - int v; - - if (G_UNLIKELY (val == 0)) { - v = getpagesize (); - g_assert (v > 0); - val = v; - } - return val; -} - struct nl_msg * nlmsg_alloc_size (size_t len) { @@ -309,6 +308,7 @@ nlmsg_alloc_size (size_t len) nm = g_slice_new0 (struct nl_msg); + nm->nm_refcnt = 1; nm->nm_protocol = -1; nm->nm_size = len; nm->nm_nlh = g_malloc0 (len); @@ -331,40 +331,48 @@ nlmsg_alloc (void) return nlmsg_alloc_size (get_default_page_size ()); } +/** + * Allocate a new netlink message with maximum payload size specified. + */ struct nl_msg * -nlmsg_alloc_convert (struct nlmsghdr *hdr) +nlmsg_alloc_inherit (struct nlmsghdr *hdr) { struct nl_msg *nm; - nm = nlmsg_alloc_size (NLMSG_ALIGN (hdr->nlmsg_len)); - memcpy (nm->nm_nlh, hdr, hdr->nlmsg_len); + nm = nlmsg_alloc (); + if (hdr) { + struct nlmsghdr *new = nm->nm_nlh; + + new->nlmsg_type = hdr->nlmsg_type; + new->nlmsg_flags = hdr->nlmsg_flags; + new->nlmsg_seq = hdr->nlmsg_seq; + new->nlmsg_pid = hdr->nlmsg_pid; + } + return nm; } struct nl_msg * -nlmsg_alloc_simple (int nlmsgtype, int flags) +nlmsg_alloc_convert (struct nlmsghdr *hdr) { struct nl_msg *nm; - struct nlmsghdr *new; - nm = nlmsg_alloc (); - new = nm->nm_nlh; - new->nlmsg_type = nlmsgtype; - new->nlmsg_flags = flags; + nm = nlmsg_alloc_size (NLMSG_ALIGN (hdr->nlmsg_len)); + memcpy(nm->nm_nlh, hdr, hdr->nlmsg_len); return nm; } -void nlmsg_free (struct nl_msg *msg) +struct nl_msg * +nlmsg_alloc_simple (int nlmsgtype, int flags) { - if (!msg) - return; + struct nlmsghdr nlh = { + .nlmsg_type = nlmsgtype, + .nlmsg_flags = flags, + }; - g_free (msg->nm_nlh); - g_slice_free (struct nl_msg, msg); + return nlmsg_alloc_inherit (&nlh); } -/*****************************************************************************/ - int nlmsg_append (struct nl_msg *n, void *data, size_t len, int pad) { @@ -374,21 +382,19 @@ nlmsg_append (struct nl_msg *n, void *data, size_t len, int pad) if (tmp == NULL) return -ENOMEM; - memcpy (tmp, data, len); + memcpy(tmp, data, len); return 0; } -/*****************************************************************************/ - int nlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy) { - if (!nlmsg_valid_hdr (nlh, hdrlen)) + if (!nlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; - return nla_parse (tb, maxtype, nlmsg_attrdata (nlh, hdrlen), - nlmsg_attrlen (nlh, hdrlen), policy); + return nla_parse (tb, maxtype, nlmsg_attrdata(nlh, hdrlen), + nlmsg_attrlen(nlh, hdrlen), policy); } struct nlmsghdr * @@ -406,8 +412,8 @@ nlmsg_put (struct nl_msg *n, uint32_t pid, uint32_t seq, nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; - if ( payload > 0 - && nlmsg_reserve (n, payload, NLMSG_ALIGNTO) == NULL) + if (payload > 0 && + nlmsg_reserve(n, payload, NLMSG_ALIGNTO) == NULL) return NULL; return nlh; @@ -418,8 +424,8 @@ nla_get_u64 (const struct nlattr *nla) { uint64_t tmp = 0; - if (nla && nla_len (nla) >= sizeof (tmp)) - memcpy (&tmp, nla_data (nla), sizeof (tmp)); + if (nla && nla_len(nla) >= sizeof (tmp)) + memcpy(&tmp, nla_data(nla), sizeof (tmp)); return tmp; } @@ -427,8 +433,8 @@ nla_get_u64 (const struct nlattr *nla) size_t nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize) { - size_t srclen = nla_len (nla); - const char *src = nla_data (nla); + size_t srclen = nla_len(nla); + const char *src = nla_data(nla); if (srclen > 0 && src[srclen - 1] == '\0') srclen--; @@ -436,8 +442,8 @@ nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize) if (dstsize > 0) { size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; - memset (dst, 0, dstsize); - memcpy (dst, src, len); + memset(dst, 0, dstsize); + memcpy(dst, src, len); } return srclen; @@ -452,7 +458,7 @@ nla_memcpy (void *dest, const struct nlattr *src, int count) return 0; minlen = NM_MIN (count, (int) nla_len (src)); - memcpy (dest, nla_data (src), minlen); + memcpy(dest, nla_data(src), minlen); return minlen; } @@ -462,7 +468,7 @@ nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data) { struct nlattr *nla; - nla = nla_reserve (msg, attrtype, datalen); + nla = nla_reserve(msg, attrtype, datalen); if (!nla) { if (datalen < 0) g_return_val_if_reached (-NLE_BUG); @@ -471,7 +477,7 @@ nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data) } if (datalen > 0) - memcpy (nla_data (nla), data, datalen); + memcpy (nla_data(nla), data, datalen); return 0; } @@ -495,21 +501,21 @@ nla_nest_cancel (struct nl_msg *msg, const struct nlattr *attr) { ssize_t len; - len = (char *) nlmsg_tail (msg->nm_nlh) - (char *) attr; + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) attr; if (len < 0) g_return_if_reached (); else if (len > 0) { msg->nm_nlh->nlmsg_len -= len; - memset (nlmsg_tail (msg->nm_nlh), 0, len); + memset(nlmsg_tail(msg->nm_nlh), 0, len); } } struct nlattr * nla_nest_start (struct nl_msg *msg, int attrtype) { - struct nlattr *start = (struct nlattr *) nlmsg_tail (msg->nm_nlh); + struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh); - if (nla_put (msg, attrtype, 0, NULL) < 0) + if (nla_put(msg, attrtype, 0, NULL) < 0) return NULL; return start; @@ -520,7 +526,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) { size_t pad, len; - len = (char *) nlmsg_tail (msg->nm_nlh) - (char *) start; + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start; if ( len > USHRT_MAX || (!keep_empty && len == NLA_HDRLEN)) { @@ -528,7 +534,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) * Max nlattr size exceeded or empty nested attribute, trim the * attribute header again */ - nla_nest_cancel (msg, start); + nla_nest_cancel(msg, start); /* Return error only if nlattr size was exceeded */ return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE; @@ -536,7 +542,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) start->nla_len = len; - pad = NLMSG_ALIGN (msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; + pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; if (pad > 0) { /* * Data inside attribute does not end at a alignment boundry. @@ -544,7 +550,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) * the message. nlmsg_reserve() may never fail in this situation, * the allocate message buffer must be a multiple of NLMSG_ALIGNTO. */ - if (!nlmsg_reserve (msg, pad, 0)) + if (!nlmsg_reserve(msg, pad, 0)) g_return_val_if_reached (-NLE_BUG); } @@ -572,7 +578,7 @@ validate_nla (const struct nlattr *nla, int maxtype, { const struct nla_policy *pt; unsigned int minlen = 0; - int type = nla_type (nla); + int type = nla_type(nla); if (type < 0 || type > maxtype) return 0; @@ -587,15 +593,15 @@ validate_nla (const struct nlattr *nla, int maxtype, else if (pt->type != NLA_UNSPEC) minlen = nla_attr_minlen[pt->type]; - if (nla_len (nla) < minlen) + if (nla_len(nla) < minlen) return -NLE_UNSPEC; - if (pt->maxlen && nla_len (nla) > pt->maxlen) + if (pt->maxlen && nla_len(nla) > pt->maxlen) return -NLE_UNSPEC; if (pt->type == NLA_STRING) { - const char *data = nla_data (nla); - if (data[nla_len (nla) - 1] != '\0') + const char *data = nla_data(nla); + if (data[nla_len(nla) - 1] != '\0') return -NLE_UNSPEC; } @@ -607,32 +613,48 @@ nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy) { struct nlattr *nla; - int rem, nlerr; + int rem, err; - memset (tb, 0, sizeof (struct nlattr *) * (maxtype + 1)); + memset(tb, 0, sizeof (struct nlattr *) * (maxtype + 1)); - nla_for_each_attr (nla, head, len, rem) { - int type = nla_type (nla); + nla_for_each_attr(nla, head, len, rem) { + int type = nla_type(nla); if (type > maxtype) continue; if (policy) { - nlerr = validate_nla (nla, maxtype, policy); - if (nlerr < 0) + err = validate_nla(nla, maxtype, policy); + if (err < 0) goto errout; } tb[type] = nla; } - nlerr = 0; + err = 0; errout: - return nlerr; + return err; } /*****************************************************************************/ +void nlmsg_free (struct nl_msg *msg) +{ + if (!msg) + return; + + if (msg->nm_refcnt < 1) + g_return_if_reached (); + + msg->nm_refcnt--; + + if (msg->nm_refcnt <= 0) { + g_free (msg->nm_nlh); + g_slice_free (struct nl_msg, msg); + } +} + int nlmsg_get_proto (struct nl_msg *msg) { @@ -791,7 +813,7 @@ int genl_ctrl_resolve (struct nl_sock *sk, const char *name) { nm_auto_nlmsg struct nl_msg *msg = NULL; - int nlerr; + int result = -ENOMEM; gint32 response_data = -1; const struct nl_cb cb = { .valid_cb = _genl_parse_getfamily, @@ -802,29 +824,31 @@ genl_ctrl_resolve (struct nl_sock *sk, const char *name) if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1)) - return -ENOMEM; + goto out; - nlerr = nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name); - if (nlerr < 0) - return nlerr; + if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0) + goto out; - nlerr = nl_send_auto (sk, msg); - if (nlerr < 0) - return nlerr; + result = nl_send_auto (sk, msg); + if (result < 0) + goto out; - nlerr = nl_recvmsgs (sk, &cb); - if (nlerr < 0) - return nlerr; + result = nl_recvmsgs (sk, &cb); + if (result < 0) + goto out; /* If search was successful, request may be ACKed after data */ - nlerr = nl_wait_for_ack (sk, NULL); - if (nlerr < 0) - return nlerr; + result = nl_wait_for_ack (sk, NULL); + if (result < 0) + goto out; - if (response_data < 0) - return -NLE_UNSPEC; + if (response_data > 0) + result = response_data; + else + result = -ENOENT; - return response_data; +out: + return result; } /*****************************************************************************/ @@ -839,7 +863,7 @@ nl_socket_alloc (void) sk->s_fd = -1; sk->s_local.nl_family = AF_NETLINK; sk->s_peer.nl_family = AF_NETLINK; - sk->s_seq_expect = sk->s_seq_next = time (NULL); + sk->s_seq_expect = sk->s_seq_next = time(NULL); return sk; } @@ -914,7 +938,7 @@ nl_socket_set_nonblocking (const struct nl_sock *sk) if (sk->s_fd == -1) return -NLE_BAD_SOCK; - if (fcntl (sk->s_fd, F_SETFL, O_NONBLOCK) < 0) + if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) return -nl_syserr2nlerr (errno); return 0; @@ -958,27 +982,25 @@ nl_socket_add_memberships (struct nl_sock *sk, int group, ...) if (sk->s_fd == -1) return -NLE_BAD_SOCK; - va_start (ap, group); + va_start(ap, group); while (group != 0) { if (group < 0) { - va_end (ap); + va_end(ap); g_return_val_if_reached (-NLE_BUG); } err = setsockopt (sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof (group)); if (err < 0) { - int errsv = errno; - - va_end (ap); - return -nl_syserr2nlerr (errsv); + va_end(ap); + return -nl_syserr2nlerr (errno); } - group = va_arg (ap, int); + group = va_arg(ap, int); } - va_end (ap); + va_end(ap); return 0; } @@ -1008,7 +1030,7 @@ void nl_socket_disable_msg_peek (struct nl_sock *sk) int nl_connect (struct nl_sock *sk, int protocol) { - int err, nlerr; + int err; socklen_t addrlen; struct sockaddr_nl local = { 0 }; @@ -1017,12 +1039,12 @@ nl_connect (struct nl_sock *sk, int protocol) sk->s_fd = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); if (sk->s_fd < 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } - nlerr = nl_socket_set_buffer_size (sk, 0, 0); - if (nlerr < 0) + err = nl_socket_set_buffer_size(sk, 0, 0); + if (err < 0) goto errout; nm_assert (sk->s_local.nl_pid == 0); @@ -1030,7 +1052,7 @@ nl_connect (struct nl_sock *sk, int protocol) err = bind (sk->s_fd, (struct sockaddr*) &sk->s_local, sizeof (sk->s_local)); if (err != 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } @@ -1038,17 +1060,17 @@ nl_connect (struct nl_sock *sk, int protocol) err = getsockname (sk->s_fd, (struct sockaddr *) &local, &addrlen); if (err < 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } if (addrlen != sizeof (local)) { - nlerr = -NLE_UNSPEC; + err = -NLE_UNSPEC; goto errout; } if (local.nl_family != AF_NETLINK) { - nlerr = -NLE_UNSPEC; + err = -NLE_UNSPEC; goto errout; } @@ -1059,10 +1081,10 @@ nl_connect (struct nl_sock *sk, int protocol) errout: if (sk->s_fd != -1) { - close (sk->s_fd); + close(sk->s_fd); sk->s_fd = -1; } - return nlerr; + return err; } /*****************************************************************************/ @@ -1078,7 +1100,7 @@ _cb_init (struct nl_cb *dst, const struct nl_cb *src) memset (dst, 0, sizeof (*dst)); } -static int ack_wait_handler (struct nl_msg *msg, void *arg) +static int ack_wait_handler(struct nl_msg *msg, void *arg) { return NL_STOP; } @@ -1099,22 +1121,16 @@ do { \ const struct nl_cb *_cb = (cb); \ \ if (_cb->type##_cb) { \ - /* the returned value here must be either a negative - * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ \ - nlerr = _cb->type##_cb ((msg), _cb->type##_arg); \ - switch (nlerr) { \ + err = _cb->type##_cb ((msg), _cb->type##_arg); \ + switch (err) { \ case NL_OK: \ - nlerr = 0; \ + err = 0; \ break; \ case NL_SKIP: \ goto skip; \ case NL_STOP: \ goto stop; \ default: \ - if (nlerr >= 0) { \ - nm_assert_not_reached (); \ - nlerr = -NLE_BUG; \ - } \ goto out; \ } \ } \ @@ -1123,7 +1139,7 @@ do { \ int nl_recvmsgs (struct nl_sock *sk, const struct nl_cb *cb) { - int n, nlerr = 0, multipart = 0, interrupted = 0, nrecv = 0; + int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0; gs_free unsigned char *buf = NULL; struct nlmsghdr *hdr; struct sockaddr_nl nla = { 0 }; @@ -1148,9 +1164,9 @@ continue_reading: nrecv++; /* Only do sequence checking if auto-ack mode is enabled */ - if (! (sk->s_flags & NL_NO_AUTO_ACK)) { + if (!(sk->s_flags & NL_NO_AUTO_ACK)) { if (hdr->nlmsg_seq != sk->s_seq_expect) { - nlerr = -NLE_SEQ_MISMATCH; + err = -NLE_SEQ_MISMATCH; goto out; } } @@ -1182,7 +1198,7 @@ continue_reading: * this action by skipping this packet. */ if (hdr->nlmsg_type == NLMSG_DONE) { multipart = 0; - NL_CB_CALL (cb, finish, msg); + NL_CB_CALL(cb, finish, msg); } /* Message to be ignored, the default action is to @@ -1196,53 +1212,50 @@ continue_reading: * quit parsing. The user may overrule this action by retuning * NL_SKIP or NL_PROCEED (dangerous) */ else if (hdr->nlmsg_type == NLMSG_OVERRUN) { - nlerr = -NLE_MSG_OVERFLOW; + err = -NLE_MSG_OVERFLOW; goto out; } /* Message carries a nlmsgerr */ else if (hdr->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *e = nlmsg_data (hdr); + struct nlmsgerr *e = nlmsg_data(hdr); - if (hdr->nlmsg_len < nlmsg_size (sizeof (*e))) { + if (hdr->nlmsg_len < nlmsg_size(sizeof (*e))) { /* Truncated error message, the default action * is to stop parsing. The user may overrule * this action by returning NL_SKIP or * NL_PROCEED (dangerous) */ - nlerr = -NLE_MSG_TRUNC; + err = -NLE_MSG_TRUNC; goto out; } if (e->error) { /* Error message reported back from kernel. */ if (cb->err_cb) { - /* the returned value here must be either a negative - * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ - nlerr = cb->err_cb (&nla, e, - cb->err_arg); - if (nlerr < 0) + err = cb->err_cb (&nla, e, + cb->err_arg); + if (err < 0) goto out; - else if (nlerr == NL_SKIP) + else if (err == NL_SKIP) goto skip; - else if (nlerr == NL_STOP) { - nlerr = -nl_syserr2nlerr (e->error); + else if (err == NL_STOP) { + err = -e->error; goto out; } - nm_assert (nlerr == NL_OK); } else { - nlerr = -nl_syserr2nlerr (e->error); + err = -e->error; goto out; } } else - NL_CB_CALL (cb, ack, msg); + NL_CB_CALL(cb, ack, msg); } else { /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no * effect on this. */ - NL_CB_CALL (cb, valid, msg); + NL_CB_CALL(cb, valid, msg); } skip: - nlerr = 0; - hdr = nlmsg_next (hdr, &n); + err = 0; + hdr = nlmsg_next(hdr, &n); } if (multipart) { @@ -1254,14 +1267,13 @@ skip: } stop: - nlerr = 0; + err = 0; out: if (interrupted) - nlerr = -NLE_DUMP_INTR; + err = -NLE_DUMP_INTR; - nm_assert (nlerr <= 0); - return nlerr ?: nrecv; + return err ?: nrecv; } int @@ -1274,7 +1286,7 @@ nl_sendmsg (struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) nlmsg_set_src (msg, &sk->s_local); - ret = sendmsg (sk->s_fd, hdr, 0); + ret = sendmsg(sk->s_fd, hdr, 0); if (ret < 0) return -nl_syserr2nlerr (errno); @@ -1292,31 +1304,31 @@ nl_send_iovec (struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsign .msg_iov = iov, .msg_iovlen = iovlen, }; - char buf[CMSG_SPACE (sizeof (struct ucred))]; + char buf[CMSG_SPACE(sizeof (struct ucred))]; /* Overwrite destination if specified in the message itself, defaults * to the peer address of the socket. */ - dst = nlmsg_get_dst (msg); + dst = nlmsg_get_dst(msg); if (dst->nl_family == AF_NETLINK) hdr.msg_name = dst; /* Add credentials if present. */ - creds = nlmsg_get_creds (msg); + creds = nlmsg_get_creds(msg); if (creds != NULL) { struct cmsghdr *cmsg; hdr.msg_control = buf; hdr.msg_controllen = sizeof (buf); - cmsg = CMSG_FIRSTHDR (&hdr); + cmsg = CMSG_FIRSTHDR(&hdr); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = CMSG_LEN (sizeof (struct ucred)); - memcpy (CMSG_DATA (cmsg), creds, sizeof (struct ucred)); + cmsg->cmsg_len = CMSG_LEN(sizeof (struct ucred)); + memcpy(CMSG_DATA(cmsg), creds, sizeof (struct ucred)); } - return nl_sendmsg (sk, msg, &hdr); + return nl_sendmsg(sk, msg, &hdr); } void @@ -1324,9 +1336,9 @@ nl_complete_msg (struct nl_sock *sk, struct nl_msg *msg) { struct nlmsghdr *nlh; - nlh = nlmsg_hdr (msg); + nlh = nlmsg_hdr(msg); if (nlh->nlmsg_pid == NL_AUTO_PORT) - nlh->nlmsg_pid = nl_socket_get_local_port (sk); + nlh->nlmsg_pid = nl_socket_get_local_port(sk); if (nlh->nlmsg_seq == NL_AUTO_SEQ) nlh->nlmsg_seq = sk->s_seq_next++; @@ -1344,18 +1356,18 @@ int nl_send (struct nl_sock *sk, struct nl_msg *msg) { struct iovec iov = { - .iov_base = (void *) nlmsg_hdr (msg), - .iov_len = nlmsg_hdr (msg)->nlmsg_len, + .iov_base = (void *) nlmsg_hdr(msg), + .iov_len = nlmsg_hdr(msg)->nlmsg_len, }; - return nl_send_iovec (sk, msg, &iov, 1); + return nl_send_iovec(sk, msg, &iov, 1); } -int nl_send_auto (struct nl_sock *sk, struct nl_msg *msg) +int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg) { - nl_complete_msg (sk, msg); + nl_complete_msg(sk, msg); - return nl_send (sk, msg); + return nl_send(sk, msg); } int @@ -1385,9 +1397,9 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, flags |= MSG_PEEK | MSG_TRUNC; if (page_size == 0) - page_size = getpagesize () * 4; + page_size = getpagesize() * 4; - iov.iov_len = sk->s_bufsize ?: page_size; + iov.iov_len = sk->s_bufsize ? : page_size; iov.iov_base = g_malloc (iov.iov_len); if ( creds @@ -1397,7 +1409,7 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, } retry: - n = recvmsg (sk->s_fd, &msg, flags); + n = recvmsg(sk->s_fd, &msg, flags); if (!n) { retval = 0; goto abort; @@ -1453,12 +1465,12 @@ retry: if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) { struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) { + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) continue; if (cmsg->cmsg_type != SCM_CREDENTIALS) continue; - tmpcreds = nm_memdup (CMSG_DATA (cmsg), sizeof (*tmpcreds)); + tmpcreds = g_memdup (CMSG_DATA(cmsg), sizeof (*tmpcreds)); break; } } diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h index 1fccddb9..185269ba 100644 --- a/src/platform/nm-netlink.h +++ b/src/platform/nm-netlink.h @@ -52,48 +52,32 @@ #endif static inline int -nl_errno (int nlerr) +nl_errno (int err) { - /* Normalizes an netlink error to be positive. Various API returns negative - * error codes, and this function converts the negative value to its - * positive. + /* the error codes from our netlink implementation are plain errno + * extended with our own error in a particular range starting from + * _NLE_BASE. * - * It's very similar to nm_errno(), but not exactly. The difference is that - * nm_errno() is for plain errno, while nl_errno() is for netlink error numbers. - * Yes, netlink error number are ~almost~ the same as errno, except that a particular - * range (_NLE_BASE, _NLE_BASE_END) is reserved. The difference between the two - * functions is only how G_MININT is mapped. - * - * See also nl_syserr2nlerr() below. */ - return nlerr >= 0 - ? nlerr - : ((nlerr == G_MININT) ? NLE_BUG : -nlerr); + * However, often we encode errors as negative values. This function + * normalizes the error and returns its positive value. */ + return err >= 0 + ? err + : ((err == G_MININT) ? NLE_BUG : -errno); } static inline int -nl_syserr2nlerr (int errsv) +nl_syserr2nlerr (int err) { - /* this maps a native errno to a (always non-negative) netlink error number. - * - * Note that netlink error numbers are embedded into the range of regular - * errno. The only difference is, that netlink error numbers reserve a - * range (_NLE_BASE, _NLE_BASE_END) for their own purpose. - * - * That means, converting an errno to netlink error number means in - * most cases just returning itself (negative values are normalized - * to be positive). Only values G_MININT and [_NLE_BASE, _NLE_BASE_END] - * are coerced to the special value NLE_NATIVE_ERRNO, as they cannot - * otherwise be represented in netlink error number domain. */ - if (errsv == G_MININT) + if (err == G_MININT) return NLE_NATIVE_ERRNO; - if (errsv < 0) - errsv = -errsv; - return (errsv >= _NLE_BASE && errsv < _NLE_BASE_END) + if (err < 0) + err = -err; + return (err >= _NLE_BASE && err < _NLE_BASE_END) ? NLE_NATIVE_ERRNO - : errsv; + : err; } -const char *nl_geterror (int nlerr); +const char *nl_geterror (int err); /*****************************************************************************/ @@ -193,12 +177,6 @@ nla_get_u8 (const struct nlattr *nla) } static inline uint8_t -nla_get_s8 (const struct nlattr *nla) -{ - return *(const int8_t *) nla_data (nla); -} - -static inline uint8_t nla_get_u8_cond (/*const*/ struct nlattr *const*tb, int attr, uint8_t default_val) { nm_assert (tb); @@ -219,12 +197,6 @@ nla_get_u32(const struct nlattr *nla) return *(const uint32_t *) nla_data (nla); } -static inline int32_t -nla_get_s32(const struct nlattr *nla) -{ - return *(const int32_t *) nla_data (nla); -} - uint64_t nla_get_u64 (const struct nlattr *nla); static inline char * @@ -260,18 +232,12 @@ nla_put_string (struct nl_msg *msg, int attrtype, const char *str) #define NLA_PUT_U8(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint8_t, attrtype, value) -#define NLA_PUT_S8(msg, attrtype, value) \ - NLA_PUT_TYPE(msg, int8_t, attrtype, value) - #define NLA_PUT_U16(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint16_t, attrtype, value) #define NLA_PUT_U32(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint32_t, attrtype, value) -#define NLA_PUT_S32(msg, attrtype, value) \ - NLA_PUT_TYPE(msg, int32_t, attrtype, value) - #define NLA_PUT_U64(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint64_t, attrtype, value) @@ -330,6 +296,8 @@ struct nl_msg *nlmsg_alloc (void); struct nl_msg *nlmsg_alloc_size (size_t max); +struct nl_msg *nlmsg_alloc_inherit (struct nlmsghdr *hdr); + struct nl_msg *nlmsg_alloc_convert (struct nlmsghdr *hdr); struct nl_msg *nlmsg_alloc_simple (int nlmsgtype, int flags); diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 216b1547..0d224443 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -36,15 +36,12 @@ #include "nm-utils.h" #include "nm-setting-wired.h" -#include "nm-ethtool-utils.h" #include "nm-core-utils.h" -#define ONOFF(bool_val) ((bool_val) ? "on" : "off") - -/****************************************************************************** +/****************************************************************** * utils - *****************************************************************************/ + ******************************************************************/ extern char *if_indextoname (unsigned __ifindex, char *__ifname); unsigned if_nametoindex (const char *__ifname); @@ -66,45 +63,9 @@ nmp_utils_if_nametoindex (const char *ifname) return if_nametoindex (ifname); } -/*****************************************************************************/ - -typedef struct { - int fd; - int ifindex; - char ifname[IFNAMSIZ]; -} SocketHandle; - -static int -socket_handle_init (SocketHandle *shandle, int ifindex) -{ - if (!nmp_utils_if_indextoname (ifindex, shandle->ifname)) { - shandle->ifindex = 0; - return -ENODEV; - } - - shandle->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (shandle->fd < 0) { - shandle->ifindex = 0; - return -errno; - } - - shandle->ifindex = ifindex; - return 0; -} - -static void -socket_handle_destroy (SocketHandle *shandle) -{ - if (shandle->ifindex) { - shandle->ifindex = 0; - nm_close (shandle->fd); - } -} -#define nm_auto_socket_handle nm_auto(socket_handle_destroy) - -/****************************************************************************** +/****************************************************************** * ethtool - *****************************************************************************/ + ******************************************************************/ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GDRVINFO, "ETHTOOL_GDRVINFO"), @@ -116,7 +77,6 @@ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GSTATS, "ETHTOOL_GSTATS"), NM_UTILS_ENUM2STR (ETHTOOL_GSTRINGS, "ETHTOOL_GSTRINGS"), NM_UTILS_ENUM2STR (ETHTOOL_GWOL, "ETHTOOL_GWOL"), - NM_UTILS_ENUM2STR (ETHTOOL_SFEATURES, "ETHTOOL_SFEATURES"), NM_UTILS_ENUM2STR (ETHTOOL_SSET, "ETHTOOL_SSET"), NM_UTILS_ENUM2STR (ETHTOOL_SWOL, "ETHTOOL_SWOL"), ); @@ -127,8 +87,6 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) return _ethtool_cmd_to_string (*((guint32 *) edata), buf, len); } -/*****************************************************************************/ - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define ethtool_cmd_speed(pedata) ((pedata)->speed) @@ -136,553 +94,117 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) G_STMT_START { (pedata)->speed = (guint16) (speed); } G_STMT_END #endif -static int -ethtool_call_handle (SocketHandle *shandle, gpointer edata) +static gboolean +ethtool_get (int ifindex, gpointer edata) { - struct ifreq ifr = { - .ifr_data = edata, - }; + char ifname[IFNAMSIZ]; char sbuf[50]; - int errsv; - - nm_assert (shandle); - nm_assert (shandle->ifindex); - nm_assert (shandle->ifname[0]); - nm_assert (strlen (shandle->ifname) < IFNAMSIZ); - nm_assert (edata); - - memcpy (ifr.ifr_name, shandle->ifname, IFNAMSIZ); - if (ioctl (shandle->fd, SIOCETHTOOL, &ifr) < 0) { - errsv = errno; - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", - shandle->ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - shandle->ifname, - strerror (errsv)); - return -errsv; - } - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", - shandle->ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - shandle->ifname); - return 0; -} + nm_assert (ifindex > 0); -static int -ethtool_call_ifindex (int ifindex, gpointer edata) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - int r; - char sbuf[50]; - - nm_assert (edata); + /* ethtool ioctl API uses the ifname to refer to an interface. That is racy + * as interfaces can be renamed *sigh*. + * + * Note that we anyway have to verify whether the interface exists, before + * calling ioctl for a non-existing ifname. This is to prevent autoloading + * of kernel modules *sigh*. + * Thus, as we anyway verify the existence of ifname before doing the call, + * go one step further and lookup the ifname everytime anew. + * + * This does not solve the renaming race, but it minimizes the time for + * the race to happen as much as possible. */ - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + if (!nmp_utils_if_indextoname (ifindex, ifname)) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: request fails resolving ifindex: %s", ifindex, _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - g_strerror (-r)); - return r; - } - - return ethtool_call_handle (&shandle, edata); -} - -/*****************************************************************************/ - -static struct ethtool_gstrings * -ethtool_get_stringset (SocketHandle *shandle, int stringset_id) -{ - struct { - struct ethtool_sset_info info; - guint32 sentinel; - } sset_info = { }; - gs_free struct ethtool_gstrings *gstrings = NULL; - guint32 i, len; - - sset_info.info.cmd = ETHTOOL_GSSET_INFO; - sset_info.info.reserved = 0; - sset_info.info.sset_mask = (1ULL << stringset_id); - - if (ethtool_call_handle (shandle, &sset_info) < 0) - return NULL; - if (!sset_info.info.sset_mask) - return NULL; - - len = sset_info.info.data[0]; - - gstrings = g_malloc0 (sizeof (*gstrings) + (len * ETH_GSTRING_LEN)); - gstrings->cmd = ETHTOOL_GSTRINGS; - gstrings->string_set = stringset_id; - gstrings->len = len; - if (gstrings->len > 0) { - if (ethtool_call_handle (shandle, gstrings) < 0) - return NULL; - for (i = 0; i < gstrings->len; i++) { - /* ensure NUL terminated */ - gstrings->data[i * ETH_GSTRING_LEN + (ETH_GSTRING_LEN - 1)] = '\0'; - } - } - - return g_steal_pointer (&gstrings); -} - -static int -ethtool_gstrings_find (const struct ethtool_gstrings *gstrings, const char *needle) -{ - guint32 i; - - /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. - * that means, we cannot possibly request longer names. */ - nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); - - for (i = 0; i < gstrings->len; i++) { - if (nm_streq ((char *) &gstrings->data[i * ETH_GSTRING_LEN], needle)) - return i; - } - return -1; -} - -static int -ethtool_get_stringset_index (SocketHandle *shandle, int stringset_id, const char *needle) -{ - gs_free struct ethtool_gstrings *gstrings = NULL; - - /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. - * that means, we cannot possibly request longer names. */ - nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); - - gstrings = ethtool_get_stringset (shandle, stringset_id); - if (gstrings) - return ethtool_gstrings_find (gstrings, needle); - return -1; -} - -/*****************************************************************************/ - -static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_NUM] = { -#define ETHT_FEAT(eid, ...) \ - { \ - .ethtool_id = eid, \ - .n_kernel_names = NM_NARG (__VA_ARGS__), \ - .kernel_names = ((const char *const[]) { __VA_ARGS__ }), \ - } - - /* the order does only matter for one thing: if it happens that more than one NMEthtoolID - * reference the same kernel-name, then the one that is mentioned *later* will win in - * case these NMEthtoolIDs are set. That mostly only makes sense for ethtool-ids which - * refer to multiple features ("feature-tso"), while also having more specific ids - * ("feature-tx-tcp-segmentation"). */ - - /* names from ethtool utility, which are aliases for multiple features. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", - "tx-scatter-gather-fraglist"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TSO, "tx-tcp-segmentation", - "tx-tcp-ecn-segmentation", - "tx-tcp-mangleid-segmentation", - "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX, "tx-checksum-ipv4", - "tx-checksum-ip-generic", - "tx-checksum-ipv6", - "tx-checksum-fcoe-crc", - "tx-checksum-sctp"), - - /* names from ethtool utility, which are aliases for one feature. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), - - /* names of features, as known by kernel. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), -}; - -/* the number of kernel features that we handle. It essentially is the sum of all - * kernel_names. So, all ethtool-ids that reference exactly one kernel-name - * (_NM_ETHTOOL_ID_FEATURE_NUM) + some extra, for ethtool-ids that are aliases - * for multiple kernel-names. */ -#define N_ETHTOOL_KERNEL_FEATURES (((guint) _NM_ETHTOOL_ID_FEATURE_NUM) + 8u) - -static void -_ASSERT_ethtool_feature_infos (void) -{ -#if NM_MORE_ASSERTS > 10 - guint i, k, n; - bool found[_NM_ETHTOOL_ID_FEATURE_NUM] = { }; - - G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (_ethtool_feature_infos) == _NM_ETHTOOL_ID_FEATURE_NUM); - - n = 0; - for (i = 0; i < G_N_ELEMENTS (_ethtool_feature_infos); i++) { - NMEthtoolFeatureState kstate; - const NMEthtoolFeatureInfo *inf = &_ethtool_feature_infos[i]; - - g_assert (inf->ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST); - g_assert (inf->ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); - g_assert (inf->n_kernel_names > 0); - - for (k = 0; k < i; k++) - g_assert (inf->ethtool_id != _ethtool_feature_infos[k].ethtool_id); - - g_assert (!found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); - found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = TRUE; - - kstate.idx_kernel_name = inf->n_kernel_names - 1; - g_assert ((guint) kstate.idx_kernel_name == (guint) (inf->n_kernel_names - 1)); - - n += inf->n_kernel_names; - for (k = 0; k < inf->n_kernel_names; k++) { - g_assert (nm_utils_strv_find_first ((char **) inf->kernel_names, - k, - inf->kernel_names[k]) < 0); - } - } - - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) - g_assert (found[i]); - - g_assert (n == N_ETHTOOL_KERNEL_FEATURES); -#endif -} - -static NMEthtoolFeatureStates * -ethtool_get_features (SocketHandle *shandle) -{ - gs_free NMEthtoolFeatureStates *states = NULL; - gs_free struct ethtool_gstrings *ss_features = NULL; - - _ASSERT_ethtool_feature_infos (); - - ss_features = ethtool_get_stringset (shandle, ETH_SS_FEATURES); - if (!ss_features) - return NULL; - - if (ss_features->len > 0) { - gs_free struct ethtool_gfeatures *gfeatures = NULL; - guint idx; - const NMEthtoolFeatureState *states_list0 = NULL; - const NMEthtoolFeatureState *const*states_plist0 = NULL; - guint states_plist_n = 0; - - gfeatures = g_malloc0 ( sizeof (struct ethtool_gfeatures) - + (NM_DIV_ROUND_UP (ss_features->len, 32u) * sizeof(gfeatures->features[0]))); - - gfeatures->cmd = ETHTOOL_GFEATURES; - gfeatures->size = NM_DIV_ROUND_UP (ss_features->len, 32u); - if (ethtool_call_handle (shandle, gfeatures) < 0) - return NULL; - - for (idx = 0; idx < G_N_ELEMENTS (_ethtool_feature_infos); idx++) { - const NMEthtoolFeatureInfo *info = &_ethtool_feature_infos[idx]; - guint idx_kernel_name; - - for (idx_kernel_name = 0; idx_kernel_name < info->n_kernel_names; idx_kernel_name++) { - NMEthtoolFeatureState *kstate; - const char *kernel_name = info->kernel_names[idx_kernel_name]; - int i_feature; - guint i_block; - guint32 i_flag; - - i_feature = ethtool_gstrings_find (ss_features, kernel_name); - if (i_feature < 0) - continue; - - i_block = ((guint) i_feature) / 32u; - i_flag = (guint32) (1u << (((guint) i_feature) % 32u)); - - if (!states) { - states = g_malloc0 (sizeof (NMEthtoolFeatureStates) - + (N_ETHTOOL_KERNEL_FEATURES * sizeof (NMEthtoolFeatureState)) - + ((N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)) * sizeof (NMEthtoolFeatureState *))); - states_list0 = &states->states_list[0]; - states_plist0 = (gpointer) &states_list0[N_ETHTOOL_KERNEL_FEATURES]; - states->n_ss_features = ss_features->len; - } - - nm_assert (states->n_states < N_ETHTOOL_KERNEL_FEATURES); - kstate = (NMEthtoolFeatureState *) &states_list0[states->n_states]; - states->n_states++; - - kstate->info = info; - kstate->idx_ss_features = i_feature; - kstate->idx_kernel_name = idx_kernel_name; - kstate->available = !!(gfeatures->features[i_block].available & i_flag); - kstate->requested = !!(gfeatures->features[i_block].requested & i_flag); - kstate->active = !!(gfeatures->features[i_block].active & i_flag); - kstate->never_changed = !!(gfeatures->features[i_block].never_changed & i_flag); - - nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); - - if (!states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) - states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = &states_plist0[states_plist_n]; - ((const NMEthtoolFeatureState **) states_plist0)[states_plist_n] = kstate; - states_plist_n++; - } - - if (states && states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) { - nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); - nm_assert (!states_plist0[states_plist_n]); - states_plist_n++; - } - } - } - - return g_steal_pointer (&states); -} - -NMEthtoolFeatureStates * -nmp_utils_ethtool_get_features (int ifindex) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - NMEthtoolFeatureStates *features; - int r; - - g_return_val_if_fail (ifindex > 0, 0); - - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "get-features", - g_strerror (-r)); + g_strerror (errno)); return FALSE; } - features = ethtool_get_features (&shandle); + { + nm_auto_close int fd = -1; + struct ifreq ifr = { + .ifr_data = edata, + }; - if (!features) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure getting features", - ifindex, - "get-features"); - return NULL; - } - - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: retrieved kernel features", - ifindex, - "get-features"); - return features; -} - -static const char * -_ethtool_feature_state_to_string (char *buf, gsize buf_size, const NMEthtoolFeatureState *s, const char *prefix) -{ - int l; - - l = g_snprintf (buf, buf_size, - "%s %s%s", - prefix ?: "", - ONOFF (s->active), - (!s->available || s->never_changed) - ? ", [fixed]" - : ((s->requested != s->active) - ? (s->requested ? ", [requested on]" : ", [requested off]") - : "")); - nm_assert (l < buf_size); - return buf; -} + memcpy (ifr.ifr_name, ifname, sizeof (ifname)); -gboolean -nmp_utils_ethtool_set_features (int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - gs_free struct ethtool_sfeatures *sfeatures = NULL; - int r; - guint i, j; - struct { - const NMEthtoolFeatureState *f_state; - NMTernary requested; - } set_states[N_ETHTOOL_KERNEL_FEATURES]; - guint set_states_n = 0; - gboolean success = TRUE; - - g_return_val_if_fail (ifindex > 0, 0); - g_return_val_if_fail (features, 0); - g_return_val_if_fail (requested, 0); - - nm_assert (features->n_states <= N_ETHTOOL_KERNEL_FEATURES); - - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { - const NMEthtoolFeatureState *const*states_indexed; - - if (requested[i] == NM_TERNARY_DEFAULT) - continue; - - if (!(states_indexed = features->states_indexed[i])) { - if (do_set) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: set feature %s: skip (not found)", - ifindex, - "set-features", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname); - success = FALSE; - } - continue; + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed creating socket for ioctl: %s", + ifindex, + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname, + g_strerror (errno)); + return FALSE; } - for (j = 0; states_indexed[j]; j++) { - const NMEthtoolFeatureState *s = states_indexed[j]; - char sbuf[255]; - - if (set_states_n >= G_N_ELEMENTS (set_states)) - g_return_val_if_reached (FALSE); - - if (s->never_changed) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s (skip feature marked as never changed)", - ifindex, - "set-features", - do_set ? "set" : "reset", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - s->info->kernel_names[s->idx_kernel_name], - ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), - _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); - continue; - } - - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s", + if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", ifindex, - "set-features", - do_set ? "set" : "reset", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - s->info->kernel_names[s->idx_kernel_name], - ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), - _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); - - if ( do_set - && (!s->available || s->never_changed) - && (s->active != (requested[i] == NM_TERNARY_TRUE))) { - /* we request to change a flag which kernel reported as fixed. - * While the ethtool operation will silently succeed, mark the request - * as failure. */ - success = FALSE; - } - - set_states[set_states_n].f_state = s; - set_states[set_states_n].requested = requested[i]; - set_states_n++; + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname, + strerror (errno)); + return FALSE; } - } - if (set_states_n == 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: no feature requested", + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", ifindex, - "set-features"); + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname); return TRUE; } +} - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "set-features", - g_strerror (-r)); - return FALSE; - } +static int +ethtool_get_stringset_index (int ifindex, int stringset_id, const char *string) +{ + gs_free struct ethtool_sset_info *info = NULL; + gs_free struct ethtool_gstrings *strings = NULL; + guint32 len, i; - sfeatures = g_malloc0 (sizeof (struct ethtool_sfeatures) - + (NM_DIV_ROUND_UP (features->n_ss_features, 32U) * sizeof(sfeatures->features[0]))); - sfeatures->cmd = ETHTOOL_SFEATURES; - sfeatures->size = NM_DIV_ROUND_UP (features->n_ss_features, 32U); + g_return_val_if_fail (ifindex > 0, -1); - for (i = 0; i < set_states_n; i++) { - const NMEthtoolFeatureState *s = set_states[i].f_state; - guint i_block; - guint32 i_flag; - gboolean is_requested; + info = g_malloc0 (sizeof (*info) + sizeof (guint32)); + info->cmd = ETHTOOL_GSSET_INFO; + info->reserved = 0; + info->sset_mask = 1ULL << stringset_id; - i_block = s->idx_ss_features / 32u; - i_flag = (guint32) (1u << (s->idx_ss_features % 32u)); + if (!ethtool_get (ifindex, info)) + return -1; + if (!info->sset_mask) + return -1; - sfeatures->features[i_block].valid |= i_flag; + len = info->data[0]; - if (do_set) - is_requested = (set_states[i].requested == NM_TERNARY_TRUE); - else - is_requested = s->active; + strings = g_malloc0 (sizeof (*strings) + len * ETH_GSTRING_LEN); + strings->cmd = ETHTOOL_GSTRINGS; + strings->string_set = stringset_id; + strings->len = len; + if (!ethtool_get (ifindex, strings)) + return -1; - if (is_requested) - sfeatures->features[i_block].requested |= i_flag; - else - sfeatures->features[i_block].requested &= ~i_flag; - } - - if ((r = ethtool_call_handle (&shandle, sfeatures)) < 0) { - success = FALSE; - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure setting features (%s)", - ifindex, - "set-features", - g_strerror (-r)); - return FALSE; + for (i = 0; i < len; i++) { + if (!strcmp ((char *) &strings->data[i * ETH_GSTRING_LEN], string)) + return i; } - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s", - ifindex, - "set-features", - success - ? "successfully setting features" - : "at least some of the features were not successfuly set"); - return success; + return -1; } -/*****************************************************************************/ - gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data) { struct ethtool_drvinfo *drvinfo; - - G_STATIC_ASSERT_EXPR (sizeof (*data) == sizeof (*drvinfo)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); - G_STATIC_ASSERT_EXPR (sizeof (data->driver) == sizeof (drvinfo->driver)); - G_STATIC_ASSERT_EXPR (sizeof (data->version) == sizeof (drvinfo->version)); - G_STATIC_ASSERT_EXPR (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); + G_STATIC_ASSERT (sizeof (*data) == sizeof (*drvinfo)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); + G_STATIC_ASSERT (sizeof (data->driver) == sizeof (drvinfo->driver)); + G_STATIC_ASSERT (sizeof (data->version) == sizeof (drvinfo->version)); + G_STATIC_ASSERT (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (data, FALSE); @@ -691,7 +213,7 @@ nmp_utils_ethtool_get_driver_info (int ifindex, memset (drvinfo, 0, sizeof (*drvinfo)); drvinfo->cmd = ETHTOOL_GDRVINFO; - return ethtool_call_ifindex (ifindex, drvinfo) >= 0; + return ethtool_get (ifindex, drvinfo); } gboolean @@ -711,7 +233,7 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, edata.e.cmd = ETHTOOL_GPERMADDR; edata.e.size = NM_UTILS_HWADDR_LEN_MAX; - if (ethtool_call_ifindex (ifindex, &edata.e) < 0) + if (!ethtool_get (ifindex, &edata.e)) return FALSE; if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX) @@ -730,8 +252,8 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, } return FALSE; } - not_all_0or1: + memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; return TRUE; @@ -748,30 +270,20 @@ nmp_utils_ethtool_supports_carrier_detect (int ifindex) * assume the device supports carrier-detect, otherwise we assume it * doesn't. */ - return ethtool_call_ifindex (ifindex, &edata) >= 0; + return ethtool_get (ifindex, &edata); } gboolean nmp_utils_ethtool_supports_vlans (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; gs_free struct ethtool_gfeatures *features = NULL; int idx, block, bit, size; g_return_val_if_fail (ifindex > 0, FALSE); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "support-vlans", - g_strerror (-r)); - return FALSE; - } - - idx = ethtool_get_stringset_index (&shandle, ETH_SS_FEATURES, "vlan-challenged"); - if (idx < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: vlan-challenged ethtool feature does not exist?", ifindex); + idx = ethtool_get_stringset_index (ifindex, ETH_SS_FEATURES, "vlan-challenged"); + if (idx == -1) { + nm_log_dbg (LOGD_PLATFORM, "ethtool: vlan-challenged ethtool feature does not exist for %d?", ifindex); return FALSE; } @@ -783,7 +295,7 @@ nmp_utils_ethtool_supports_vlans (int ifindex) features->cmd = ETHTOOL_GFEATURES; features->size = size; - if (ethtool_call_handle (&shandle, features) < 0) + if (!ethtool_get (ifindex, features)) return FALSE; return !(features->features[block].active & (1 << bit)); @@ -792,32 +304,21 @@ nmp_utils_ethtool_supports_vlans (int ifindex) int nmp_utils_ethtool_get_peer_ifindex (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; - gs_free struct ethtool_stats *stats = NULL; int peer_ifindex_stat; g_return_val_if_fail (ifindex > 0, 0); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "get-peer-ifindex", - g_strerror (-r)); - return FALSE; - } - - peer_ifindex_stat = ethtool_get_stringset_index (&shandle, ETH_SS_STATS, "peer_ifindex"); - if (peer_ifindex_stat < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: peer_ifindex stat does not exist?", ifindex); + peer_ifindex_stat = ethtool_get_stringset_index (ifindex, ETH_SS_STATS, "peer_ifindex"); + if (peer_ifindex_stat == -1) { + nm_log_dbg (LOGD_PLATFORM, "ethtool: peer_ifindex stat for %d does not exist?", ifindex); return FALSE; } stats = g_malloc0 (sizeof (*stats) + (peer_ifindex_stat + 1) * sizeof (guint64)); stats->cmd = ETHTOOL_GSTATS; stats->n_stats = peer_ifindex_stat + 1; - if (ethtool_call_ifindex (ifindex, stats) < 0) + if (!ethtool_get (ifindex, stats)) return 0; return stats->data[peer_ifindex_stat]; @@ -832,7 +333,7 @@ nmp_utils_ethtool_get_wake_on_lan (int ifindex) memset (&wol, 0, sizeof (wol)); wol.cmd = ETHTOOL_GWOL; - if (ethtool_call_ifindex (ifindex, &wol) < 0) + if (!ethtool_get (ifindex, &wol)) return FALSE; return wol.wolopts != 0; @@ -850,7 +351,7 @@ nmp_utils_ethtool_get_link_settings (int ifindex, g_return_val_if_fail (ifindex > 0, FALSE); - if (ethtool_call_ifindex (ifindex, &edata) < 0) + if (!ethtool_get (ifindex, &edata)) return FALSE; if (out_autoneg) @@ -932,13 +433,9 @@ nmp_utils_ethtool_set_link_settings (int ifindex, || (!speed && duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN), FALSE); /* retrieve first current settings */ - if (ethtool_call_ifindex (ifindex, &edata) < 0) + if (!ethtool_get (ifindex, &edata)) return FALSE; - /* FIXME: try first new ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API - * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3f1ac7a700d039c61d8d8b99f28d605d489a60cf - */ - /* then change the needed ones */ edata.cmd = ETHTOOL_SSET; if (autoneg) { @@ -988,7 +485,7 @@ nmp_utils_ethtool_set_link_settings (int ifindex, } } - return ethtool_call_ifindex (ifindex, &edata) >= 0; + return ethtool_get (ifindex, &edata); } gboolean @@ -1003,8 +500,8 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) return TRUE; - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: setting Wake-on-LAN options 0x%x, password '%s'", - ifindex, (unsigned) wol, wol_password); + nm_log_dbg (LOGD_PLATFORM, "setting Wake-on-LAN options 0x%x, password '%s'", + (unsigned) wol, wol_password); wol_info.cmd = ETHTOOL_SWOL; wol_info.wolopts = 0; @@ -1024,41 +521,45 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol_password) { if (!nm_utils_hwaddr_aton (wol_password, wol_info.sopass, ETH_ALEN)) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: couldn't parse Wake-on-LAN password '%s'", ifindex, wol_password); + nm_log_dbg (LOGD_PLATFORM, "couldn't parse Wake-on-LAN password '%s'", wol_password); return FALSE; } wol_info.wolopts |= WAKE_MAGICSECURE; } - return ethtool_call_ifindex (ifindex, &wol_info) >= 0; + return ethtool_get (ifindex, &wol_info); } -/****************************************************************************** +/****************************************************************** * mii - *****************************************************************************/ + ******************************************************************/ gboolean nmp_utils_mii_supports_carrier_detect (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; + char ifname[IFNAMSIZ]; + nm_auto_close int fd = -1; struct ifreq ifr; struct mii_ioctl_data *mii; g_return_val_if_fail (ifindex > 0, FALSE); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: failed creating ethtool socket: %s", - ifindex, - g_strerror (-r)); + if (!nmp_utils_if_indextoname (ifindex, ifname)) { + nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: request fails resolving ifindex: %s", ifindex, g_strerror (errno)); + return FALSE; + } + + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: couldn't open control socket: %s", ifindex, ifname, g_strerror (errno)); return FALSE; } memset (&ifr, 0, sizeof (struct ifreq)); - memcpy (ifr.ifr_name, shandle.ifname, IFNAMSIZ); + memcpy (ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl (shandle.fd, SIOCGMIIPHY, &ifr) < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, shandle.ifname, strerror (errno)); + if (ioctl (fd, SIOCGMIIPHY, &ifr) < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, ifname, strerror (errno)); return FALSE; } @@ -1066,18 +567,18 @@ nmp_utils_mii_supports_carrier_detect (int ifindex) mii = (struct mii_ioctl_data *) &ifr.ifr_ifru; mii->reg_num = MII_BMSR; - if (ioctl (shandle.fd, SIOCGMIIREG, &ifr) != 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, shandle.ifname, strerror (errno)); + if (ioctl (fd, SIOCGMIIREG, &ifr) != 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, ifname, strerror (errno)); return FALSE; } - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, shandle.ifname, mii->val_out); + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, ifname, mii->val_out); return TRUE; } -/****************************************************************************** +/****************************************************************** * udev - *****************************************************************************/ + ******************************************************************/ const char * nmp_utils_udev_get_driver (struct udev_device *udevice) diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index bad77aee..97f5630a 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -23,9 +23,6 @@ #include "nm-platform.h" #include "nm-setting-wired.h" -#include "nm-ethtool-utils.h" - -/*****************************************************************************/ const char *nmp_utils_ethtool_get_driver (int ifindex); gboolean nmp_utils_ethtool_supports_carrier_detect (int ifindex); @@ -38,10 +35,6 @@ gboolean nmp_utils_ethtool_set_wake_on_lan (int ifindex, NMSettingWiredWakeOnLan gboolean nmp_utils_ethtool_get_link_settings (int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); gboolean nmp_utils_ethtool_set_link_settings (int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); -gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, - guint8 *buf, - size_t *length); - typedef struct { /* We don't want to include <linux/ethtool.h> in header files, * thus create a ABI compatible version of struct ethtool_drvinfo.*/ @@ -62,52 +55,9 @@ typedef struct { gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data); -typedef struct { - NMEthtoolID ethtool_id; - - guint8 n_kernel_names; - - /* one NMEthtoolID refers to one or more kernel_names. The reason for supporting this complexity - * (where one NMSettingEthtool option refers to multiple kernel features) is to follow what - * ethtool does, where "tx" is an alias for multiple features. */ - const char *const*kernel_names; -} NMEthtoolFeatureInfo; - -typedef struct { - const NMEthtoolFeatureInfo *info; - - guint idx_ss_features; - - /* one NMEthtoolFeatureInfo references one or more kernel_names. This is the index - * of the matching info->kernel_names */ - guint8 idx_kernel_name; - - bool available:1; - bool requested:1; - bool active:1; - bool never_changed:1; -} NMEthtoolFeatureState; - -struct _NMEthtoolFeatureStates { - guint n_states; - - guint n_ss_features; - - /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ - const NMEthtoolFeatureState *const*states_indexed[_NM_ETHTOOL_ID_FEATURE_NUM]; - - /* the same content, here as a list of n_states entries. */ - const NMEthtoolFeatureState states_list[]; -}; - -NMEthtoolFeatureStates *nmp_utils_ethtool_get_features (int ifindex); - -gboolean nmp_utils_ethtool_set_features (int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */); - -/*****************************************************************************/ +gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, + guint8 *buf, + size_t *length); gboolean nmp_utils_mii_supports_carrier_detect (int ifindex); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 7ddcf41a..f75019e8 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 - 2018 Red Hat, Inc. + * Copyright (C) 2012 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -27,8 +27,6 @@ #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <sys/socket.h> -#include <netdb.h> #include <string.h> #include <linux/ip.h> #include <linux/if_tun.h> @@ -76,6 +74,8 @@ G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OF } \ } G_STMT_END +#define LOG_FMT_IP_TUNNEL "adding %s '%s' parent %u local %s remote %s" + /*****************************************************************************/ static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = { 0 }; @@ -807,7 +807,6 @@ _nm_platform_link_get_by_address_match_link (const NMPObject *obj, struct _nm_pl **/ const NMPlatformLink * nm_platform_link_get_by_address (NMPlatform *self, - NMLinkType link_type, gconstpointer address, size_t length) { @@ -828,7 +827,7 @@ nm_platform_link_get_by_address (NMPlatform *self, g_return_val_if_reached (NULL); obj = nmp_cache_lookup_link_full (nm_platform_get_cache (self), - 0, NULL, TRUE, link_type, + 0, NULL, TRUE, NM_LINK_TYPE_NONE, (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, &d); return NMP_OBJECT_CAST_LINK (obj); } @@ -902,7 +901,7 @@ nm_platform_link_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s (%d)" + _LOGD ("link: adding link '%s' of type '%s' (%d)" "%s%s" /* address */ "%s%s" /* veth peer */ "", @@ -986,7 +985,7 @@ nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) if (!pllink) return FALSE; - _LOGD ("link: move link %d to network namespace with fd %d", ifindex, netns_fd); + _LOGD ("link: ifindex %d changing network namespace to %d", ifindex, netns_fd); return klass->link_set_netns (self, ifindex, netns_fd); } @@ -1355,18 +1354,15 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) { - gs_free char *mac = NULL; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (address, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (length > 0, NM_PLATFORM_ERROR_BUG); - _LOGD ("link: setting %s (%d) hardware address to %s", + _LOGD ("link: setting %s (%d) hardware address", nm_strquote_a (20, nm_platform_link_get_name (self, ifindex)), - ifindex, - (mac = nm_utils_hwaddr_ntoa (address, length))); + ifindex); return klass->link_set_address (self, ifindex, address, length); } @@ -1463,52 +1459,18 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) return klass->link_supports_sriov (self, ifindex); } -/** - * nm_platform_link_set_sriov_params: - * @self: platform instance - * @ifindex: the index of the interface to change - * @num_vfs: the number of VFs to create - * @autoprobe: -1 to keep the current autoprobe-drivers value, - * or {0,1} to set a new value - */ gboolean -nm_platform_link_set_sriov_params (NMPlatform *self, - int ifindex, - guint num_vfs, - int autoprobe) +nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (NM_IN_SET (autoprobe, -1, 0, 1), FALSE); - _LOGD ("link: setting %u total VFs and autoprobe %d for %s (%d)", + _LOGD ("link: setting %u VFs for %s (%d)", num_vfs, - autoprobe, nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); - return klass->link_set_sriov_params (self, ifindex, num_vfs, autoprobe); -} - -gboolean -nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs) -{ - guint i; - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - _LOGD ("link: setting VFs for \"%s\" (%d):", - nm_platform_link_get_name (self, ifindex), - ifindex); - - for (i = 0; vfs[i]; i++) { - const NMPlatformVF *vf = vfs[i]; - - _LOGD ("link: VF %s", nm_platform_vf_to_string (vf, NULL, 0)); - } - - return klass->link_set_sriov_vfs (self, ifindex, vfs); + return klass->link_set_sriov_num_vfs (self, ifindex, num_vfs); } /** @@ -1890,12 +1852,6 @@ nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLin return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link); } -const NMPlatformLnkGre * -nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRETAP, out_link); -} - const NMPlatformLnkInfiniband * nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -1908,18 +1864,6 @@ nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatform return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6TNL, out_link); } -const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRE, out_link); -} - -const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link); -} - const NMPlatformLnkIpIp * nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -1968,12 +1912,6 @@ nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformL return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link); } -const NMPlatformLnkWireGuard * -nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link); -} - /*****************************************************************************/ /** @@ -2058,9 +1996,8 @@ nm_platform_link_vlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': vlan parent %d vlanid %d vlanflags %x", + _LOGD ("link: adding vlan '%s' parent %d vlanid %d vlanflags %x", name, parent, vlanid, vlanflags); - if (!klass->vlan_add (self, name, parent, vlanid, vlanflags, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; @@ -2091,9 +2028,8 @@ nm_platform_link_vxlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s", - name, nm_platform_lnk_vxlan_to_string (props, NULL, 0)); - + _LOGD ("link: adding vxlan '%s' parent %d id %d", + name, props->parent_ifindex, props->id); if (!klass->link_vxlan_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; @@ -2144,78 +2080,13 @@ nm_platform_link_tun_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s", + _LOGD ("link: adding tun '%s' %s", name, nm_platform_lnk_tun_to_string (props, b, sizeof (b))); - if (!klass->link_tun_add (self, name, props, out_link, out_fd)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; } -/** - * nm_platform_6lowpan_add: - * @self: platform instance - * @parent: parent link - * @name: name of the new interface - * @out_link: on success, the link object - * - * Create a 6LoWPAN interface. - */ -NMPlatformError -nm_platform_link_6lowpan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLink **out_link) -{ - NMPlatformError plerr; - - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_6LOWPAN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - - _LOGD ("adding link '%s': 6lowpan parent %u", name, parent); - - if (!klass->link_6lowpan_add (self, name, parent, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; -} - -gboolean -nm_platform_link_6lowpan_get_properties (NMPlatform *self, int ifindex, int *out_parent) -{ - const NMPlatformLink *plink; - _CHECK_SELF (self, klass, FALSE); - - plink = nm_platform_link_get (self, ifindex); - - if (!plink) - return FALSE; - if (plink->type != NM_LINK_TYPE_6LOWPAN) - return FALSE; - - if (plink->parent != 0) { - NM_SET_OUT (out_parent, plink->parent); - return TRUE; - } - - /* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK. - * Find the WPAN device with the same MAC address. */ - if (out_parent) { - const NMPlatformLink *parent_plink; - - parent_plink = nm_platform_link_get_by_address (self, NM_LINK_TYPE_WPAN, - plink->addr.data, - plink->addr.len); - NM_SET_OUT (out_parent, parent_plink ? parent_plink->ifindex : -1); - } - - return TRUE; -} - /*****************************************************************************/ static gboolean @@ -2439,18 +2310,23 @@ nm_platform_link_gre_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - plerr = _link_add_check_existing (self, name, props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, out_link); + plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_GRE, out_link); if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_gre_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "gre", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_gre_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2496,9 +2372,6 @@ _infiniband_add_add_or_delete (NMPlatform *self, if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; } else { - _LOGD ("link: deleting infiniband partition %s for parent '%s' (%d), key %d", - name, parent_link->name, parent, p_key); - if (!klass->infiniband_partition_delete (self, parent, p_key)) return NM_PLATFORM_ERROR_UNSPECIFIED; } @@ -2599,19 +2472,23 @@ nm_platform_link_ip6tnl_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET6_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (!props->is_gre, NM_PLATFORM_ERROR_BUG); plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IP6TNL, out_link); if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "ip6tnl", + name, + props->parent_ifindex, + nm_utils_inet6_ntop (&props->local, NULL), + nm_utils_inet6_ntop (&props->remote, buffer)); if (!klass->link_ip6tnl_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2619,46 +2496,6 @@ nm_platform_link_ip6tnl_add (NMPlatform *self, } /** - * nm_platform_ip6gre_add: - * @self: platform instance - * @name: name of the new interface - * @props: interface properties - * @out_link: on success, the link object - * - * Create an IPv6 GRE/GRETAP tunnel. - */ -NMPlatformError -nm_platform_link_ip6gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link) -{ - NMPlatformError plerr; - - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (props->is_gre, NM_PLATFORM_ERROR_BUG); - - plerr = _link_add_check_existing (self, - name, - props->is_tap - ? NM_LINK_TYPE_IP6GRETAP - : NM_LINK_TYPE_IP6GRE, - out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); - - if (!klass->link_ip6gre_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; -} - -/** * nm_platform_ipip_add: * @self: platform instance * @name: name of the new interface @@ -2674,6 +2511,7 @@ nm_platform_link_ipip_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); @@ -2684,8 +2522,12 @@ nm_platform_link_ipip_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ipip_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "ipip", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_ipip_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2696,7 +2538,6 @@ nm_platform_link_ipip_add (NMPlatform *self, * nm_platform_macsec_add: * @self: platform instance * @name: name of the new interface - * @parent: parent link * @props: interface properties * @out_link: on success, the link object * @@ -2720,8 +2561,10 @@ nm_platform_link_macsec_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macsec_to_string (props, NULL, 0)); + _LOGD ("adding macsec '%s' parent %u sci %llx", + name, + parent, + (unsigned long long) props->sci); if (!klass->link_macsec_add (self, name, parent, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2758,8 +2601,11 @@ nm_platform_link_macvlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macvlan_to_string (props, NULL, 0)); + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", + name, + parent, + props->mode); if (!klass->link_macvlan_add (self, name, parent, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2782,6 +2628,7 @@ nm_platform_link_sit_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); @@ -2792,8 +2639,12 @@ nm_platform_link_sit_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_sit_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "sit", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_sit_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -3037,16 +2888,6 @@ nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gbo klass->wifi_indicate_addressing_running (self, ifindex, running); } -NMSettingWirelessWakeOnWLan -nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wifi_get_wake_on_wlan (self, ifindex); -} - gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl) { @@ -3088,46 +2929,6 @@ nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gs return klass->mesh_set_ssid (self, ifindex, ssid, len); } -guint16 -nm_platform_wpan_get_pan_id (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_get_pan_id (self, ifindex); -} - -gboolean -nm_platform_wpan_set_pan_id (NMPlatform *self, int ifindex, guint16 pan_id) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_set_pan_id (self, ifindex, pan_id); -} - -guint16 -nm_platform_wpan_get_short_addr (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_get_short_addr (self, ifindex); -} - -gboolean -nm_platform_wpan_set_short_addr (NMPlatform *self, int ifindex, guint16 short_addr) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_set_short_addr (self, ifindex, short_addr); -} - #define TO_STRING_DEV_BUF_SIZE (5+15+1) static const char * _to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size) @@ -3213,32 +3014,6 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_platform_link_duplex_type_to_string, NMPlatformLi /*****************************************************************************/ -NMEthtoolFeatureStates * -nm_platform_ethtool_get_link_features (NMPlatform *self, int ifindex) -{ - _CHECK_SELF_NETNS (self, klass, netns, NULL); - - g_return_val_if_fail (ifindex > 0, NULL); - - return nmp_utils_ethtool_get_features (ifindex); -} - -gboolean -nm_platform_ethtool_set_features (NMPlatform *self, - int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */) -{ - _CHECK_SELF_NETNS (self, klass, netns, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return nmp_utils_ethtool_set_features (ifindex, features, requested, do_set); -} - -/*****************************************************************************/ - const NMDedupMultiHeadEntry * nm_platform_lookup_all (NMPlatform *platform, NMPCacheIdType cache_id_type, @@ -3847,7 +3622,7 @@ ip6_address_scope_priority (const struct in6_addr *addr) return 3; } -static int +static gint ip6_address_scope_cmp (gconstpointer a, gconstpointer b) { const NMPlatformIP6Address *x = NMP_OBJECT_CAST_IP6_ADDRESS (*(const void **) a); @@ -5182,7 +4957,7 @@ nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len return buf; g_snprintf (buf, len, - lnk->is_tap ? "gretap" : "gre" + "gre" "%s" /* remote */ "%s" /* local */ "%s" /* parent_ifindex */ @@ -5239,18 +5014,12 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi char str_encap[30]; char str_proto[30]; char str_parent_ifindex[30]; - char *str_type; if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) return buf; - if (lnk->is_gre) - str_type = lnk->is_tap ? "ip6gretap" : "ip6gre"; - else - str_type = "ip6tnl"; - g_snprintf (buf, len, - "%s" /* type */ + "ip6tnl" "%s" /* remote */ "%s" /* local */ "%s" /* parent_ifindex */ @@ -5261,7 +5030,6 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi "%s" /* proto */ " flags 0x%x" "", - str_type, nm_sprintf_buf (str_remote, " remote %s", nm_utils_inet6_ntop (&lnk->remote, str_remote1)), nm_sprintf_buf (str_local, " local %s", nm_utils_inet6_ntop (&lnk->local, str_local1)), lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", @@ -5346,8 +5114,7 @@ nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, g return buf; g_snprintf (buf, len, - "%s mode %u %s", - lnk->tap ? "macvtap" : "macvlan", + "macvlan mode %u %s", lnk->mode, lnk->no_promisc ? "not-promisc" : "promisc"); return buf; @@ -5531,91 +5298,6 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize return buf; } -const char * -nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, gsize len) -{ - gs_free char *public_key_b64 = NULL; - char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100]; - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - guint i; - - nm_utils_to_string_buffer_init (&buf, &len); - - if (peer->endpoint_family == AF_INET) { - nm_sprintf_buf (s_endpoint, - " endpoint %s:%u", - nm_utils_inet4_ntop (peer->endpoint_addr.addr4, s_addr), - (guint) peer->endpoint_port); - } else if (peer->endpoint_family == AF_INET6) { - nm_sprintf_buf (s_endpoint, - " endpoint [%s]:%u", - nm_utils_inet6_ntop (&peer->endpoint_addr.addr6, s_addr), - (guint) peer->endpoint_port); - } else - s_endpoint[0] = '\0'; - - public_key_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key)); - - nm_utils_strbuf_append (&buf, &len, - "public-key %s" - "%s" /* preshared-key */ - "%s" /* endpoint */ - " rx %"G_GUINT64_FORMAT - " tx %"G_GUINT64_FORMAT - "%s", /* allowed-ips */ - public_key_b64, - nm_utils_mem_all_zero (peer->preshared_key, sizeof (peer->preshared_key)) - ? "" - : " preshared-key (hidden)", - s_endpoint, - peer->rx_bytes, - peer->tx_bytes, - peer->allowed_ips_len > 0 - ? " allowed-ips" - : ""); - - for (i = 0; i < peer->allowed_ips_len; i++) { - const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i]; - - nm_utils_strbuf_append (&buf, &len, - " %s/%u", - nm_utils_inet_ntop (allowed_ip->family, &allowed_ip->addr, s_addr), - allowed_ip->mask); - } - - return buf; -} - -const char * -nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len) -{ - gs_free char *public_b64 = NULL; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - if (!nm_utils_mem_all_zero (lnk->public_key, sizeof (lnk->public_key))) - public_b64 = g_base64_encode (lnk->public_key, sizeof (lnk->public_key)); - - g_snprintf (buf, len, - "wireguard" - "%s%s" /* public-key */ - "%s" /* private-key */ - " listen-port %u" - " fwmark 0x%x", - public_b64 - ? " public-key " - : "", - public_b64 ?: "", - nm_utils_mem_all_zero (lnk->private_key, sizeof (lnk->private_key)) - ? "" - : " private-key (hidden)", - lnk->listen_port, - lnk->fwmark); - - return buf; -} - /** * nm_platform_ip4_address_to_string: * @route: pointer to NMPlatformIP4Address address structure @@ -6093,56 +5775,6 @@ nm_platform_tfilter_cmp (const NMPlatformTfilter *a, const NMPlatformTfilter *b) return 0; } -const char * -nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len) -{ - char str_mac[128], mac[128]; - char str_spoof_check[64]; - char str_trust[64]; - char str_min_tx_rate[64]; - char str_max_tx_rate[64]; - nm_auto_free_gstring GString *gstr_vlans = NULL; - guint i; - - if (!nm_utils_to_string_buffer_init_null (vf, &buf, &len)) - return buf; - - if (vf->mac.len) { - nm_utils_hwaddr_ntoa_buf (vf->mac.data, vf->mac.len, TRUE, mac, sizeof (mac)); - nm_sprintf_buf (str_mac, " mac %s", mac); - } else - str_mac[0] = '\0'; - - if (vf->num_vlans) { - gstr_vlans = g_string_new (""); - for (i = 0; i < vf->num_vlans; i++) { - g_string_append_printf (gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id); - if (vf->vlans[i].qos) - g_string_append_printf (gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos); - if (vf->vlans[i].proto_ad) - g_string_append (gstr_vlans, " proto 802.1ad"); - } - } - - g_snprintf (buf, len, - "%u" /* index */ - "%s" /* MAC */ - "%s" /* spoof check */ - "%s" /* trust */ - "%s" /* min tx rate */ - "%s" /* max tx rate */ - "%s", /* VLANs */ - vf->index, - str_mac, - vf->spoofchk >= 0 ? nm_sprintf_buf (str_spoof_check, " spoofchk %d", vf->spoofchk) : "", - vf->trust >= 0 ? nm_sprintf_buf (str_trust, " trust %d", vf->trust) : "", - vf->min_tx_rate ? nm_sprintf_buf (str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate) : "", - vf->max_tx_rate ? nm_sprintf_buf (str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate) : "", - gstr_vlans ? gstr_vlans->str : ""); - - return buf; -} - void nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h) { @@ -6211,8 +5843,7 @@ nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h) obj->output_key, obj->ttl, obj->tos, - (bool) obj->path_mtu_discovery, - (bool) obj->is_tap); + (bool) obj->path_mtu_discovery); } int @@ -6229,7 +5860,6 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) NM_CMP_FIELD (a, b, ttl); NM_CMP_FIELD (a, b, tos); NM_CMP_FIELD_BOOL (a, b, path_mtu_discovery); - NM_CMP_FIELD_BOOL (a, b, is_tap); return 0; } @@ -6261,13 +5891,7 @@ nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState obj->encap_limit, obj->proto, obj->flow_label, - obj->flags, - obj->input_flags, - obj->output_flags, - obj->input_key, - obj->output_key, - (bool) obj->is_gre, - (bool) obj->is_tap); + obj->flags); } int @@ -6283,12 +5907,6 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6 NM_CMP_FIELD (a, b, flow_label); NM_CMP_FIELD (a, b, proto); NM_CMP_FIELD (a, b, flags); - NM_CMP_FIELD (a, b, input_flags); - NM_CMP_FIELD (a, b, output_flags); - NM_CMP_FIELD (a, b, input_key); - NM_CMP_FIELD (a, b, output_key); - NM_CMP_FIELD_BOOL (a, b, is_gre); - NM_CMP_FIELD_BOOL (a, b, is_tap); return 0; } @@ -6506,27 +6124,6 @@ nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan } void -nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->listen_port, - obj->fwmark); - nm_hash_update (h, obj->private_key, sizeof (obj->private_key)); - nm_hash_update (h, obj->public_key, sizeof (obj->public_key)); -} - -int -nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, listen_port); - NM_CMP_FIELD (a, b, fwmark); - NM_CMP_FIELD_MEMCMP (a, b, private_key); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - return 0; -} - -void nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h) { nm_hash_update_vals (h, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 11495aff..866df736 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2018 Red Hat, Inc. + * Copyright (C) 2009 - 2017 Red Hat, Inc. */ #ifndef __NETWORKMANAGER_PLATFORM_H__ @@ -608,26 +608,6 @@ extern const NMPlatformVTableRoute nm_platform_vtable_route_v4; extern const NMPlatformVTableRoute nm_platform_vtable_route_v6; typedef struct { - guint16 id; - guint32 qos; - bool proto_ad:1; -} NMPlatformVFVlan; - -typedef struct { - guint32 index; - guint32 min_tx_rate; - guint32 max_tx_rate; - guint num_vlans; - NMPlatformVFVlan *vlans; - struct { - guint8 data[20]; /* NM_UTILS_HWADDR_LEN_MAX */ - guint8 len; - } mac; - gint8 spoofchk; - gint8 trust; -} NMPlatformVF; - -typedef struct { in_addr_t local; in_addr_t remote; int parent_ifindex; @@ -638,7 +618,6 @@ typedef struct { guint8 ttl; guint8 tos; bool path_mtu_discovery:1; - bool is_tap:1; } NMPlatformLnkGre; typedef struct { @@ -656,14 +635,6 @@ typedef struct { guint8 proto; guint flow_label; guint32 flags; - - /* IP6GRE only */ - guint32 input_key; - guint32 output_key; - guint16 input_flags; - guint16 output_flags; - bool is_tap:1; - bool is_gre:1; } NMPlatformLnkIp6Tnl; typedef struct { @@ -752,16 +723,6 @@ typedef struct { bool l3miss:1; } NMPlatformLnkVxlan; -#define NMP_WIREGUARD_PUBLIC_KEY_LEN 32 -#define NMP_WIREGUARD_SYMMETRIC_KEY_LEN 32 - -typedef struct { - guint32 fwmark; - guint16 listen_port; - guint8 private_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; - guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; -} NMPlatformLnkWireGuard; - typedef enum { NM_PLATFORM_LINK_DUPLEX_UNKNOWN, NM_PLATFORM_LINK_DUPLEX_HALF, @@ -825,8 +786,7 @@ typedef struct { NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); NMPlatformError (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name); - gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe); - gboolean (*link_set_sriov_vfs) (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); + gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs); char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); guint (*link_get_dev_id) (NMPlatform *, int ifindex); @@ -869,10 +829,6 @@ typedef struct { const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link); - gboolean (*link_ip6gre_add) (NMPlatform *, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); gboolean (*link_ipip_add) (NMPlatform *, const char *name, const NMPlatformLnkIpIp *props, @@ -898,16 +854,12 @@ typedef struct { const NMPlatformLink **out_link, int *out_fd); - gboolean (*link_6lowpan_add) (NMPlatform *platform, - const char *name, - int parent, - const NMPlatformLink **out_link); - gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, const NMPlatformLink **out_link); gboolean (*infiniband_partition_delete) (NMPlatform *, int parent, int p_key); gboolean (*wifi_get_capabilities) (NMPlatform *, int ifindex, NMDeviceWifiCapabilities *caps); gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, guint8 *bssid); + GByteArray *(*wifi_get_ssid) (NMPlatform *, int ifindex); guint32 (*wifi_get_frequency) (NMPlatform *, int ifindex); int (*wifi_get_quality) (NMPlatform *, int ifindex); guint32 (*wifi_get_rate) (NMPlatform *, int ifindex); @@ -916,18 +868,12 @@ typedef struct { void (*wifi_set_powersave) (NMPlatform *, int ifindex, guint32 powersave); guint32 (*wifi_find_frequency) (NMPlatform *, int ifindex, const guint32 *freqs); void (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running); - NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex); gboolean (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 (*mesh_get_channel) (NMPlatform *, int ifindex); gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel); gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len); - guint16 (*wpan_get_pan_id) (NMPlatform *, int ifindex); - gboolean (*wpan_set_pan_id) (NMPlatform *, int ifindex, guint16 pan_id); - guint16 (*wpan_get_short_addr) (NMPlatform *, int ifindex); - gboolean (*wpan_set_short_addr) (NMPlatform *, int ifindex, guint16 short_addr); - gboolean (*object_delete) (NMPlatform *, const NMPObject *obj); gboolean (*ip4_address_add) (NMPlatform *, @@ -1132,7 +1078,7 @@ const NMPObject *nm_platform_link_get_obj (NMPlatform *self, gboolean visible_only); const NMPlatformLink *nm_platform_link_get (NMPlatform *self, int ifindex); const NMPlatformLink *nm_platform_link_get_by_ifname (NMPlatform *self, const char *ifname); -const NMPlatformLink *nm_platform_link_get_by_address (NMPlatform *self, NMLinkType link_type, gconstpointer address, size_t length); +const NMPlatformLink *nm_platform_link_get_by_address (NMPlatform *self, gconstpointer address, size_t length); GPtrArray *nm_platform_link_get_all (NMPlatform *self, gboolean sort_by_name); NMPlatformError nm_platform_link_dummy_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); @@ -1216,8 +1162,7 @@ gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); NMPlatformError nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name); -gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe); -gboolean nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); +gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs); char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex); guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex); @@ -1242,10 +1187,7 @@ char *nm_platform_sysctl_slave_get_option (NMPlatform *self, int ifindex, const const NMPObject *nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link); const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkGre *nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); @@ -1256,7 +1198,6 @@ const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifin const NMPlatformLnkTun *nm_platform_link_get_lnk_tun (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkWireGuard *nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); NMPlatformError nm_platform_link_vlan_add (NMPlatform *self, const char *name, @@ -1306,18 +1247,12 @@ void nm_platform_wifi_set_mode (NMPlatform *self, int ifindex, NM void nm_platform_wifi_set_powersave (NMPlatform *self, int ifindex, guint32 powersave); guint32 nm_platform_wifi_find_frequency (NMPlatform *self, int ifindex, const guint32 *freqs); void nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running); -NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex); gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex); gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel); gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len); -guint16 nm_platform_wpan_get_pan_id (NMPlatform *platform, int ifindex); -gboolean nm_platform_wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id); -guint16 nm_platform_wpan_get_short_addr (NMPlatform *platform, int ifindex); -gboolean nm_platform_wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr); - void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen); const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr); @@ -1331,10 +1266,6 @@ NMPlatformError nm_platform_link_ip6tnl_add (NMPlatform *self, const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_ip6gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); NMPlatformError nm_platform_link_ipip_add (NMPlatform *self, const char *name, const NMPlatformLnkIpIp *props, @@ -1358,13 +1289,6 @@ NMPlatformError nm_platform_link_tun_add (NMPlatform *self, const NMPlatformLnkTun *props, const NMPlatformLink **out_link, int *out_fd); -NMPlatformError nm_platform_link_6lowpan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLink **out_link); -gboolean nm_platform_link_6lowpan_get_properties (NMPlatform *self, - int ifindex, - int *out_parent); const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address); @@ -1451,14 +1375,12 @@ const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *bu const char *nm_platform_lnk_tun_to_string (const NMPlatformLnkTun *lnk, char *buf, gsize len); const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len); const char *nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len); -const char *nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len); const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len); const char *nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *buf, gsize len); const char *nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len); const char *nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len); const char *nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len); const char *nm_platform_tfilter_to_string (const NMPlatformTfilter *tfilter, char *buf, gsize len); -const char *nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len); const char *nm_platform_vlan_qos_mapping_to_string (const char *name, const NMVlanQosMapping *map, @@ -1466,11 +1388,6 @@ const char *nm_platform_vlan_qos_mapping_to_string (const char *name, char *buf, gsize len); -struct _NMPWireGuardPeer; -const char *nm_platform_wireguard_peer_to_string (const struct _NMPWireGuardPeer *peer, - char *buf, - gsize len); - int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b); int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b); int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b); @@ -1482,7 +1399,6 @@ int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit * int nm_platform_lnk_tun_cmp (const NMPlatformLnkTun *a, const NMPlatformLnkTun *b); int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b); int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b); -int nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b); int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b); int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b); @@ -1519,7 +1435,6 @@ void nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState * void nm_platform_lnk_tun_hash_update (const NMPlatformLnkTun *obj, NMHashState *h); void nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h); void nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h); -void nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h); void nm_platform_qdisc_hash_update (const NMPlatformQdisc *obj, NMHashState *h); void nm_platform_tfilter_hash_update (const NMPlatformTfilter *obj, NMHashState *h); @@ -1537,17 +1452,6 @@ int nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPla gboolean nm_platform_ethtool_set_wake_on_lan (NMPlatform *self, int ifindex, NMSettingWiredWakeOnLan wol, const char *wol_password); gboolean nm_platform_ethtool_set_link_settings (NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); gboolean nm_platform_ethtool_get_link_settings (NMPlatform *self, int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); - -typedef struct _NMEthtoolFeatureStates NMEthtoolFeatureStates; - -NMEthtoolFeatureStates *nm_platform_ethtool_get_link_features (NMPlatform *self, - int ifindex); -gboolean nm_platform_ethtool_set_features (NMPlatform *self, - int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */); - const char * nm_platform_link_duplex_type_to_string (NMPlatformLinkDuplexType duplex); void nm_platform_ip4_dev_route_blacklist_set (NMPlatform *self, diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index fdc27440..50e6825b 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -27,14 +27,10 @@ #include <libudev.h> #include "nm-utils.h" -#include "nm-utils/nm-secret-utils.h" #include "nm-core-utils.h" #include "nm-platform-utils.h" -#include "wifi/nm-wifi-utils.h" -#include "wpan/nm-wpan-utils.h" - /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM @@ -341,103 +337,12 @@ _vlan_xgress_qos_mappings_cpy (guint *dst_n_map, g_clear_pointer (dst_map, g_free); *dst_n_map = src_n_map; if (src_n_map > 0) - *dst_map = nm_memdup (src_map, sizeof (*src_map) * src_n_map); + *dst_map = g_memdup (src_map, sizeof (*src_map) * src_n_map); } } /*****************************************************************************/ -static void -_wireguard_allowed_ip_hash_update (const NMPWireGuardAllowedIP *ip, - NMHashState *h) -{ - nm_hash_update_vals (h, ip->family, - ip->mask); - - if (ip->family == AF_INET) - nm_hash_update_val (h, ip->addr.addr4); - else if (ip->family == AF_INET6) - nm_hash_update_val (h, ip->addr.addr6); -} - -static int -_wireguard_allowed_ip_cmp (const NMPWireGuardAllowedIP *a, - const NMPWireGuardAllowedIP *b) -{ - NM_CMP_SELF (a, b); - - NM_CMP_FIELD (a, b, family); - NM_CMP_FIELD (a, b, mask); - - if (a->family == AF_INET) - NM_CMP_FIELD (a, b, addr.addr4); - else if (a->family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, addr.addr6); - - return 0; -} - -static void -_wireguard_peer_hash_update (const NMPWireGuardPeer *peer, - NMHashState *h) -{ - guint i; - - nm_hash_update (h, peer->public_key, sizeof (peer->public_key)); - nm_hash_update (h, peer->preshared_key, sizeof (peer->preshared_key)); - nm_hash_update_vals (h, - peer->persistent_keepalive_interval, - peer->allowed_ips_len, - peer->rx_bytes, - peer->tx_bytes, - peer->last_handshake_time.tv_sec, - peer->last_handshake_time.tv_nsec, - peer->endpoint_port, - peer->endpoint_family); - - if (peer->endpoint_family == AF_INET) - nm_hash_update_val (h, peer->endpoint_addr.addr4); - else if (peer->endpoint_family == AF_INET6) - nm_hash_update_val (h, peer->endpoint_addr.addr6); - - for (i = 0; i < peer->allowed_ips_len; i++) - _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h); -} - -static int -_wireguard_peer_cmp (const NMPWireGuardPeer *a, - const NMPWireGuardPeer *b) -{ - guint i; - - NM_CMP_SELF (a, b); - - NM_CMP_FIELD (a, b, last_handshake_time.tv_sec); - NM_CMP_FIELD (a, b, last_handshake_time.tv_nsec); - NM_CMP_FIELD (a, b, rx_bytes); - NM_CMP_FIELD (a, b, tx_bytes); - NM_CMP_FIELD (a, b, allowed_ips_len); - NM_CMP_FIELD (a, b, persistent_keepalive_interval); - NM_CMP_FIELD (a, b, endpoint_port); - NM_CMP_FIELD (a, b, endpoint_family); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - NM_CMP_FIELD_MEMCMP (a, b, preshared_key); - - if (a->endpoint_family == AF_INET) - NM_CMP_FIELD (a, b, endpoint_addr.addr4); - else if (a->endpoint_family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, endpoint_addr.addr6); - - for (i = 0; i < a->allowed_ips_len; i++) { - NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i], - &b->allowed_ips[i])); - } - - return 0; -} - -/*****************************************************************************/ - static const char * _link_get_driver (struct udev_device *udevice, const char *kind, int ifindex) { @@ -551,7 +456,6 @@ _vt_cmd_obj_dispose_link (NMPObject *obj) udev_device_unref (obj->_link.udev.device); obj->_link.udev.device = NULL; } - g_clear_object (&obj->_link.ext_data); nmp_object_unref (obj->_link.netlink.lnk); } @@ -562,28 +466,6 @@ _vt_cmd_obj_dispose_lnk_vlan (NMPObject *obj) g_free ((gpointer) obj->_lnk_vlan.egress_qos_map); } -static void -_wireguard_clear (NMPObjectLnkWireGuard *lnk) -{ - guint i; - - nm_explicit_bzero (lnk->_public.private_key, - sizeof (lnk->_public.private_key)); - for (i = 0; i < lnk->peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i]; - - nm_explicit_bzero (peer->preshared_key, sizeof (peer->preshared_key)); - } - g_free ((gpointer) lnk->peers); - g_free ((gpointer) lnk->_allowed_ips_buf); -} - -static void -_vt_cmd_obj_dispose_lnk_wireguard (NMPObject *obj) -{ - _wireguard_clear (&obj->_lnk_wireguard); -} - static NMPObject * _nmp_object_new_from_class (const NMPClass *klass) { @@ -749,35 +631,31 @@ static const char * _vt_cmd_obj_to_string_link (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) { const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj); - char *b = buf; + char buf2[sizeof (_nm_utils_to_string_buffer)]; + char buf3[sizeof (_nm_utils_to_string_buffer)]; switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: return klass->cmd_plobj_to_string_id (&obj->object, buf, buf_size); case NMP_OBJECT_TO_STRING_ALL: - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - obj->_link.netlink.is_in_netlink ? '+' : '-', - obj->_link.udev.device); - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - if (obj->_link.netlink.lnk) { - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_ALL, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - } - nm_utils_strbuf_append_c (&b, &buf_size, ']'); + g_snprintf (buf, buf_size, + "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; %s]", + klass->obj_type_name, obj, obj->parent._ref_count, + nmp_object_is_alive (obj) ? '+' : '-', + nmp_object_is_visible (obj) ? '+' : '-', + obj->_link.netlink.is_in_netlink ? '+' : '-', + obj->_link.udev.device, + nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2))); return buf; case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); if (obj->_link.netlink.lnk) { - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, b, buf_size); - } + NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf2, sizeof (buf2)); + nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, buf3, sizeof (buf3)); + g_snprintf (buf, buf_size, + "%s; %s", + buf2, buf3); + } else + NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); return buf; default: g_return_val_if_reached ("ERROR"); @@ -842,55 +720,6 @@ _vt_cmd_obj_to_string_lnk_vlan (const NMPObject *obj, NMPObjectToStringMode to_s } } -static const char * -_vt_cmd_obj_to_string_lnk_wireguard (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass; - char buf2[sizeof (_nm_utils_to_string_buffer)]; - char *b; - guint i; - - klass = NMP_OBJECT_GET_CLASS (obj); - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - g_snprintf (buf, buf_size, "%p", obj); - return buf; - case NMP_OBJECT_TO_STRING_ALL: - b = buf; - - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible; %s" - "%s", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2)), - obj->_lnk_wireguard.peers_len > 0 - ? " peers {" - : ""); - - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) { - const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i]; - - nm_utils_strbuf_append_str (&b, &buf_size, " { "); - nm_platform_wireguard_peer_to_string (peer, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - } - if (obj->_lnk_wireguard.peers_len) - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); - - return buf; - default: - g_return_val_if_reached ("ERROR"); - } -} - #define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ static const char * \ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \ @@ -939,7 +768,6 @@ _vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h) nm_platform_link_hash_update (&obj->link, h); nm_hash_update_vals (h, obj->_link.netlink.is_in_netlink, - obj->_link.wireguard_family_id, obj->_link.udev.device); if (obj->_link.netlink.lnk) nmp_object_hash_update (obj->_link.netlink.lnk, h); @@ -959,26 +787,17 @@ _vt_cmd_obj_hash_update_lnk_vlan (const NMPObject *obj, NMHashState *h) h); } -static void -_vt_cmd_obj_hash_update_lnk_wireguard (const NMPObject *obj, NMHashState *h) -{ - guint i; - - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD); - - nm_platform_lnk_wireguard_hash_update (&obj->lnk_wireguard, h); - - nm_hash_update_val (h, obj->_lnk_wireguard.peers_len); - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) - _wireguard_peer_hash_update (&obj->_lnk_wireguard.peers[i], h); -} - int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) { const NMPClass *klass1, *klass2; - NM_CMP_SELF (obj1, obj2); + if (obj1 == obj2) + return 0; + if (!obj1) + return -1; + if (!obj2) + return 1; g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj1), -1); g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), 1); @@ -999,11 +818,16 @@ nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) static int _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2) { - NM_CMP_RETURN (nm_platform_link_cmp (&obj1->link, &obj2->link)); - NM_CMP_DIRECT (obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); - NM_CMP_RETURN (nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); - NM_CMP_DIRECT (obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); + int i; + i = nm_platform_link_cmp (&obj1->link, &obj2->link); + if (i) + return i; + if (obj1->_link.netlink.is_in_netlink != obj2->_link.netlink.is_in_netlink) + return obj1->_link.netlink.is_in_netlink ? -1 : 1; + i = nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk); + if (i) + return i; if (obj1->_link.udev.device != obj2->_link.udev.device) { if (!obj1->_link.udev.device) return -1; @@ -1016,7 +840,6 @@ _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2) * Have this check as very last. */ return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1; } - return 0; } @@ -1042,21 +865,6 @@ _vt_cmd_obj_cmp_lnk_vlan (const NMPObject *obj1, const NMPObject *obj2) return c; } -static int -_vt_cmd_obj_cmp_lnk_wireguard (const NMPObject *obj1, const NMPObject *obj2) -{ - guint i; - - NM_CMP_RETURN (nm_platform_lnk_wireguard_cmp (&obj1->lnk_wireguard, &obj2->lnk_wireguard)); - - NM_CMP_FIELD (obj1, obj2, _lnk_wireguard.peers_len); - - for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++) - NM_CMP_RETURN (_wireguard_peer_cmp (&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i])); - - return 0; -} - /* @src is a const object, which is not entirely correct for link types, where * we increase the ref count for src->_link.udev.device. * Hence, nmp_object_copy() can violate the const promise of @src. @@ -1100,12 +908,6 @@ _vt_cmd_obj_copy_link (NMPObject *dst, const NMPObject *src) nmp_object_unref (dst->_link.netlink.lnk); dst->_link.netlink.lnk = src->_link.netlink.lnk; } - if (dst->_link.ext_data != src->_link.ext_data) { - if (dst->_link.ext_data) - g_clear_object (&dst->_link.ext_data); - if (src->_link.ext_data) - dst->_link.ext_data = g_object_ref (src->_link.ext_data); - } dst->_link = src->_link; } @@ -1123,41 +925,6 @@ _vt_cmd_obj_copy_lnk_vlan (NMPObject *dst, const NMPObject *src) src->_lnk_vlan.egress_qos_map); } -static void -_vt_cmd_obj_copy_lnk_wireguard (NMPObject *dst, const NMPObject *src) -{ - guint i; - - nm_assert (dst != src); - - _wireguard_clear (&dst->_lnk_wireguard); - - dst->_lnk_wireguard = src->_lnk_wireguard; - - dst->_lnk_wireguard.peers = nm_memdup (dst->_lnk_wireguard.peers, - sizeof (NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len); - dst->_lnk_wireguard._allowed_ips_buf = nm_memdup (dst->_lnk_wireguard._allowed_ips_buf, - sizeof (NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len); - - /* all the peers' pointers point into the buffer. They need to be readjusted. */ - for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i]; - - if (peer->allowed_ips_len == 0) { - nm_assert (!peer->allowed_ips); - continue; - } - nm_assert (dst->_lnk_wireguard._allowed_ips_buf_len > 0); - nm_assert (src->_lnk_wireguard._allowed_ips_buf); - nm_assert (peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf); - nm_assert (&peer->allowed_ips[peer->allowed_ips_len] <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]); - - peer->allowed_ips = &dst->_lnk_wireguard._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf]; - } - - nm_assert (nmp_object_equal (src, dst)); -} - #define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \ static void \ _vt_cmd_plobj_id_copy_##type (NMPlatformObject *_dst, const NMPlatformObject *_src) \ @@ -2935,17 +2702,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, }, - [NMP_OBJECT_TYPE_LNK_GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_GRETAP, - .sizeof_data = sizeof (NMPObjectLnkGre), - .sizeof_public = sizeof (NMPlatformLnkGre), - .obj_type_name = "gretap", - .lnk_link_type = NM_LINK_TYPE_GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, - }, [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, @@ -2968,28 +2724,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, }, - [NMP_OBJECT_TYPE_LNK_IP6GRE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRE, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gre", - .lnk_link_type = NM_LINK_TYPE_IP6GRE, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IP6GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRETAP, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gretap", - .lnk_link_type = NM_LINK_TYPE_IP6GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, [NMP_OBJECT_TYPE_LNK_IPIP - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), .obj_type = NMP_OBJECT_TYPE_LNK_IPIP, @@ -3083,20 +2817,5 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vxlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp, }, - [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_WIREGUARD, - .sizeof_data = sizeof (NMPObjectLnkWireGuard), - .sizeof_public = sizeof (NMPlatformLnkWireGuard), - .obj_type_name = "wireguard", - .lnk_link_type = NM_LINK_TYPE_WIREGUARD, - .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_wireguard, - .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_wireguard, - .cmd_obj_copy = _vt_cmd_obj_copy_lnk_wireguard, - .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, - .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_wireguard_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp, - }, }; + diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 97be8321..f473f462 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 - 2017 Red Hat, Inc. */ #ifndef __NMP_OBJECT_H__ @@ -27,36 +27,6 @@ struct udev_device; -/*****************************************************************************/ - -typedef struct { - NMIPAddr addr; - guint8 family; - guint8 mask; -} NMPWireGuardAllowedIP; - -typedef struct _NMPWireGuardPeer { - NMIPAddr endpoint_addr; - struct timespec last_handshake_time; - guint64 rx_bytes; - guint64 tx_bytes; - union { - const NMPWireGuardAllowedIP *allowed_ips; - guint _construct_idx_start; - }; - union { - guint allowed_ips_len; - guint _construct_idx_end; - }; - guint16 persistent_keepalive_interval; - guint16 endpoint_port; - guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; - guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; - guint8 endpoint_family; -} NMPWireGuardPeer; - -/*****************************************************************************/ - typedef enum { /*< skip >*/ NMP_OBJECT_TO_STRING_ID, NMP_OBJECT_TO_STRING_PUBLIC, @@ -194,14 +164,6 @@ typedef struct { */ struct udev_device *device; } udev; - - /* Auxiliary data object for Wi-Fi and WPAN */ - GObject *ext_data; - - /* FIXME: not every NMPObjectLink should pay the price for tracking - * the wireguard family id. This should be tracked via ext_data, which - * would be exactly the right place. */ - int wireguard_family_id; } NMPObjectLink; typedef struct { @@ -252,14 +214,6 @@ typedef struct { } NMPObjectLnkVxlan; typedef struct { - NMPlatformLnkWireGuard _public; - const NMPWireGuardPeer *peers; - const NMPWireGuardAllowedIP *_allowed_ips_buf; - guint peers_len; - guint _allowed_ips_buf_len; -} NMPObjectLnkWireGuard; - -typedef struct { NMPlatformIP4Address _public; } NMPObjectIP4Address; @@ -324,9 +278,6 @@ struct _NMPObject { NMPlatformLnkVxlan lnk_vxlan; NMPObjectLnkVxlan _lnk_vxlan; - NMPlatformLnkWireGuard lnk_wireguard; - NMPObjectLnkWireGuard _lnk_wireguard; - NMPlatformIPAddress ip_address; NMPlatformIPXAddress ipx_address; NMPlatformIP4Address ip4_address; diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 12d91812..8b8c87d8 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -60,7 +60,7 @@ test_cleanup_internal (void) g_assert (ifindex > 0); /* wait for kernel to add the IPv6 link local address... it takes a bit. */ - NMTST_WAIT_ASSERT (300, { + NMTST_WAIT_ASSERT (100, { gs_unref_array GArray *addrs = NULL; const NMPlatformIP6Address *a; diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 3dedbd10..42569d5b 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1243,29 +1243,21 @@ nmtstp_link_gre_add (NMPlatform *platform, const NMPlatformLink *pllink = NULL; gboolean success; char buffer[INET_ADDRSTRLEN]; - NMLinkType link_type; g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); - link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; _init_platform (&platform, external_command); if (external_command) { gs_free char *dev = NULL; - char *obj, *type; if (lnk->parent_ifindex) dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - obj = lnk->is_tap ? "link" : "tunnel"; - type = lnk->is_tap ? "type gretap" : "mode gre"; - - success = !nmtstp_run_command ("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", - obj, + success = !nmtstp_run_command ("ip tunnel add %s mode gre %s local %s remote %s ttl %u tos %02x %s", name, - type, dev ?: "", nm_utils_inet4_ntop (lnk->local, NULL), nm_utils_inet4_ntop (lnk->remote, buffer), @@ -1273,11 +1265,11 @@ nmtstp_link_gre_add (NMPlatform *platform, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_GRE, 100); } else success = nm_platform_link_gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_GRE); return pllink; } @@ -1297,7 +1289,6 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean tclass_inherit; g_assert (nm_utils_is_valid_iface_name (name, NULL)); - g_assert (!lnk->is_gre); external_command = nmtstp_run_command_check_external (external_command); @@ -1345,56 +1336,6 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, } const NMPlatformLink * -nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char buffer[INET6_ADDRSTRLEN]; - char tclass[20]; - gboolean tclass_inherit; - - g_assert (nm_utils_is_valid_iface_name (name, NULL)); - g_assert (lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", - name, - lnk->is_tap ? "ip6gretap" : "ip6gre", - dev, - nm_utils_inet6_ntop (&lnk->local, NULL), - nm_utils_inet6_ntop (&lnk->remote, buffer), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - lnk->flow_label); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, - name, - lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - 100); - } - } else - success = nm_platform_link_ip6gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - - _assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); - - return pllink; -} - -const NMPlatformLink * nmtstp_link_ipip_add (NMPlatform *platform, gboolean external_command, const char *name, diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 1baadfa1..bd02b0d7 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -80,7 +80,7 @@ typedef struct { gulong handler_id; const char *name; NMPlatformSignalChangeType change_type; - int received_count; + gint received_count; GMainLoop *loop; int ifindex; const char *ifname; @@ -297,10 +297,6 @@ const NMPlatformLink *nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean external_command, const char *name, const NMPlatformLnkIp6Tnl *lnk); -const NMPlatformLink *nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk); const NMPlatformLink *nmtstp_link_ipip_add (NMPlatform *platform, gboolean external_command, const char *name, diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index eebc15d8..8708c80f 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 Red Hat, Inc. */ #include "nm-default.h" @@ -57,7 +57,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); g_test_add_func ("/general/init_linux_platform", test_init_linux_platform); g_test_add_func ("/general/link_get_all", test_link_get_all); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 057490c4..cd5880e3 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -25,7 +25,6 @@ #include <sys/types.h> #include <linux/if_tun.h> -#include "nm-utils/nm-io-utils.h" #include "platform/nmp-object.h" #include "platform/nmp-netns.h" #include "platform/nm-platform-utils.h" @@ -700,7 +699,6 @@ test_software_detect (gconstpointer user_data) guint i_step; const gboolean ext = test_data->external_command; NMPlatformLnkTun lnk_tun; - NMPlatformLnkGre lnk_gre = { }; nm_auto_close int tun_fd = -1; nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME); @@ -708,6 +706,7 @@ test_software_detect (gconstpointer user_data) switch (test_data->link_type) { case NM_LINK_TYPE_GRE: { + NMPlatformLnkGre lnk_gre = { }; gboolean gracefully_skip = FALSE; lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204"); @@ -731,31 +730,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_GRETAP: { - gboolean gracefully_skip = FALSE; - - lnk_gre.local = nmtst_inet4_from_string ("192.168.1.133"); - lnk_gre.remote = nmtst_inet4_from_string ("172.168.101.2"); - lnk_gre.parent_ifindex = ifindex_parent; - lnk_gre.ttl = 39; - lnk_gre.tos = 12; - lnk_gre.path_mtu_discovery = FALSE; - lnk_gre.is_tap = TRUE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gretap0")) { - /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0; - } - - if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) { - if (gracefully_skip) { - g_test_skip ("Cannot create gretap tunnel because of missing ip_gre module (modprobe ip_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding GRETAP tunnel"); - } - break; - } case NM_LINK_TYPE_IPIP: { NMPlatformLnkIpIp lnk_ipip = { }; gboolean gracefully_skip = FALSE; @@ -820,58 +794,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_IP6GRE: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::42"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::aaaa"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.tclass = 21; - lnk_ip6tnl.flow_label = 1338; - lnk_ip6tnl.is_gre = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gre tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRE tunnel"); - } - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fe80::abcd"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fc01::bbbb"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.ttl = 10; - lnk_ip6tnl.tclass = 22; - lnk_ip6tnl.flow_label = 1339; - lnk_ip6tnl.is_gre = TRUE; - lnk_ip6tnl.is_tap = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gretap tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRETAP tunnel"); - } - break; - } case NM_LINK_TYPE_MACVLAN: { NMPlatformLnkMacvlan lnk_macvlan = { }; const NMPlatformLink *dummy; @@ -1048,15 +970,16 @@ test_software_detect (gconstpointer user_data) const NMPlatformLnkGre *plnk = &lnk->lnk_gre; g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); - - break; - } - case NM_LINK_TYPE_GRETAP: { - const NMPlatformLnkGre *plnk = &lnk->lnk_gre; - - g_assert (plnk == nm_platform_link_get_lnk_gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); + g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); + g_assert_cmpint (plnk->input_flags, ==, 0); + g_assert_cmpint (plnk->output_flags, ==, 0); + g_assert_cmpint (plnk->input_key, ==, 0); + g_assert_cmpint (plnk->output_key, ==, 0); + nmtst_assert_ip4_address (plnk->local, "192.168.233.204"); + nmtst_assert_ip4_address (plnk->remote, "172.168.10.25"); + g_assert_cmpint (plnk->ttl, ==, 174); + g_assert_cmpint (plnk->tos, ==, 37); + g_assert_cmpint (plnk->path_mtu_discovery, ==, TRUE); break; } case NM_LINK_TYPE_IP6TNL: { @@ -1089,33 +1012,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_IP6GRE: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fd01::42"); - nmtst_assert_ip6_address (&plnk->remote, "fd01::aaaa"); - g_assert_cmpint (plnk->tclass, ==, 21); - g_assert_cmpint (plnk->flow_label, ==, 1338); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, FALSE); - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fe80::abcd"); - nmtst_assert_ip6_address (&plnk->remote, "fc01::bbbb"); - g_assert_cmpint (plnk->ttl, ==, 10); - g_assert_cmpint (plnk->tclass, ==, 22); - g_assert_cmpint (plnk->flow_label, ==, 1339); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, TRUE); - break; - } case NM_LINK_TYPE_IPIP: { const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip; @@ -1836,7 +1732,7 @@ test_create_many_links_do (guint n_devices) char name[64]; const NMPlatformLink *pllink; gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices); - const int EX = ((int) (nmtst_get_rand_int () % 4)) - 1; + const gint EX = ((int) (nmtst_get_rand_int () % 4)) - 1; g_assert (EX >= -1 && EX <= 2); @@ -2623,9 +2519,7 @@ test_sysctl_rename (void) case 0: { gs_free char *c = NULL; - if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024, &c, NULL, NULL) < 0) g_assert_not_reached(); g_assert_cmpint (ifindex[0], ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); break; @@ -2689,9 +2583,7 @@ test_sysctl_netns_switch (void) { gs_free char *c = NULL; - if (nm_utils_file_get_contents (dirfd, "ifindex", 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "ifindex", 0, &c, NULL, NULL) < 0) g_assert_not_reached(); g_assert_cmpint (ifindex, ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); } @@ -2703,11 +2595,7 @@ test_sysctl_netns_switch (void) { gs_free char *c = NULL; - if (nm_utils_file_get_contents (-1, - nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), - 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (-1, nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), 0, &c, NULL, NULL) < 0) ifindex_tmp = -1; else ifindex_tmp = _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -2); @@ -2722,102 +2610,6 @@ test_sysctl_netns_switch (void) /*****************************************************************************/ -static void -ethtool_features_dump (const NMEthtoolFeatureStates *features) -{ - guint i, j; - - g_assert (features); - - _LOGT (">>> %u features (%u ss-features)", features->n_states, features->n_ss_features); - - for (i = 0; i < features->n_states; i++) { - const NMEthtoolFeatureState *s = &features->states_list[i]; - - _LOGT (">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s", - i, - (int) s->info->ethtool_id, - s->info->kernel_names[s->idx_kernel_name], - s->idx_ss_features, - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { - _LOGT (">>> feature-idx [%3u]: %-32s = %u features", - i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST, - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - (guint) NM_PTRARRAY_LEN (features->states_indexed[i])); - for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) { - const NMEthtoolFeatureState *s = features->states_indexed[i][j]; - - _LOGT (">>> %3u: %-32s | %s %s %s %s", - j, - s->info->kernel_names[s->idx_kernel_name], - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - } -} - -static void -test_ethtool_features_get (void) -{ - gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func (g_free); - const int IFINDEX = 1; - guint i; - guint i_run; - - for (i_run = 0; i_run < 5; i_run++) { - NMEthtoolFeatureStates *features; - NMTernary *requested; - gboolean do_set = TRUE; - - requested = g_new (NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM); - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) - requested[i] = NM_TERNARY_DEFAULT; - g_ptr_array_add (gfree_keeper, requested); - - if (i_run == 0) { - requested[NM_ETHTOOL_ID_FEATURE_RX] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_FALSE; - } else if (i_run == 1) - do_set = FALSE; - else if (i_run == 2) { - requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_TRUE; - } else if (i_run == 3) - do_set = FALSE; - - _LOGT (">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset"); - - features = nmp_utils_ethtool_get_features (IFINDEX); - g_ptr_array_add (gfree_keeper, features); - - ethtool_features_dump (features); - - if (_LOGT_ENABLED ()) { - int ignore; - - ignore = system ("ethtool -k lo"); - (void) ignore; - } - - if (!do_set) { - requested = gfree_keeper->pdata[i_run * 2 - 2]; - features = gfree_keeper->pdata[i_run * 2 - 1]; - } - - nmp_utils_ethtool_set_features (IFINDEX, features, requested, do_set); - } -} - -/*****************************************************************************/ - NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void @@ -2849,11 +2641,8 @@ _nmtstp_setup_tests (void) g_test_add_func ("/link/external", test_external); test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0); - test_software_detect_add ("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0); test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0); test_software_detect_add ("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1); - test_software_detect_add ("/link/software/detect/ip6gre", NM_LINK_TYPE_IP6GRE, 0); - test_software_detect_add ("/link/software/detect/ip6gretap", NM_LINK_TYPE_IP6GRETAP, 0); test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0); test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0); test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0); @@ -2879,7 +2668,5 @@ _nmtstp_setup_tests (void) g_test_add_func ("/general/sysctl/rename", test_sysctl_rename); g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch); - - g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get); } } diff --git a/src/platform/wifi/nm-wifi-utils.c b/src/platform/wifi/nm-wifi-utils.c deleted file mode 100644 index 25d71c6a..00000000 --- a/src/platform/wifi/nm-wifi-utils.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#include "nm-default.h" - -#include "nm-wifi-utils.h" - -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#include "nm-wifi-utils-private.h" -#include "nm-wifi-utils-nl80211.h" -#if HAVE_WEXT -#include "nm-wifi-utils-wext.h" -#endif -#include "nm-core-utils.h" - -#include "platform/nm-platform-utils.h" - -G_DEFINE_ABSTRACT_TYPE (NMWifiUtils, nm_wifi_utils, G_TYPE_OBJECT) - -/*****************************************************************************/ - -static void -nm_wifi_utils_init (NMWifiUtils *self) -{ -} - -static void -nm_wifi_utils_class_init (NMWifiUtilsClass *klass) -{ -} - -NMWifiUtils * -nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) -{ - NMWifiUtils *ret; - - g_return_val_if_fail (ifindex > 0, NULL); - - ret = nm_wifi_utils_nl80211_new (ifindex, genl); - -#if HAVE_WEXT - if (ret == NULL) - ret = nm_wifi_utils_wext_new (ifindex, check_scan); -#endif - - return ret; -} - -NMDeviceWifiCapabilities -nm_wifi_utils_get_caps (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); - - return data->caps; -} - -NM80211Mode -nm_wifi_utils_get_mode (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_mode (data); -} - -gboolean -nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) - || (mode == NM_802_11_MODE_AP) - || (mode == NM_802_11_MODE_ADHOC), FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - /* nl80211 probably doesn't need this */ - return klass->set_mode ? klass->set_mode (data, mode) : TRUE; -} - -gboolean -nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_powersave ? klass->set_powersave (data, powersave) : TRUE; -} - -NMSettingWirelessWakeOnWLan -nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - return klass->get_wake_on_wlan ? klass->get_wake_on_wlan (data) : NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; -} - -gboolean -nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_wake_on_wlan ? klass->set_wake_on_wlan (data, wowl) : FALSE; -} - -guint32 -nm_wifi_utils_get_freq (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_freq (data); -} - -guint32 -nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs) -{ - g_return_val_if_fail (data != NULL, 0); - g_return_val_if_fail (freqs != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->find_freq (data, freqs); -} - -gboolean -nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid) -{ - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (out_bssid != NULL, FALSE); - - memset (out_bssid, 0, ETH_ALEN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_bssid (data, out_bssid); -} - -guint32 -nm_wifi_utils_get_rate (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_rate (data); -} - -int -nm_wifi_utils_get_qual (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_qual (data); -} - -gboolean -nm_wifi_utils_is_wifi (int dirfd, const char *ifname) -{ - g_return_val_if_fail (dirfd >= 0, FALSE); - - if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) - return TRUE; -#if HAVE_WEXT - if (nm_wifi_utils_wext_is_wifi (ifname)) - return TRUE; -#endif - return FALSE; -} - -/* OLPC Mesh-only functions */ - -guint32 -nm_wifi_utils_get_mesh_channel (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->get_mesh_channel != NULL, FALSE); - - return klass->get_mesh_channel (data); -} - -gboolean -nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (channel <= 13, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_channel != NULL, FALSE); - - return klass->set_mesh_channel (data, channel); -} - -gboolean -nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_ssid != NULL, FALSE); - - return klass->set_mesh_ssid (data, ssid, len); -} - -gboolean -nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->indicate_addressing_running ? klass->indicate_addressing_running (data, running) : FALSE; -} diff --git a/src/platform/wifi/nm-wifi-utils.h b/src/platform/wifi/nm-wifi-utils.h deleted file mode 100644 index 6cd178bd..00000000 --- a/src/platform/wifi/nm-wifi-utils.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#ifndef __WIFI_UTILS_H__ -#define __WIFI_UTILS_H__ - -#include <net/ethernet.h> - -#include "nm-dbus-interface.h" -#include "nm-setting-wireless.h" -#include "platform/nm-netlink.h" - -typedef struct NMWifiUtils NMWifiUtils; - -#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type ()) -#define NM_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtils)) -#define NM_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) -#define NM_IS_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS)) -#define NM_IS_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS)) -#define NM_WIFI_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) - -GType nm_wifi_utils_get_type (void); - -gboolean nm_wifi_utils_is_wifi (int dirfd, const char *ifname); - -NMWifiUtils *nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan); - -NMDeviceWifiCapabilities nm_wifi_utils_get_caps (NMWifiUtils *data); - -NM80211Mode nm_wifi_utils_get_mode (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode); - -/* Returns frequency in MHz */ -guint32 nm_wifi_utils_get_freq (NMWifiUtils *data); - -/* Return the first supported frequency in the zero-terminated list. - * Frequencies are specified in MHz. */ -guint32 nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs); - -/* out_bssid must be ETH_ALEN bytes */ -gboolean nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid); - -/* Returns current bitrate in Kbps */ -guint32 nm_wifi_utils_get_rate (NMWifiUtils *data); - -/* Returns quality 0 - 100% on succes, or -1 on error */ -int nm_wifi_utils_get_qual (NMWifiUtils *data); - -/* Tells the driver DHCP or SLAAC is running */ -gboolean nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running); - -gboolean nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave); - -NMSettingWirelessWakeOnWLan nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); - -/* OLPC Mesh-only functions */ -guint32 nm_wifi_utils_get_mesh_channel (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel); - -gboolean nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len); - -#endif /* __WIFI_UTILS_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index b3bb2bb6..6c2ff3f5 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -15,14 +15,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2011 Intel Corporation. All rights reserved. */ #include "nm-default.h" -#include "nm-wifi-utils-nl80211.h" +#include "wifi-utils-nl80211.h" #include <errno.h> #include <string.h> @@ -32,7 +32,7 @@ #include <linux/nl80211.h> #include "platform/nm-netlink.h" -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "platform/nm-platform.h" #include "platform/nm-platform-utils.h" #include "nm-utils.h" @@ -47,20 +47,14 @@ } G_STMT_END typedef struct { - NMWifiUtils parent; + WifiData parent; struct nl_sock *nl_sock; guint32 *freqs; int id; int num_freqs; int phy; bool can_wowlan:1; -} NMWifiUtilsNl80211; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsNl80211Class; - -G_DEFINE_TYPE (NMWifiUtilsNl80211, nm_wifi_utils_nl80211, NM_TYPE_WIFI_UTILS) +} WifiDataNl80211; static int ack_handler (struct nl_msg *msg, void *arg) @@ -103,7 +97,7 @@ nla_put_failure: } static struct nl_msg * -nl80211_alloc_msg (NMWifiUtilsNl80211 *nl80211, guint32 cmd, guint32 flags) +nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags) { return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, nl80211->phy, cmd, flags); } @@ -160,7 +154,7 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, } static int -nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, +nl80211_send_and_recv (WifiDataNl80211 *nl80211, struct nl_msg *msg, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) @@ -170,11 +164,13 @@ nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, } static void -dispose (GObject *object) +wifi_nl80211_deinit (WifiData *parent) { - NMWifiUtilsNl80211 *nl80211 = NM_WIFI_UTILS_NL80211 (object); + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) parent; - g_clear_pointer (&nl80211->freqs, g_free); + if (nl80211->nl_sock) + nl_socket_free (nl80211->nl_sock); + g_free (nl80211->freqs); } struct nl80211_iface_info { @@ -211,9 +207,9 @@ nl80211_iface_info_handler (struct nl_msg *msg, void *arg) } static NM80211Mode -wifi_nl80211_get_mode (NMWifiUtils *data) +wifi_nl80211_get_mode (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_iface_info iface_info = { .mode = NM_802_11_MODE_UNKNOWN, }; @@ -229,9 +225,9 @@ wifi_nl80211_get_mode (NMWifiUtils *data) } static gboolean -wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -259,9 +255,9 @@ nla_put_failure: } static gboolean -wifi_nl80211_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_nl80211_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -275,64 +271,10 @@ nla_put_failure: return FALSE; } -static int -nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg) -{ - NMSettingWirelessWakeOnWLan *wowl = arg; - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; - struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); - - nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) - return NL_SKIP; - - nla_parse (trig, MAX_NL80211_WOWLAN_TRIG, - nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - NULL); - - *wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; - if (trig[NL80211_WOWLAN_TRIG_ANY]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY; - if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT; - if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC; - if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE; - if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST; - if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE; - if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE; - if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP; - - return NL_SKIP; -} - -static NMSettingWirelessWakeOnWLan -wifi_nl80211_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; - NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; - nm_auto_nlmsg struct nl_msg *msg = NULL; - - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); - - nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl); - - return wowl; -} - static gboolean -wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) +wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *triggers; int err; @@ -340,11 +282,11 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0); + msg = nl80211_alloc_msg(nl80211, NL80211_CMD_SET_WOWLAN, 0); if (!msg) return FALSE; - triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS); + triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY)) NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY); @@ -364,8 +306,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo nla_nest_end(msg, triggers); err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: return FALSE; @@ -491,7 +432,7 @@ nl80211_bss_dump_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_bss_info (WifiDataNl80211 *nl80211, struct nl80211_bss_info *bss_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -504,9 +445,9 @@ nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, } static guint32 -wifi_nl80211_get_freq (NMWifiUtils *data) +wifi_nl80211_get_freq (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -515,9 +456,9 @@ wifi_nl80211_get_freq (NMWifiUtils *data) } static guint32 -wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_nl80211_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; int i; for (i = 0; i < nl80211->num_freqs; i++) { @@ -531,9 +472,9 @@ wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_nl80211_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_nl80211_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -615,7 +556,7 @@ nl80211_station_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_ap_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_ap_info (WifiDataNl80211 *nl80211, struct nl80211_station_info *sta_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -645,9 +586,9 @@ nla_put_failure: } static guint32 -wifi_nl80211_get_rate (NMWifiUtils *data) +wifi_nl80211_get_rate (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -656,9 +597,9 @@ wifi_nl80211_get_rate (NMWifiUtils *data) } static int -wifi_nl80211_get_qual (NMWifiUtils *data) +wifi_nl80211_get_qual (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -666,9 +607,9 @@ wifi_nl80211_get_qual (NMWifiUtils *data) } static gboolean -wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running) +wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -697,6 +638,44 @@ nla_put_failure: return FALSE; } +struct nl80211_wowlan_info { + gboolean enabled; +}; + +static int +nl80211_wowlan_handler (struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nl80211_wowlan_info *info = arg; + + info->enabled = FALSE; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_WOWLAN_TRIGGERS]) + info->enabled = TRUE; + + return NL_SKIP; +} + +static gboolean +wifi_nl80211_get_wowlan (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_wowlan_info info; + + if (!nl80211->can_wowlan) + return FALSE; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); + nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info); + return info.enabled; +} + struct nl80211_device_info { int phy; guint32 *freqs; @@ -900,58 +879,48 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) return NL_SKIP; } -static void -nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self) -{ -} - -static void -nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass) +WifiData * +wifi_nl80211_init (int ifindex) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_nl80211_get_mode; - wifi_utils_class->set_mode = wifi_nl80211_set_mode; - wifi_utils_class->set_powersave = wifi_nl80211_set_powersave; - wifi_utils_class->get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan, - wifi_utils_class->set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, - wifi_utils_class->get_freq = wifi_nl80211_get_freq; - wifi_utils_class->find_freq = wifi_nl80211_find_freq; - wifi_utils_class->get_bssid = wifi_nl80211_get_bssid; - wifi_utils_class->get_rate = wifi_nl80211_get_rate; - wifi_utils_class->get_qual = wifi_nl80211_get_qual; - wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running; -} - -NMWifiUtils * -nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) -{ - gs_unref_object NMWifiUtilsNl80211 *nl80211 = NULL; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataNl80211), + .get_mode = wifi_nl80211_get_mode, + .set_mode = wifi_nl80211_set_mode, + .set_powersave = wifi_nl80211_set_powersave, + .set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, + .get_freq = wifi_nl80211_get_freq, + .find_freq = wifi_nl80211_find_freq, + .get_bssid = wifi_nl80211_get_bssid, + .get_rate = wifi_nl80211_get_rate, + .get_qual = wifi_nl80211_get_qual, + .get_wowlan = wifi_nl80211_get_wowlan, + .indicate_addressing_running = wifi_nl80211_indicate_addressing_running, + .deinit = wifi_nl80211_deinit, + }; + WifiDataNl80211 *nl80211; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_device_info device_info = {}; char ifname[IFNAMSIZ]; - if (!genl) - return NULL; - if (!nmp_utils_if_indextoname (ifindex, ifname)) { _LOGW (LOGD_PLATFORM | LOGD_WIFI, "can't determine interface name for ifindex %d", ifindex); nm_sprintf_buf (ifname, "if %d", ifindex); } - nl80211 = g_object_new (NM_TYPE_WIFI_UTILS_NL80211, NULL); + nl80211 = wifi_data_new (&klass, ifindex); + + nl80211->nl_sock = nl_socket_alloc (); + if (nl80211->nl_sock == NULL) + goto error; - nl80211->parent.ifindex = ifindex; - nl80211->nl_sock = genl; + if (nl_connect (nl80211->nl_sock, NETLINK_GENERIC)) + goto error; nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); if (nl80211->id < 0) { _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); - return NULL; + goto error; } nl80211->phy = -1; @@ -963,42 +932,42 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request failed", ifname); - return NULL; + goto error; } if (!device_info.success) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request indicated failure", ifname); - return NULL; + goto error; } if (!device_info.supported) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not fully support nl80211, falling back to WEXT", ifname); - return NULL; + goto error; } if (!device_info.can_scan_ssid) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans", ifname); - return NULL; + goto error; } if (device_info.num_freqs == 0 || device_info.freqs == NULL) { nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver reports no supported frequencies", ifname); - return NULL; + goto error; } if (device_info.caps == 0) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver doesn't report support of any encryption", ifname); - return NULL; + goto error; } nl80211->phy = device_info.phy; @@ -1010,5 +979,10 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGI (LOGD_PLATFORM | LOGD_WIFI, "(%s): using nl80211 for WiFi device control", ifname); - return (NMWifiUtils *) g_steal_pointer (&nl80211); + return (WifiData *) nl80211; + +error: + wifi_utils_unref ((WifiData *) nl80211); + return NULL; } + diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.h b/src/platform/wifi/wifi-utils-nl80211.h index 27f67697..aff24555 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.h +++ b/src/platform/wifi/wifi-utils-nl80211.h @@ -16,24 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2011 Intel Corporation. All rights reserved. - * Copyright (C) 2018 Red Hat, Inc. */ #ifndef __WIFI_UTILS_NL80211_H__ #define __WIFI_UTILS_NL80211_H__ -#include "nm-wifi-utils.h" -#include "platform/nm-netlink.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_NL80211 (nm_wifi_utils_nl80211_get_type ()) -#define NM_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211)) -#define NM_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) -#define NM_IS_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_IS_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_WIFI_UTILS_NL80211_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) - -GType nm_wifi_utils_nl80211_get_type (void); - -NMWifiUtils *nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl); +WifiData *wifi_nl80211_init (int ifindex); #endif /* __WIFI_UTILS_NL80211_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index bcbc1c51..627108cb 100644 --- a/src/platform/wifi/nm-wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -15,65 +15,67 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_PRIVATE_H__ #define __WIFI_UTILS_PRIVATE_H__ #include "nm-dbus-interface.h" -#include "nm-wifi-utils.h" +#include "wifi-utils.h" typedef struct { - GObjectClass parent; + gsize struct_size; - NM80211Mode (*get_mode) (NMWifiUtils *data); + NM80211Mode (*get_mode) (WifiData *data); - gboolean (*set_mode) (NMWifiUtils *data, const NM80211Mode mode); + gboolean (*set_mode) (WifiData *data, const NM80211Mode mode); /* Set power saving mode on an interface */ - gboolean (*set_powersave) (NMWifiUtils *data, guint32 powersave); - - /* Get WakeOnWLAN configuration on an interface */ - NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (NMWifiUtils *data); + gboolean (*set_powersave) (WifiData *data, guint32 powersave); /* Set WakeOnWLAN mode on an interface */ - gboolean (*set_wake_on_wlan) (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); + gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl); /* Return current frequency in MHz (really associated BSS frequency) */ - guint32 (*get_freq) (NMWifiUtils *data); + guint32 (*get_freq) (WifiData *data); /* Return first supported frequency in the zero-terminated list */ - guint32 (*find_freq) (NMWifiUtils *data, const guint32 *freqs); + guint32 (*find_freq) (WifiData *data, const guint32 *freqs); /* Return current bitrate in Kbps */ - guint32 (*get_rate) (NMWifiUtils *data); + guint32 (*get_rate) (WifiData *data); - gboolean (*get_bssid) (NMWifiUtils *data, guint8 *out_bssid); + gboolean (*get_bssid) (WifiData *data, guint8 *out_bssid); /* Return a signal strength percentage 0 - 100% for the current BSSID; * return -1 on errors or if not associated. */ - int (*get_qual) (NMWifiUtils *data); + int (*get_qual) (WifiData *data); + + void (*deinit) (WifiData *data); + + gboolean (*get_wowlan) (WifiData *data); /* OLPC Mesh-only functions */ - guint32 (*get_mesh_channel) (NMWifiUtils *data); + guint32 (*get_mesh_channel) (WifiData *data); /* channel == 0 means "auto channel" */ - gboolean (*set_mesh_channel) (NMWifiUtils *data, guint32 channel); + gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); /* ssid == NULL means "auto SSID" */ - gboolean (*set_mesh_ssid) (NMWifiUtils *data, const guint8 *ssid, gsize len); + gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len); - gboolean (*indicate_addressing_running) (NMWifiUtils *data, gboolean running); -} NMWifiUtilsClass; - -struct NMWifiUtils { - GObject parent; + gboolean (*indicate_addressing_running) (WifiData *data, gboolean running); +} WifiDataClass; +struct WifiData { + const WifiDataClass *klass; int ifindex; NMDeviceWifiCapabilities caps; }; +gpointer wifi_data_new (const WifiDataClass *klass, int ifindex); + #endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index e52ae5a3..c8744f79 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -15,13 +15,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ #include "nm-default.h" -#include "nm-wifi-utils-wext.h" +#include "wifi-utils-wext.h" #include <errno.h> #include <string.h> @@ -38,24 +38,17 @@ #include <sys/socket.h> #include <linux/wireless.h> -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "nm-utils.h" #include "platform/nm-platform-utils.h" -#include "nm-core-internal.h" typedef struct { - NMWifiUtils parent; + WifiData parent; int fd; struct iw_quality max_qual; gint8 num_freqs; guint32 freqs[IW_MAX_FREQUENCIES]; -} NMWifiUtilsWext; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsWextClass; - -G_DEFINE_TYPE (NMWifiUtilsWext, nm_wifi_utils_wext, NM_TYPE_WIFI_UTILS) +} WifiDataWext; /* Until a new wireless-tools comes out that has the defs and the structure, * need to copy them here. @@ -101,11 +94,11 @@ iw_freq_to_uint32 (const struct iw_freq *freq) } static void -dispose (GObject *object) +wifi_wext_deinit (WifiData *parent) { - NMWifiUtilsWext *wext = NM_WIFI_UTILS_WEXT (object); + WifiDataWext *wext = (WifiDataWext *) parent; - wext->fd = nm_close (wext->fd); + nm_close (wext->fd); } static gboolean @@ -125,9 +118,9 @@ get_ifname (int ifindex, char *buffer, const char *op) } static NM80211Mode -wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) +wifi_wext_get_mode_ifname (WifiData *data, const char *ifname) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; memset (&wrq, 0, sizeof (struct iwreq)); @@ -157,7 +150,7 @@ wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) } static NM80211Mode -wifi_wext_get_mode (NMWifiUtils *data) +wifi_wext_get_mode (WifiData *data) { char ifname[IFNAMSIZ]; @@ -168,9 +161,9 @@ wifi_wext_get_mode (NMWifiUtils *data) } static gboolean -wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_wext_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -210,9 +203,9 @@ wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) } static gboolean -wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_wext_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -239,9 +232,9 @@ wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) } static guint32 -wifi_wext_get_freq (NMWifiUtils *data) +wifi_wext_get_freq (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -261,9 +254,9 @@ wifi_wext_get_freq (NMWifiUtils *data) } static guint32 -wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_wext_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; int i; for (i = 0; i < wext->num_freqs; i++) { @@ -277,9 +270,9 @@ wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -299,9 +292,9 @@ wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) } static guint32 -wifi_wext_get_rate (NMWifiUtils *data) +wifi_wext_get_rate (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; int err; char ifname[IFNAMSIZ]; @@ -410,9 +403,9 @@ wext_qual_to_percent (const struct iw_quality *qual, } static int -wifi_wext_get_qual (NMWifiUtils *data) +wifi_wext_get_qual (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; struct iw_statistics stats; char ifname[IFNAMSIZ]; @@ -440,13 +433,13 @@ wifi_wext_get_qual (NMWifiUtils *data) /* OLPC Mesh-only functions */ static guint32 -wifi_wext_get_mesh_channel (NMWifiUtils *data) +wifi_wext_get_mesh_channel (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; guint32 freq; int i; - freq = nm_wifi_utils_get_freq (data); + freq = wifi_utils_get_freq (data); for (i = 0; i < wext->num_freqs; i++) { if (freq == wext->freqs[i]) return i + 1; @@ -455,9 +448,9 @@ wifi_wext_get_mesh_channel (NMWifiUtils *data) } static gboolean -wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) +wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -484,9 +477,9 @@ wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) } static gboolean -wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) +wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char buf[IW_ESSID_MAX_SIZE + 1]; char ifname[IFNAMSIZ]; @@ -507,13 +500,11 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) return TRUE; if (errno != ENODEV) { - gs_free char *ssid_str = NULL; - errsv = errno; _LOGE (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, "(%s): error setting SSID to '%s': %s", ifname, - (ssid_str = _nm_utils_ssid_to_string_arr (ssid, len)), + ssid ? nm_utils_escape_ssid (ssid, len) : "(null)", strerror (errsv)); } @@ -523,7 +514,7 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) /*****************************************************************************/ static gboolean -wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) +wext_can_scan_ifname (WifiDataWext *wext, const char *ifname) { struct iwreq wrq; @@ -537,7 +528,7 @@ wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) } static gboolean -wext_get_range_ifname (NMWifiUtilsWext *wext, +wext_get_range_ifname (WifiDataWext *wext, const char *ifname, struct iw_range *range, guint32 *response_len) @@ -586,7 +577,7 @@ wext_get_range_ifname (NMWifiUtilsWext *wext, NM_WIFI_DEVICE_CAP_RSN) static guint32 -wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range) +wext_get_caps (WifiDataWext *wext, const char *ifname, struct iw_range *range) { guint32 caps = NM_WIFI_DEVICE_CAP_NONE; @@ -635,38 +626,25 @@ wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range return caps; } -/*****************************************************************************/ - -static void -nm_wifi_utils_wext_init (NMWifiUtilsWext *self) -{ -} - -static void -nm_wifi_utils_wext_class_init (NMWifiUtilsWextClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_wext_get_mode; - wifi_utils_class->set_mode = wifi_wext_set_mode; - wifi_utils_class->set_powersave = wifi_wext_set_powersave; - wifi_utils_class->get_freq = wifi_wext_get_freq; - wifi_utils_class->find_freq = wifi_wext_find_freq; - wifi_utils_class->get_bssid = wifi_wext_get_bssid; - wifi_utils_class->get_rate = wifi_wext_get_rate; - wifi_utils_class->get_qual = wifi_wext_get_qual; - wifi_utils_class->get_mesh_channel = wifi_wext_get_mesh_channel; - wifi_utils_class->set_mesh_channel = wifi_wext_set_mesh_channel; - wifi_utils_class->set_mesh_ssid = wifi_wext_set_mesh_ssid; -} - -NMWifiUtils * -nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) +WifiData * +wifi_wext_init (int ifindex, gboolean check_scan) { - NMWifiUtilsWext *wext; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataWext), + .get_mode = wifi_wext_get_mode, + .set_mode = wifi_wext_set_mode, + .set_powersave = wifi_wext_set_powersave, + .get_freq = wifi_wext_get_freq, + .find_freq = wifi_wext_find_freq, + .get_bssid = wifi_wext_get_bssid, + .get_rate = wifi_wext_get_rate, + .get_qual = wifi_wext_get_qual, + .deinit = wifi_wext_deinit, + .get_mesh_channel = wifi_wext_get_mesh_channel, + .set_mesh_channel = wifi_wext_set_mesh_channel, + .set_mesh_ssid = wifi_wext_set_mesh_ssid, + }; + WifiDataWext *wext; struct iw_range range; guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; @@ -680,9 +658,8 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) return NULL; } - wext = g_object_new (NM_TYPE_WIFI_UTILS_WEXT, NULL); + wext = wifi_data_new (&klass, ifindex); - wext->parent.ifindex = ifindex; wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) goto error; @@ -754,15 +731,15 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) "(%s): using WEXT for WiFi device control", ifname); - return (NMWifiUtils *) wext; + return (WifiData *) wext; error: - g_object_unref (wext); + wifi_utils_unref ((WifiData *) wext); return NULL; } gboolean -nm_wifi_utils_wext_is_wifi (const char *iface) +wifi_wext_is_wifi (const char *iface) { int fd; struct iwreq iwr; diff --git a/src/platform/wifi/nm-wifi-utils-wext.h b/src/platform/wifi/wifi-utils-wext.h index 44b11afb..3ef5a173 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.h +++ b/src/platform/wifi/wifi-utils-wext.h @@ -15,25 +15,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_WEXT_H__ #define __WIFI_UTILS_WEXT_H__ -#include "nm-wifi-utils.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_WEXT (nm_wifi_utils_wext_get_type ()) -#define NM_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWext)) -#define NM_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) -#define NM_IS_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_IS_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_WIFI_UTILS_WEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) +WifiData *wifi_wext_init (int ifindex, gboolean check_scan); -GType nm_wifi_utils_wext_get_type (void); - -NMWifiUtils *nm_wifi_utils_wext_new (int ifindex, gboolean check_scan); - -gboolean nm_wifi_utils_wext_is_wifi (const char *iface); +gboolean wifi_wext_is_wifi (const char *iface); #endif /* __WIFI_UTILS_WEXT_H__ */ diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c new file mode 100644 index 00000000..b3dd92ba --- /dev/null +++ b/src/platform/wifi/wifi-utils.c @@ -0,0 +1,231 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "nm-default.h" + +#include "wifi-utils.h" + +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> + +#include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" +#if HAVE_WEXT +#include "wifi-utils-wext.h" +#endif +#include "nm-core-utils.h" + +#include "platform/nm-platform-utils.h" + +gpointer +wifi_data_new (const WifiDataClass *klass, int ifindex) +{ + WifiData *data; + + nm_assert (klass); + nm_assert (klass->struct_size > sizeof (WifiData)); + + data = g_malloc0 (klass->struct_size); + data->klass = klass; + data->ifindex = ifindex; + return data; +} + +/*****************************************************************************/ + +WifiData * +wifi_utils_init (int ifindex, gboolean check_scan) +{ + WifiData *ret; + + g_return_val_if_fail (ifindex > 0, NULL); + + ret = wifi_nl80211_init (ifindex); + if (ret == NULL) { +#if HAVE_WEXT + ret = wifi_wext_init (ifindex, check_scan); +#endif + } + return ret; +} + +int +wifi_utils_get_ifindex (WifiData *data) +{ + g_return_val_if_fail (data != NULL, -1); + + return data->ifindex; +} + +NMDeviceWifiCapabilities +wifi_utils_get_caps (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); + + return data->caps; +} + +NM80211Mode +wifi_utils_get_mode (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); + return data->klass->get_mode (data); +} + +gboolean +wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) + || (mode == NM_802_11_MODE_AP) + || (mode == NM_802_11_MODE_ADHOC), FALSE); + + /* nl80211 probably doesn't need this */ + return data->klass->set_mode ? data->klass->set_mode (data, mode) : TRUE; +} + +gboolean +wifi_utils_set_powersave (WifiData *data, guint32 powersave) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE; +} + +gboolean +wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_wake_on_wlan ? + data->klass->set_wake_on_wlan (data, wowl) : FALSE; +} + +guint32 +wifi_utils_get_freq (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_freq (data); +} + +guint32 +wifi_utils_find_freq (WifiData *data, const guint32 *freqs) +{ + g_return_val_if_fail (data != NULL, 0); + g_return_val_if_fail (freqs != NULL, 0); + return data->klass->find_freq (data, freqs); +} + +gboolean +wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (out_bssid != NULL, FALSE); + + memset (out_bssid, 0, ETH_ALEN); + return data->klass->get_bssid (data, out_bssid); +} + +guint32 +wifi_utils_get_rate (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_rate (data); +} + +int +wifi_utils_get_qual (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_qual (data); +} + +gboolean +wifi_utils_get_wowlan (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + + if (!data->klass->get_wowlan) + return FALSE; + return data->klass->get_wowlan (data); +} + +void +wifi_utils_unref (WifiData *data) +{ + g_return_if_fail (data != NULL); + + data->klass->deinit (data); + g_free (data); +} + +gboolean +wifi_utils_is_wifi (int dirfd, const char *ifname) +{ + g_return_val_if_fail (dirfd >= 0, FALSE); + + if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) + return TRUE; +#if HAVE_WEXT + if (wifi_wext_is_wifi (ifname)) + return TRUE; +#endif + return FALSE; +} + +/* OLPC Mesh-only functions */ + +guint32 +wifi_utils_get_mesh_channel (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->get_mesh_channel != NULL, FALSE); + return data->klass->get_mesh_channel (data); +} + +gboolean +wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (channel <= 13, FALSE); + g_return_val_if_fail (data->klass->set_mesh_channel != NULL, FALSE); + return data->klass->set_mesh_channel (data, channel); +} + +gboolean +wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->set_mesh_ssid != NULL, FALSE); + return data->klass->set_mesh_ssid (data, ssid, len); +} + +gboolean +wifi_utils_indicate_addressing_running (WifiData *data, gboolean running) +{ + g_return_val_if_fail (data != NULL, FALSE); + if (data->klass->indicate_addressing_running) + return data->klass->indicate_addressing_running (data, running); + return FALSE; +} + diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h new file mode 100644 index 00000000..c69561de --- /dev/null +++ b/src/platform/wifi/wifi-utils.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __WIFI_UTILS_H__ +#define __WIFI_UTILS_H__ + +#include <net/ethernet.h> + +#include "nm-dbus-interface.h" +#include "nm-setting-wireless.h" + +typedef struct WifiData WifiData; + +gboolean wifi_utils_is_wifi (int dirfd, const char *ifname); + +WifiData *wifi_utils_init (int ifindex, gboolean check_scan); + +int wifi_utils_get_ifindex (WifiData *data); + +void wifi_utils_unref (WifiData *data); + +NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); + +NM80211Mode wifi_utils_get_mode (WifiData *data); + +gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); + +/* Returns frequency in MHz */ +guint32 wifi_utils_get_freq (WifiData *data); + +/* Return the first supported frequency in the zero-terminated list. + * Frequencies are specified in MHz. */ +guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); + +/* out_bssid must be ETH_ALEN bytes */ +gboolean wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid); + +/* Returns current bitrate in Kbps */ +guint32 wifi_utils_get_rate (WifiData *data); + +/* Returns quality 0 - 100% on succes, or -1 on error */ +int wifi_utils_get_qual (WifiData *data); + +/* Tells the driver DHCP or SLAAC is running */ +gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running); + +/* Returns true if WoWLAN is enabled on device */ +gboolean wifi_utils_get_wowlan (WifiData *data); + +gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave); + +gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl); + +/* OLPC Mesh-only functions */ +guint32 wifi_utils_get_mesh_channel (WifiData *data); + +gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); + +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len); + +#endif /* __WIFI_UTILS_H__ */ diff --git a/src/platform/wpan/nm-wpan-utils.c b/src/platform/wpan/nm-wpan-utils.c deleted file mode 100644 index 0544539a..00000000 --- a/src/platform/wpan/nm-wpan-utils.c +++ /dev/null @@ -1,286 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-wpan-utils.h" - -#include "platform/linux/nl802154.h" -#include "platform/nm-netlink.h" - -#define _NMLOG_PREFIX_NAME "wpan-nl802154" -#define _NMLOG(level, domain, ...) \ - G_STMT_START { \ - nm_log ((level), (domain), NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END - -/*****************************************************************************/ - -struct NMWpanUtils { - GObject parent; - int ifindex; - struct nl_sock *nl_sock; - int id; -}; - -typedef struct { - GObjectClass parent; -} NMWpanUtilsClass; - -G_DEFINE_TYPE (NMWpanUtils, nm_wpan_utils, G_TYPE_OBJECT) - -/*****************************************************************************/ - -static int -ack_handler (struct nl_msg *msg, void *arg) -{ - int *done = arg; - *done = 1; - return NL_STOP; -} - -static int -finish_handler (struct nl_msg *msg, void *arg) -{ - int *done = arg; - *done = 1; - return NL_SKIP; -} - -static int -error_handler (struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) -{ - int *done = arg; - *done = err->error; - return NL_SKIP; -} - -static struct nl_msg * -_nl802154_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - - msg = nlmsg_alloc (); - genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0); - NLA_PUT_U32 (msg, NL802154_ATTR_IFINDEX, ifindex); - return g_steal_pointer (&msg); - -nla_put_failure: - return NULL; -} - -static struct nl_msg * -nl802154_alloc_msg (NMWpanUtils *self, guint32 cmd, guint32 flags) -{ - return _nl802154_alloc_msg (self->id, self->ifindex, cmd, flags); -} - -static int -_nl802154_send_and_recv (struct nl_sock *nl_sock, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - int err; - int done = 0; - const struct nl_cb cb = { - .err_cb = error_handler, - .err_arg = &done, - .finish_cb = finish_handler, - .finish_arg = &done, - .ack_cb = ack_handler, - .ack_arg = &done, - .valid_cb = valid_handler, - .valid_arg = valid_data, - }; - - g_return_val_if_fail (msg != NULL, -ENOMEM); - - err = nl_send_auto (nl_sock, msg); - if (err < 0) - return err; - - /* Loop until one of our NL callbacks says we're done; on success - * done will be 1, on error it will be < 0. - */ - while (!done) { - err = nl_recvmsgs (nl_sock, &cb); - if (err < 0 && err != -EAGAIN) { - _LOGW (LOGD_PLATFORM, "nl_recvmsgs() error: (%d) %s", - err, nl_geterror (err)); - break; - } - } - - if (err >= 0 && done < 0) - err = done; - return err; -} - -static int -nl802154_send_and_recv (NMWpanUtils *self, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - return _nl802154_send_and_recv (self->nl_sock, msg, - valid_handler, valid_data); -} - -struct nl802154_interface { - guint16 pan_id; - guint16 short_addr; - - gboolean valid; -}; - -static int -nl802154_get_interface_handler (struct nl_msg *msg, void *arg) -{ - struct nl802154_interface *info = arg; - struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); - struct nlattr *tb[NL802154_ATTR_MAX + 1] = { 0, }; - static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX + 1] = { - [NL802154_ATTR_PAN_ID] = { .type = NLA_U16 }, - [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16 }, - }; - - if (nla_parse (tb, NL802154_ATTR_MAX, genlmsg_attrdata (gnlh, 0), - genlmsg_attrlen (gnlh, 0), nl802154_policy) < 0) - return NL_SKIP; - - if (tb[NL802154_ATTR_PAN_ID]) - info->pan_id = le16toh (nla_get_u16 (tb[NL802154_ATTR_PAN_ID])); - - if (tb[NL802154_ATTR_SHORT_ADDR]) - info->short_addr = le16toh (nla_get_u16 (tb[NL802154_ATTR_SHORT_ADDR])); - - info->valid = TRUE; - - return NL_SKIP; -} - -static void -nl802154_get_interface (NMWpanUtils *self, - struct nl802154_interface *interface) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - - memset (interface, 0, sizeof (*interface)); - - msg = nl802154_alloc_msg (self, NL802154_CMD_GET_INTERFACE, 0); - - nl802154_send_and_recv (self, msg, nl802154_get_interface_handler, interface); -} - -/*****************************************************************************/ - -guint16 -nm_wpan_utils_get_pan_id (NMWpanUtils *self) -{ - struct nl802154_interface interface; - - nl802154_get_interface (self, &interface); - - return interface.pan_id; -} - -gboolean -nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - int err; - - g_return_val_if_fail (self != NULL, FALSE); - - msg = nl802154_alloc_msg (self, NL802154_CMD_SET_PAN_ID, 0); - NLA_PUT_U16 (msg, NL802154_ATTR_PAN_ID, htole16 (pan_id)); - err = nl802154_send_and_recv (self, msg, NULL, NULL); - return err >= 0; - -nla_put_failure: - return FALSE; -} - -guint16 -nm_wpan_utils_get_short_addr (NMWpanUtils *self) -{ - struct nl802154_interface interface; - - nl802154_get_interface (self, &interface); - - return interface.short_addr; -} - -gboolean -nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - int err; - - g_return_val_if_fail (self != NULL, FALSE); - - msg = nl802154_alloc_msg (self, NL802154_CMD_SET_SHORT_ADDR, 0); - NLA_PUT_U16 (msg, NL802154_ATTR_SHORT_ADDR, htole16 (short_addr)); - err = nl802154_send_and_recv (self, msg, NULL, NULL); - return err >= 0; - -nla_put_failure: - return FALSE; -} - -/*****************************************************************************/ - -static void -nm_wpan_utils_init (NMWpanUtils *self) -{ -} - -static void -nm_wpan_utils_class_init (NMWpanUtilsClass *klass) -{ -} - -NMWpanUtils * -nm_wpan_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) -{ - NMWpanUtils *self; - int id; - - g_return_val_if_fail (ifindex > 0, NULL); - - if (!genl) - return NULL; - - id = genl_ctrl_resolve (genl, "nl802154"); - if (id < 0) { - _LOGD (LOGD_PLATFORM, "genl_ctrl_resolve: failed to resolve \"nl802154\""); - return NULL; - } - - self = g_object_new (NM_TYPE_WPAN_UTILS, NULL); - self->ifindex = ifindex; - self->nl_sock = genl; - self->id = id; - - return self; -} diff --git a/src/platform/wpan/nm-wpan-utils.h b/src/platform/wpan/nm-wpan-utils.h deleted file mode 100644 index f7d0c03e..00000000 --- a/src/platform/wpan/nm-wpan-utils.h +++ /dev/null @@ -1,47 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2018 Red Hat, Inc. - */ - -#ifndef __WPAN_UTILS_H__ -#define __WPAN_UTILS_H__ - -#include <net/ethernet.h> - -#include "nm-dbus-interface.h" -#include "platform/nm-netlink.h" - -typedef struct NMWpanUtils NMWpanUtils; - -#define NM_TYPE_WPAN_UTILS (nm_wpan_utils_get_type ()) -#define NM_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WPAN_UTILS, NMWpanUtils)) -#define NM_WPAN_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) -#define NM_IS_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WPAN_UTILS)) -#define NM_IS_WPAN_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WPAN_UTILS)) -#define NM_WPAN_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) - -GType nm_wpan_utils_get_type (void); - -NMWpanUtils *nm_wpan_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan); - -guint16 nm_wpan_utils_get_pan_id (NMWpanUtils *self); -gboolean nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id); - -guint16 nm_wpan_utils_get_short_addr (NMWpanUtils *self); -gboolean nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr); - -#endif /* __WPAN_UTILS_H__ */ |