diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/nm-fake-platform.c | 35 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 295 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.h | 2 | ||||
| -rw-r--r-- | src/platform/nm-platform-utils.c | 27 | ||||
| -rw-r--r-- | src/platform/nm-platform-utils.h | 4 | ||||
| -rw-r--r-- | src/platform/nm-platform.c | 128 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 84 | ||||
| -rw-r--r-- | src/platform/nmp-object.c | 13 | ||||
| -rw-r--r-- | src/platform/nmp-object.h | 8 | ||||
| -rw-r--r-- | src/platform/tests/monitor.c | 23 | ||||
| -rw-r--r-- | src/platform/tests/test-address.c | 28 | ||||
| -rw-r--r-- | src/platform/tests/test-cleanup.c | 24 | ||||
| -rw-r--r-- | src/platform/tests/test-common.c | 30 | ||||
| -rw-r--r-- | src/platform/tests/test-link.c | 36 | ||||
| -rw-r--r-- | src/platform/tests/test-nmp-object.c | 4 | ||||
| -rw-r--r-- | src/platform/tests/test-route.c | 25 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-nl80211.c | 3 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-wext.c | 6 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.c | 3 |
19 files changed, 475 insertions, 303 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index a4eae902..68b72b19 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -18,7 +18,9 @@ * Copyright (C) 2012–2013 Red Hat, Inc. */ -#include "config.h" +#include "nm-default.h" + +#include "nm-fake-platform.h" #include <errno.h> #include <unistd.h> @@ -27,10 +29,9 @@ #include <linux/rtnetlink.h> #include "nm-utils.h" + +#include "nm-core-utils.h" #include "nmp-object.h" -#include "NetworkManagerUtils.h" -#include "nm-fake-platform.h" -#include "nm-default.h" #include "nm-test-utils.h" @@ -173,10 +174,10 @@ link_init (NMFakePlatformLink *device, int ifindex, int type, const char *name) strcpy (device->link.name, name); switch (device->link.type) { case NM_LINK_TYPE_DUMMY: - device->link.flags = NM_FLAGS_SET (device->link.flags, IFF_NOARP); + device->link.n_ifi_flags = NM_FLAGS_SET (device->link.n_ifi_flags, IFF_NOARP); break; default: - device->link.flags = NM_FLAGS_UNSET (device->link.flags, IFF_NOARP); + device->link.n_ifi_flags = NM_FLAGS_UNSET (device->link.n_ifi_flags, IFF_NOARP); break; } } @@ -440,9 +441,9 @@ link_set_up (NMPlatform *platform, int ifindex, gboolean *out_no_firmware) g_error ("Unexpected device type: %d", device->link.type); } - if ( NM_FLAGS_HAS (device->link.flags, IFF_UP) != !!up + if ( NM_FLAGS_HAS (device->link.n_ifi_flags, IFF_UP) != !!up || device->link.connected != connected) { - device->link.flags = NM_FLAGS_ASSIGN (device->link.flags, IFF_UP, up); + device->link.n_ifi_flags = NM_FLAGS_ASSIGN (device->link.n_ifi_flags, IFF_UP, up); device->link.connected = connected; link_changed (platform, device, TRUE); } @@ -460,8 +461,8 @@ link_set_down (NMPlatform *platform, int ifindex) return FALSE; } - if (NM_FLAGS_HAS (device->link.flags, IFF_UP) || device->link.connected) { - device->link.flags = NM_FLAGS_UNSET (device->link.flags, IFF_UP); + if (NM_FLAGS_HAS (device->link.n_ifi_flags, IFF_UP) || device->link.connected) { + device->link.n_ifi_flags = NM_FLAGS_UNSET (device->link.n_ifi_flags, IFF_UP); device->link.connected = FALSE; link_changed (platform, device, TRUE); @@ -480,7 +481,7 @@ link_set_arp (NMPlatform *platform, int ifindex) return FALSE; } - device->link.flags = NM_FLAGS_UNSET (device->link.flags, IFF_NOARP); + device->link.n_ifi_flags = NM_FLAGS_UNSET (device->link.n_ifi_flags, IFF_NOARP); link_changed (platform, device, TRUE); @@ -497,7 +498,7 @@ link_set_noarp (NMPlatform *platform, int ifindex) return FALSE; } - device->link.flags = NM_FLAGS_SET (device->link.flags, IFF_NOARP); + device->link.n_ifi_flags = NM_FLAGS_SET (device->link.n_ifi_flags, IFF_NOARP); link_changed (platform, device, TRUE); @@ -509,7 +510,8 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t { NMFakePlatformLink *device = link_get (platform, ifindex); - if ( len == 0 + if ( !device + || len == 0 || len > NM_UTILS_HWADDR_LEN_MAX || !addr) g_return_val_if_reached (FALSE); @@ -611,7 +613,7 @@ link_enslave (NMPlatform *platform, int master, int slave) device->link.master = master; if (NM_IN_SET (master_device->link.type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) { - device->link.flags = NM_FLAGS_SET (device->link.flags, IFF_UP); + device->link.n_ifi_flags = NM_FLAGS_SET (device->link.n_ifi_flags, IFF_UP); device->link.connected = TRUE; } @@ -937,7 +939,8 @@ ip6_address_add (NMPlatform *platform, int plen, struct in6_addr peer_addr, guint32 lifetime, - guint32 preferred, guint flags) + guint32 preferred, + guint32 flags) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); NMPlatformIP6Address address; @@ -952,7 +955,7 @@ ip6_address_add (NMPlatform *platform, address.timestamp = nm_utils_get_monotonic_timestamp_s (); address.lifetime = lifetime; address.preferred = preferred; - address.flags = flags; + address.n_ifa_flags = flags; for (i = 0; i < priv->ip6_addresses->len; i++) { NMPlatformIP6Address *item = &g_array_index (priv->ip6_addresses, NMPlatformIP6Address, i); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f73c228b..196e75cb 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -17,7 +17,9 @@ * * Copyright (C) 2012-2015 Red Hat, Inc. */ -#include "config.h" +#include "nm-default.h" + +#include "nm-linux-platform.h" #include <errno.h> #include <unistd.h> @@ -42,22 +44,21 @@ #include <netlink/route/route.h> #include <gudev/gudev.h> +#include "nm-utils.h" #include "nm-core-internal.h" -#include "NetworkManagerUtils.h" -#include "nm-linux-platform.h" +#include "nm-setting-vlan.h" + +#include "nm-core-utils.h" +#include "nmp-object.h" #include "nm-platform-utils.h" -#include "NetworkManagerUtils.h" -#include "nm-utils.h" -#include "nm-default.h" #include "wifi/wifi-utils.h" #include "wifi/wifi-utils-wext.h" -#include "nmp-object.h" - -/* This is only included for the translation of VLAN flags */ -#include "nm-setting-vlan.h" #define VLAN_FLAG_MVRP 0x8 +/* nm-internal error codes for libnl. Make sure they don't overlap. */ +#define _NLE_NM_NOBUFS 500 + /*********************************************************************************************/ #define IFQDISCSIZ 32 @@ -115,8 +116,26 @@ #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 _NMLOG2(level, ...) _LOG(level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) +#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; \ + const void *const __self = (self); \ + \ + if (__self && __self != nm_platform_try_get ()) { \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log (__level, __domain, __errsv, \ + "%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 { \ @@ -124,20 +143,30 @@ const NMLogDomain __domain = (domain); \ \ if (nm_logging_enabled (__level, __domain)) { \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const void *const __self = (self); \ + _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); \ \ - if (__self && __self != nm_platform_try_get ()) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, __domain, 0, \ - "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + /* 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 + #define LOG_FMT_IP_TUNNEL "adding %s '%s' parent %u local %s remote %s" /****************************************************************** @@ -257,17 +286,6 @@ _support_user_ipv6ll_detect (struct nlattr **tb) * Various utilities ******************************************************************/ -const NMIPAddr nm_ip_addr_zero = NMIPAddrInit; - -#define IPV4LL_NETWORK (htonl (0xA9FE0000L)) -#define IPV4LL_NETMASK (htonl (0xFFFF0000L)) - -static gboolean -ip4_address_is_link_local (in_addr_t addr) -{ - return (addr & IPV4LL_NETMASK) == IPV4LL_NETWORK; -} - static guint _nm_ip_config_source_to_rtprot (NMIPConfigSource source) { @@ -579,7 +597,7 @@ _lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_fro if (!*completed_from_cache) { obj = ifindex > 0 && cache ? nmp_cache_lookup_link (cache, ifindex) : NULL; - if (obj && !obj->_link.netlink.is_in_netlink) + if (obj && obj->_link.netlink.is_in_netlink) *link_cached = obj; else *link_cached = NULL; @@ -605,8 +623,8 @@ _linktype_read_devtype (const char *sysfs_path) end = strpbrk (cont, "\r\n"); if (end) *end++ = '\0'; - if (strncmp (cont, DEVTYPE_PREFIX, STRLEN (DEVTYPE_PREFIX)) == 0) { - cont += STRLEN (DEVTYPE_PREFIX); + if (strncmp (cont, DEVTYPE_PREFIX, NM_STRLEN (DEVTYPE_PREFIX)) == 0) { + cont += NM_STRLEN (DEVTYPE_PREFIX); memmove (contents, cont, strlen (cont) + 1); return contents; } @@ -732,13 +750,19 @@ _linktype_get_type (NMPlatform *platform, if (wifi_utils_is_wifi (ifname, sysfs_path)) return NM_LINK_TYPE_WIFI; - /* Standard wired ethernet interfaces don't report an rtnl_link_type, so - * only allow fallback to Ethernet if no type is given. This should - * prevent future virtual network drivers from being treated as Ethernet - * when they should be Generic instead. - */ - if (arptype == ARPHRD_ETHER && !kind && !devtype) - return NM_LINK_TYPE_ETHERNET; + if (arptype == ARPHRD_ETHER) { + /* Standard wired ethernet interfaces don't report an rtnl_link_type, so + * only allow fallback to Ethernet if no type is given. This should + * prevent future virtual network drivers from being treated as Ethernet + * when they should be Generic instead. + */ + if (!kind && !devtype) + return NM_LINK_TYPE_ETHERNET; + /* The USB gadget interfaces behave and look like ordinary ethernet devices + * aside from the DEVTYPE. */ + if (!g_strcmp0 (devtype, "gadget")) + return NM_LINK_TYPE_ETHERNET; + } } return NM_LINK_TYPE_UNKNOWN; @@ -1464,8 +1488,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr nl_info_data = li[IFLA_INFO_DATA]; } - obj->link.flags = ifi->ifi_flags; - obj->link.connected = NM_FLAGS_HAS (obj->link.flags, IFF_LOWER_UP); + obj->link.n_ifi_flags = ifi->ifi_flags; + obj->link.connected = NM_FLAGS_HAS (obj->link.n_ifi_flags, IFF_LOWER_UP); obj->link.arptype = ifi->ifi_type; obj->link.type = _linktype_get_type (platform, @@ -1473,7 +1497,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr nl_info_kind, obj->link.ifindex, obj->link.name, - obj->link.flags, + obj->link.n_ifi_flags, obj->link.arptype, completed_from_cache, &link_cached, @@ -1650,9 +1674,9 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) obj->ip_address.source = NM_IP_CONFIG_SOURCE_KERNEL; if (!is_v4) { - obj->ip6_address.flags = tb[IFA_FLAGS] - ? nla_get_u32 (tb[IFA_FLAGS]) - : ifa->ifa_flags; + obj->ip6_address.n_ifa_flags = tb[IFA_FLAGS] + ? nla_get_u32 (tb[IFA_FLAGS]) + : ifa->ifa_flags; } if (is_v4) { @@ -2329,8 +2353,8 @@ static gboolean _support_kernel_extended_ifa_flags_get (void) { if (_support_kernel_extended_ifa_flags_still_undecided ()) { - _LOG2W ("support: kernel-extended-ifa-flags: unable to detect kernel support for handling IPv6 temporary addresses. Assume none"); - _support_kernel_extended_ifa_flags = 0; + _LOG2W ("support: kernel-extended-ifa-flags: unable to detect kernel support for handling IPv6 temporary addresses. Assume support"); + _support_kernel_extended_ifa_flags = 1; } return _support_kernel_extended_ifa_flags; } @@ -2427,8 +2451,11 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *va static gboolean sysctl_set (NMPlatform *platform, const char *path, const char *value) { - int fd, len, nwrote, tries; + int fd, tries; + gssize nwrote; + gsize len; char *actual; + gs_free char *actual_free = NULL; g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); @@ -2458,10 +2485,16 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) * sysctl support partial writes so the LF must be added to the string we're * about to write. */ - actual = g_strdup_printf ("%s\n", value); + len = strlen (value) + 1; + if (len > 512) + actual = actual_free = g_malloc (len + 1); + else + actual = g_alloca (len + 1); + memcpy (actual, value, len - 1); + actual[len - 1] = '\n'; + actual[len] = '\0'; /* Try to write the entire value three times if a partial write occurs */ - len = strlen (actual); for (tries = 0, nwrote = 0; tries < 3 && nwrote != len; tries++) { nwrote = write (fd, actual, len); if (nwrote == -1) { @@ -2480,15 +2513,14 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) path, value); } - g_free (actual); close (fd); return (nwrote == len); } static GSList *sysctl_clear_cache_list; -void -_nm_linux_platform_sysctl_clear_cache (void) +static void +_nm_logging_clear_platform_logging_cache_impl (void) { while (sysctl_clear_cache_list) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (sysctl_clear_cache_list->data); @@ -2508,6 +2540,7 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *co const char *prev_value = NULL; if (!priv->sysctl_get_prev_values) { + _nm_logging_clear_platform_logging_cache = _nm_logging_clear_platform_logging_cache_impl; sysctl_clear_cache_list = g_slist_prepend (sysctl_clear_cache_list, platform); priv->sysctl_get_prev_values = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } else @@ -2798,13 +2831,23 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, static void delayed_action_wait_for_nl_response_complete_all (NMPlatform *platform, - WaitForNlResponseResult result) + WaitForNlResponseResult fallback_result) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); if (NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) { - while (priv->delayed_action.list_wait_for_nl_response->len > 0) - delayed_action_wait_for_nl_response_complete (platform, priv->delayed_action.list_wait_for_nl_response->len - 1, result); + while (priv->delayed_action.list_wait_for_nl_response->len > 0) { + const DelayedActionWaitForNlResponseData *data; + guint idx = priv->delayed_action.list_wait_for_nl_response->len - 1; + WaitForNlResponseResult r; + + data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, idx); + + /* prefer the result that we already have. */ + r = data->seq_result ? : fallback_result; + + delayed_action_wait_for_nl_response_complete (platform, idx, r); + } } nm_assert (!NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)); nm_assert (priv->delayed_action.list_wait_for_nl_response->len == 0); @@ -3190,9 +3233,9 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP if ( ops_type == NMP_CACHE_OPS_UPDATED && old && new /* <-- nonsensical, make coverity happy */ && old->_link.netlink.is_in_netlink - && NM_FLAGS_HAS (old->link.flags, IFF_LOWER_UP) + && NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP) && new->_link.netlink.is_in_netlink - && !NM_FLAGS_HAS (new->link.flags, IFF_LOWER_UP)) { + && !NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP)) { delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ROUTES | DELAYED_ACTION_TYPE_REFRESH_ALL_IP6_ROUTES, @@ -3235,6 +3278,19 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP DELAYED_ACTION_TYPE_REFRESH_LINK, GINT_TO_POINTER (new->link.ifindex)); } + if ( new->link.type == NM_LINK_TYPE_ETHERNET + && new->link.addr.len == 0) { + /* Due to a kernel bug, we sometimes receive spurious NEWLINK + * messages after a wifi interface has disappeared. Since the + * link is not present anymore we can't determine its type and + * thus it will show up as a Ethernet one, with no address + * specified. Request the link again to check if it really + * exists. https://bugzilla.redhat.com/show_bug.cgi?id=1302037 + */ + delayed_action_schedule (platform, + DELAYED_ACTION_TYPE_REFRESH_LINK, + GINT_TO_POINTER (new->link.ifindex)); + } } { /* on enslave/release, we also refresh the master. */ @@ -3243,8 +3299,8 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP changed_master = (new && new->_link.netlink.is_in_netlink && new->link.master > 0 ? new->link.master : 0) != (old && old->_link.netlink.is_in_netlink && old->link.master > 0 ? old->link.master : 0); - changed_connected = (new && new->_link.netlink.is_in_netlink ? NM_FLAGS_HAS (new->link.flags, IFF_LOWER_UP) : 2) - != (old && old->_link.netlink.is_in_netlink ? NM_FLAGS_HAS (old->link.flags, IFF_LOWER_UP) : 2); + changed_connected = (new && new->_link.netlink.is_in_netlink ? NM_FLAGS_HAS (new->link.n_ifi_flags, IFF_LOWER_UP) : 2) + != (old && old->_link.netlink.is_in_netlink ? NM_FLAGS_HAS (old->link.n_ifi_flags, IFF_LOWER_UP) : 2); if (changed_master || changed_connected) { ifindex1 = (old && old->_link.netlink.is_in_netlink && old->link.master > 0) ? old->link.master : 0; @@ -3455,7 +3511,7 @@ event_seq_check (NMPlatform *platform, struct nl_msg *msg, WaitForNlResponseResu } static void -event_valid_msg (NMPlatform *platform, struct nl_msg *msg) +event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_events) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); nm_auto_nmpobj NMPObject *obj = NULL; @@ -3471,6 +3527,9 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg) if (_support_kernel_extended_ifa_flags_still_undecided () && msghdr->nlmsg_type == RTM_NEWADDR) _support_kernel_extended_ifa_flags_detect (msg); + if (!handle_events) + return; + if (NM_IN_SET (msghdr->nlmsg_type, RTM_DELLINK, RTM_DELADDR, RTM_DELROUTE)) { /* The event notifies about a deleted object. We don't need to initialize all * fields of the object. */ @@ -4684,7 +4743,6 @@ link_vlan_change (NMPlatform *platform, NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const NMPObject *obj_cache; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - unsigned flags; const NMPObjectLnkVlan *lnk; guint new_n_ingress_map = 0; guint new_n_egress_map = 0; @@ -4702,7 +4760,6 @@ link_vlan_change (NMPlatform *platform, } lnk = obj_cache->_link.netlink.lnk ? &obj_cache->_link.netlink.lnk->_lnk_vlan : NULL; - flags = obj_cache->link.flags; flags_set &= flags_mask; @@ -4821,6 +4878,7 @@ tun_add (NMPlatform *platform, const char *name, gboolean tap, if (out_link) *out_link = obj ? &obj->link : NULL; + close (fd); return !!obj; } @@ -5139,7 +5197,7 @@ ip4_address_add (NMPlatform *platform, plen, &peer_addr, 0, - ip4_address_is_link_local (addr) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE, + nmp_utils_ip4_address_is_link_local (addr) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE, lifetime, preferred, label); @@ -5156,7 +5214,7 @@ ip6_address_add (NMPlatform *platform, struct in6_addr peer_addr, guint32 lifetime, guint32 preferred, - guint flags) + guint32 flags) { NMPObject obj_id; nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5492,8 +5550,7 @@ event_handler_recvmsgs (NMPlatform *platform, gboolean handle_events) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); struct nl_sock *sk = priv->nlh; - int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0; - unsigned char *buf = NULL; + int n, err = 0, multipart = 0, interrupted = 0; struct nlmsghdr *hdr; WaitForNlResponseResult seq_result; @@ -5503,34 +5560,44 @@ event_handler_recvmsgs (NMPlatform *platform, gboolean handle_events) initialize the variable. Thomas Graf. */ struct sockaddr_nl nla = {0}; - struct nl_msg *msg = NULL; - struct ucred *creds = NULL; + nm_auto_free struct ucred *creds = NULL; + nm_auto_free unsigned char *buf = NULL; continue_reading: + g_clear_pointer (&buf, free); + g_clear_pointer (&creds, free); errno = 0; n = nl_recv (sk, &nla, &buf, &creds); - /* Work around a libnl bug fixed in 3.2.22 (375a6294) */ - if (n == 0 && errno == EAGAIN) { - /* EAGAIN is equal to EWOULDBLOCK. If it would not be, we'd have to - * workaround libnl3 mapping EWOULDBLOCK to -NLE_FAILURE. */ - G_STATIC_ASSERT (EAGAIN == EWOULDBLOCK); - n = -NLE_AGAIN; + switch (n) { + case 0: + /* Work around a libnl bug fixed in 3.2.22 (375a6294) */ + if (errno == EAGAIN) { + /* EAGAIN is equal to EWOULDBLOCK. If it would not be, we'd have to + * workaround libnl3 mapping EWOULDBLOCK to -NLE_FAILURE. */ + G_STATIC_ASSERT (EAGAIN == EWOULDBLOCK); + n = -NLE_AGAIN; + } + break; + case -NLE_NOMEM: + if (errno == ENOBUFS) { + /* we are very much interested in a overrun of the receive buffer. + * nl_recv() maps all kinds of errors to NLE_NOMEM, so check also + * for errno explicitly. And if so, hack our own return code to signal + * the overrun. */ + n = -_NLE_NM_NOBUFS; + } + break; } if (n <= 0) return n; - if (!handle_events) { - /* we read until failure or there is nothing to read (EAGAIN). */ - goto continue_reading; - } - hdr = (struct nlmsghdr *) buf; while (nlmsg_ok (hdr, n)) { + nm_auto_nlmsg struct nl_msg *msg = NULL; gboolean abort_parsing = FALSE; - nlmsg_free (msg); msg = nlmsg_convert (hdr); if (!msg) { err = -NLE_NOMEM; @@ -5539,13 +5606,13 @@ continue_reading: nlmsg_set_proto (msg, NETLINK_ROUTE); nlmsg_set_src (msg, &nla); - nrecv++; if (!creds || creds->pid) { if (creds) - _LOGD ("netlink: recvmsg: received non-kernel message (pid %d)", creds->pid); + _LOGT ("netlink: recvmsg: received non-kernel message (pid %d)", creds->pid); else - _LOGD ("netlink: recvmsg: received message without credentials"); + _LOGT ("netlink: recvmsg: received message without credentials"); + err = 0; goto stop; } @@ -5618,42 +5685,35 @@ continue_reading: /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no * effect on this. */ - event_valid_msg (platform, msg); + + event_valid_msg (platform, msg, handle_events); + seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; } event_seq_check (platform, msg, seq_result); - err = 0; - hdr = nlmsg_next (hdr, &n); if (abort_parsing) - goto out; - } + goto stop; - nlmsg_free (msg); - free (buf); - free (creds); - buf = NULL; - msg = NULL; - creds = NULL; + err = 0; + hdr = nlmsg_next (hdr, &n); + } if (multipart) { /* Multipart message not yet complete, continue reading */ goto continue_reading; } stop: - err = 0; + if (!handle_events) { + /* when we don't handle events, we want to drain all messages from the socket + * without handling the messages (but still check for sequence numbers). + * Repeat reading. */ + goto continue_reading; + } out: - nlmsg_free (msg); - free (buf); - free (creds); - if (interrupted) err = -NLE_DUMP_INTR; - - if (!err) - err = nrecv; - return err; } @@ -5687,12 +5747,10 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) case -NLE_DUMP_INTR: _LOGD ("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); break; - case -NLE_NOMEM: + case -_NLE_NM_NOBUFS: _LOGI ("netlink: read: too many netlink events. Need to resynchronize platform cache"); - /* Drain the event queue, we've lost events and are out of sync anyway and we'd - * like to free up some space. We'll read in the status synchronously. */ - delayed_action_wait_for_nl_response_complete_all (platform, WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC); event_handler_recvmsgs (platform, FALSE); + delayed_action_wait_for_nl_response_complete_all (platform, WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC); delayed_action_schedule (platform, DELAYED_ACTION_TYPE_REFRESH_ALL_LINKS | DELAYED_ACTION_TYPE_REFRESH_ALL_IP4_ADDRESSES | @@ -5728,9 +5786,10 @@ after_read: i++; if ( data_next.seq_number == 0 - || data_next.timeout_abs_ns > data->timeout_abs_ns) + || data_next.timeout_abs_ns > data->timeout_abs_ns) { data_next.seq_number = data->seq_number; data_next.timeout_abs_ns = data->timeout_abs_ns; + } } } @@ -5916,14 +5975,8 @@ constructed (GObject *_object) nle = nl_socket_set_nonblocking (priv->nlh); g_assert (!nle); - /* The default buffer size wasn't enough for the testsuites. It might just - * as well happen with NetworkManager itself. For now let's hope 128KB is - * good enough. - * - * FIXME: it's unclear that this is still actually needed. The testsuite - * certainly doesn't fail for me. Maybe it can be removed. - */ - nle = nl_socket_set_buffer_size (priv->nlh, 131072, 0); + /* use 8 MB for receive socket kernel queue. */ + nle = nl_socket_set_buffer_size (priv->nlh, 8*1024*1024, 0); g_assert (!nle); nle = nl_socket_add_memberships (priv->nlh, diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index 81f9c738..a9e2cd82 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -50,6 +50,4 @@ GType nm_linux_platform_get_type (void); void nm_linux_platform_setup (void); -void _nm_linux_platform_sysctl_clear_cache (void); - #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 953ac8c5..0f2656f2 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -18,6 +18,8 @@ * Copyright (C) 2015 Red Hat, Inc. */ +#include "nm-default.h" + #include "nm-platform-utils.h" #include <string.h> @@ -30,10 +32,9 @@ #include <linux/version.h> #include "nm-utils.h" -#include "NetworkManagerUtils.h" -#include "nm-default.h" #include "nm-setting-wired.h" +#include "nm-core-utils.h" /****************************************************************** * ethtool @@ -142,7 +143,8 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, struct ethtool_perm_addr e; guint8 _extra_data[NM_UTILS_HWADDR_LEN_MAX + 1]; } edata; - guint zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; + static const guint8 zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; + static guint8 ones[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; if (!ifname) return FALSE; @@ -161,6 +163,12 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, if (memcmp (edata.e.data, zeros, edata.e.size) == 0) return FALSE; + /* Some drivers return a permanent address of all ones. Reject that too */ + if (G_UNLIKELY (ones[0] != 0xFF)) + memset (ones, 0xFF, sizeof (ones)); + if (memcmp (edata.e.data, ones, edata.e.size) == 0) + return FALSE; + memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; return TRUE; @@ -408,6 +416,15 @@ out: * utils ******************************************************************/ +#define IPV4LL_NETWORK (htonl (0xA9FE0000L)) +#define IPV4LL_NETMASK (htonl (0xFFFF0000L)) + +gboolean +nmp_utils_ip4_address_is_link_local (in_addr_t addr) +{ + return (addr & IPV4LL_NETMASK) == IPV4LL_NETWORK; +} + /** * Takes a pair @timestamp and @duration, and returns the remaining duration based * on the new timestamp @now. @@ -496,13 +513,13 @@ gboolean nmp_utils_device_exists (const char *name) { #define SYS_CLASS_NET "/sys/class/net/" - char sysdir[STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET; + char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET; if ( !name || strlen (name) >= IFNAMSIZ || !nm_utils_is_valid_path_component (name)) g_return_val_if_reached (FALSE); - strcpy (&sysdir[STRLEN (SYS_CLASS_NET)], name); + strcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], name); return g_file_test (sysdir, G_FILE_TEST_EXISTS); } diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index 3769a8e1..a9d29c04 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -21,8 +21,6 @@ #ifndef __NM_PLATFORM_UTILS_H__ #define __NM_PLATFORM_UTILS_H__ -#include "config.h" - #include <gudev/gudev.h> #include "nm-platform.h" @@ -69,4 +67,6 @@ gboolean nmp_utils_lifetime_get (guint32 timestamp, gboolean nmp_utils_device_exists (const char *name); +gboolean nmp_utils_ip4_address_is_link_local (in_addr_t addr); + #endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 3bb44e1a..e3126442 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -18,7 +18,9 @@ * Copyright (C) 2012 Red Hat, Inc. */ -#include "config.h" +#include "nm-default.h" + +#include "nm-platform.h" #include <stdlib.h> #include <errno.h> @@ -32,15 +34,19 @@ #include <linux/if_tun.h> #include <linux/if_tunnel.h> -#include "NetworkManagerUtils.h" #include "nm-utils.h" -#include "nm-platform.h" +#include "nm-core-internal.h" + +#include "nm-core-utils.h" +#include "nm-enum-types.h" #include "nm-platform-utils.h" #include "nmp-object.h" -#include "NetworkManagerUtils.h" -#include "nm-default.h" -#include "nm-enum-types.h" -#include "nm-core-internal.h" + +/*****************************************************************************/ + +const NMIPAddr nm_ip_addr_zero = NMIPAddrInit; + +/*****************************************************************************/ #define ADDRESS_LIFETIME_PADDING 5 @@ -181,39 +187,26 @@ nm_platform_try_get (void) /******************************************************************/ /** - * nm_platform_error_to_string: + * _nm_platform_error_to_string: * @error_code: the error code to stringify. * * Returns: A string representation of the error. * For negative numbers, this function interprets * the code as -errno. + * For invalid (positive) numbers it returns NULL. */ -const char * -nm_platform_error_to_string (NMPlatformError error) -{ - switch (error) { - case NM_PLATFORM_ERROR_SUCCESS: - return "success"; - case NM_PLATFORM_ERROR_BUG: - return "bug"; - case NM_PLATFORM_ERROR_UNSPECIFIED: - return "unspecified"; - case NM_PLATFORM_ERROR_NOT_FOUND: - return "not-found"; - case NM_PLATFORM_ERROR_EXISTS: - return "exists"; - case NM_PLATFORM_ERROR_WRONG_TYPE: - return "wrong-type"; - case NM_PLATFORM_ERROR_NOT_SLAVE: - return "not-slave"; - case NM_PLATFORM_ERROR_NO_FIRMWARE: - return "no-firmware"; - default: - if (error < 0) - return g_strerror (- ((int) error)); - return "unknown"; - } -} +NM_UTILS_LOOKUP_STR_DEFINE (_nm_platform_error_to_string, NMPlatformError, + NM_UTILS_LOOKUP_DEFAULT ( val < 0 ? g_strerror (- ((int) val)) : NULL ), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_SUCCESS, "success"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_BUG, "bug"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_UNSPECIFIED, "unspecified"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NOT_FOUND, "not-found"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_EXISTS, "exists"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_WRONG_TYPE, "wrong-type"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NOT_SLAVE, "not-slave"), + NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NO_FIRMWARE, "no-firmware"), + NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT), +); /******************************************************************/ @@ -811,13 +804,13 @@ nm_platform_link_refresh (NMPlatform *self, int ifindex) return TRUE; } -static guint32 +static guint _link_get_flags (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; pllink = nm_platform_link_get (self, ifindex); - return pllink ? pllink->flags : IFF_NOARP; + return pllink ? pllink->n_ifi_flags : IFF_NOARP; } /** @@ -2147,7 +2140,8 @@ nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_pe gboolean nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname, NMPlatformTunProperties *props) { - char *path, *val; + char path[256]; + char *val; gboolean success = TRUE; _CHECK_SELF (self, klass, FALSE); @@ -2160,11 +2154,9 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname if (!ifname || !nm_utils_iface_valid_name (ifname)) return FALSE; - ifname = ASSERT_VALID_PATH_COMPONENT (ifname); - path = g_strdup_printf ("/sys/class/net/%s/owner", ifname); + nm_sprintf_buf (path, "/sys/class/net/%s/owner", ifname); val = nm_platform_sysctl_get (self, path); - g_free (path); if (val) { props->owner = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) @@ -2173,9 +2165,8 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname } else success = FALSE; - path = g_strdup_printf ("/sys/class/net/%s/group", ifname); + nm_sprintf_buf (path, "/sys/class/net/%s/group", ifname); val = nm_platform_sysctl_get (self, path); - g_free (path); if (val) { props->group = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) @@ -2184,9 +2175,8 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname } else success = FALSE; - path = g_strdup_printf ("/sys/class/net/%s/tun_flags", ifname); + nm_sprintf_buf (path, "/sys/class/net/%s/tun_flags", ifname); val = nm_platform_sysctl_get (self, path); - g_free (path); if (val) { gint64 flags; @@ -2461,7 +2451,7 @@ nm_platform_ip6_address_add (NMPlatform *self, struct in6_addr peer_address, guint32 lifetime, guint32 preferred, - guint flags) + guint32 flags) { _CHECK_SELF (self, klass, FALSE); @@ -2480,7 +2470,7 @@ nm_platform_ip6_address_add (NMPlatform *self, addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */ addr.lifetime = lifetime; addr.preferred = preferred; - addr.flags = flags; + addr.n_ifa_flags = flags; _LOGD ("address: adding or updating IPv6 address: %s", nm_platform_ip6_address_to_string (&addr, NULL, 0)); } @@ -2701,7 +2691,7 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known if (!nm_platform_ip6_address_add (self, ifindex, known_address->address, known_address->plen, known_address->peer_address, - lifetime, preferred, known_address->flags)) + lifetime, preferred, known_address->n_ifa_flags)) return FALSE; } @@ -2978,19 +2968,19 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) return buf; str_flags = g_string_new (NULL); - if (NM_FLAGS_HAS (link->flags, IFF_NOARP)) + if (NM_FLAGS_HAS (link->n_ifi_flags, IFF_NOARP)) g_string_append (str_flags, "NOARP,"); - if (NM_FLAGS_HAS (link->flags, IFF_UP)) + if (NM_FLAGS_HAS (link->n_ifi_flags, IFF_UP)) g_string_append (str_flags, "UP"); else g_string_append (str_flags, "DOWN"); if (link->connected) g_string_append (str_flags, ",LOWER_UP"); - if (link->flags) { + if (link->n_ifi_flags) { char str_flags_buf[64]; - nm_platform_link_flags2str (link->flags, str_flags_buf, sizeof (str_flags_buf)); + nm_platform_link_flags2str (link->n_ifi_flags, str_flags_buf, sizeof (str_flags_buf)); g_string_append_printf (str_flags, ";%s", str_flags_buf); } @@ -3006,21 +2996,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) else parent[0] = 0; - if (link->inet6_addr_gen_mode_inv) { - switch (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv)) { - case 0: - g_snprintf (str_addrmode, sizeof (str_addrmode), " addrgenmode eui64"); - break; - case 1: - g_snprintf (str_addrmode, sizeof (str_addrmode), " addrgenmode none"); - break; - default: - g_snprintf (str_addrmode, sizeof (str_addrmode), " addrgenmode %d", _nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv)); - break; - } - } else - str_addrmode[0] = '\0'; - if (link->addr.len) str_addr = nm_utils_hwaddr_ntoa (link->addr.data, MIN (link->addr.len, sizeof (link->addr.data))); if (link->inet6_token.is_valid) @@ -3036,10 +3011,10 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) " mtu %d" "%s" /* master */ " arp %u" /* arptype */ - "%s%s" /* link->type */ + " %s" /* link->type */ "%s%s" /* kind */ "%s" /* is-in-udev */ - "%s" /* addr-gen-mode */ + "%s%s" /* addr-gen-mode */ "%s%s" /* addr */ "%s%s" /* inet6_token */ "%s%s" /* driver */ @@ -3050,12 +3025,12 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) str_flags->str, link->mtu, master, link->arptype, - str_link_type ? " " : "", str_if_set (str_link_type, "???"), - link->kind ? (g_strcmp0 (str_link_type, link->kind) ? "/" : "*") : "", + link->kind ? (g_strcmp0 (str_link_type, link->kind) ? "/" : "*") : "?", link->kind && g_strcmp0 (str_link_type, link->kind) ? link->kind : "", link->initialized ? " init" : " not-init", - str_addrmode, + link->inet6_addr_gen_mode_inv ? " addrgenmode " : "", + link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "", str_addr ? " addr " : "", str_addr ? str_addr : "", str_inet6_token ? " inet6token " : "", @@ -3444,6 +3419,7 @@ NM_UTILS_ENUM2STR_DEFINE (nm_platform_link_inet6_addrgenmode2str, guint8, NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_NONE, "none"), NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_EUI64, "eui64"), NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY, "stable-privacy"), + NM_UTILS_ENUM2STR (NM_IN6_ADDR_GEN_MODE_RANDOM, "random"), ); NM_UTILS_FLAGS2STR_DEFINE (nm_platform_addr_flags2str, unsigned, @@ -3503,11 +3479,11 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu _to_string_dev (NULL, address->ifindex, str_dev, sizeof (str_dev)); - nm_platform_addr_flags2str (address->flags, &s_flags[STRLEN (S_FLAGS_PREFIX)], sizeof (s_flags) - STRLEN (S_FLAGS_PREFIX)); - if (s_flags[STRLEN (S_FLAGS_PREFIX)] == '\0') + nm_platform_addr_flags2str (address->n_ifa_flags, &s_flags[NM_STRLEN (S_FLAGS_PREFIX)], sizeof (s_flags) - NM_STRLEN (S_FLAGS_PREFIX)); + if (s_flags[NM_STRLEN (S_FLAGS_PREFIX)] == '\0') s_flags[0] = '\0'; else - memcpy (s_flags, S_FLAGS_PREFIX, STRLEN (S_FLAGS_PREFIX)); + memcpy (s_flags, S_FLAGS_PREFIX, NM_STRLEN (S_FLAGS_PREFIX)); str_lft_p = _lifetime_to_string (address->timestamp, address->lifetime ? address->lifetime : NM_PLATFORM_LIFETIME_PERMANENT, @@ -3708,7 +3684,7 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) _CMP_FIELD_STR (a, b, name); _CMP_FIELD (a, b, master); _CMP_FIELD (a, b, parent); - _CMP_FIELD (a, b, flags); + _CMP_FIELD (a, b, n_ifi_flags); _CMP_FIELD (a, b, connected); _CMP_FIELD (a, b, mtu); _CMP_FIELD_BOOL (a, b, initialized); @@ -3871,7 +3847,7 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); - _CMP_FIELD (a, b, flags); + _CMP_FIELD (a, b, n_ifa_flags); return 0; } diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 8ac129a0..b94c440a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -27,11 +27,11 @@ #include <linux/if_link.h> #include "nm-dbus-interface.h" -#include "nm-default.h" -#include "NetworkManagerUtils.h" -#include "nm-setting-vlan.h" #include "nm-core-types-internal.h" +#include "nm-core-utils.h" +#include "nm-setting-vlan.h" + #define NM_TYPE_PLATFORM (nm_platform_get_type ()) #define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform)) #define NM_PLATFORM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_PLATFORM, NMPlatformClass)) @@ -61,6 +61,7 @@ typedef struct _NMPlatform NMPlatform; #define NM_IN6_ADDR_GEN_MODE_EUI64 0 /* IN6_ADDR_GEN_MODE_EUI64 */ #define NM_IN6_ADDR_GEN_MODE_NONE 1 /* IN6_ADDR_GEN_MODE_NONE */ #define NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2 /* IN6_ADDR_GEN_MODE_STABLE_PRIVACY */ +#define NM_IN6_ADDR_GEN_MODE_RANDOM 3 /* IN6_ADDR_GEN_MODE_RANDOM */ #define NM_IFF_MULTI_QUEUE 0x0100 /* IFF_MULTI_QUEUE */ @@ -118,7 +119,6 @@ struct _NMPlatformLink { /* NMPlatform initializes this field with a static string. */ const char *driver; - gboolean initialized; int master; /* rtnl_link_get_link(), IFLA_LINK. @@ -126,6 +126,11 @@ struct _NMPlatformLink { * this field be set to (negative) NM_PLATFORM_LINK_OTHER_NETNS. */ int parent; + /* IFF_* flags. Note that the flags in 'struct ifinfomsg' are declared as 'unsigned'. */ + guint n_ifi_flags; + + guint mtu; + /* rtnl_link_get_arptype(), ifinfomsg.ifi_type. */ guint32 arptype; @@ -146,15 +151,11 @@ struct _NMPlatformLink { * initialized with memset(0) has and unset value.*/ guint8 inet6_addr_gen_mode_inv; - /* IFF_* flags as u32. Note that ifi_flags in 'struct ifinfomsg' is declared as 'unsigned', - * but libnl stores the flag internally as u32. */ - guint32 flags; - - /* @connected is mostly identical to (@flags & IFF_UP). Except for bridge/bond masters, + /* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters, * where we coerce the link as disconnect if it has no slaves. */ - gboolean connected; + bool connected:1; - guint mtu; + bool initialized:1; }; typedef enum { /*< skip >*/ @@ -268,7 +269,7 @@ struct _NMPlatformIP6Address { __NMPlatformIPAddress_COMMON; struct in6_addr address; struct in6_addr peer_address; - guint flags; /* ifa_flags from <linux/if_addr.h>, field type "unsigned int" is as used in rtnl_addr_get_flags. */ + guint32 n_ifa_flags; /* ifa_flags from <linux/if_addr.h>, field type "unsigned int" is as used in rtnl_addr_get_flags. */ }; typedef union { @@ -362,16 +363,16 @@ extern const NMPlatformVTableRoute nm_platform_vtable_route_v4; extern const NMPlatformVTableRoute nm_platform_vtable_route_v6; typedef struct { + in_addr_t local; + in_addr_t remote; int parent_ifindex; guint16 input_flags; guint16 output_flags; guint32 input_key; guint32 output_key; - in_addr_t local; - in_addr_t remote; guint8 ttl; guint8 tos; - gboolean path_mtu_discovery; + bool path_mtu_discovery:1; } NMPlatformLnkGre; typedef struct { @@ -380,42 +381,42 @@ typedef struct { } NMPlatformLnkInfiniband; typedef struct { - int parent_ifindex; struct in6_addr local; struct in6_addr remote; + int parent_ifindex; guint8 ttl; guint8 tclass; guint8 encap_limit; - guint flow_label; guint8 proto; + guint flow_label; } NMPlatformLnkIp6Tnl; typedef struct { - int parent_ifindex; in_addr_t local; in_addr_t remote; + int parent_ifindex; guint8 ttl; guint8 tos; - gboolean path_mtu_discovery; + bool path_mtu_discovery:1; } NMPlatformLnkIpIp; typedef struct { guint mode; - gboolean no_promisc; - gboolean tap; + bool no_promisc:1; + bool tap:1; } NMPlatformLnkMacvlan; typedef NMPlatformLnkMacvlan NMPlatformLnkMacvtap; typedef struct { - int parent_ifindex; in_addr_t local; in_addr_t remote; + int parent_ifindex; guint8 ttl; guint8 tos; - gboolean path_mtu_discovery; - guint16 flags; guint8 proto; + bool path_mtu_discovery:1; + guint16 flags; } NMPlatformLnkSit; typedef struct { @@ -425,33 +426,33 @@ typedef struct { } NMPlatformLnkVlan; typedef struct { - int parent_ifindex; - guint32 id; - in_addr_t group; - in_addr_t local; struct in6_addr group6; struct in6_addr local6; - guint8 tos; - guint8 ttl; - gboolean learning; + in_addr_t group; + in_addr_t local; + int parent_ifindex; + guint32 id; guint32 ageing; guint32 limit; guint16 dst_port; guint16 src_port_min; guint16 src_port_max; - gboolean proxy; - gboolean rsc; - gboolean l2miss; - gboolean l3miss; + guint8 tos; + guint8 ttl; + bool learning:1; + bool proxy:1; + bool rsc:1; + bool l2miss:1; + bool l3miss:1; } NMPlatformLnkVxlan; typedef struct { gint64 owner; gint64 group; const char *mode; - gboolean no_pi; - gboolean vnet_hdr; - gboolean multi_queue; + bool no_pi:1; + bool vnet_hdr:1; + bool multi_queue:1; } NMPlatformTunProperties; /******************************************************************/ @@ -593,7 +594,7 @@ typedef struct { struct in6_addr peer_address, guint32 lifetime, guint32 preferred_lft, - guint flags); + guint32 flags); gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen); const NMPlatformIP4Address *(*ip4_address_get) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); @@ -666,7 +667,8 @@ _nm_platform_uint8_inv (guint8 scope) const char *nm_link_type_to_string (NMLinkType link_type); -const char *nm_platform_error_to_string (NMPlatformError error); +const char *_nm_platform_error_to_string (NMPlatformError error); +#define nm_platform_error_to_string(error) NM_UTILS_LOOKUP_STR (_nm_platform_error_to_string, error) gboolean nm_platform_sysctl_set (NMPlatform *self, const char *path, const char *value); char *nm_platform_sysctl_get (NMPlatform *self, const char *path); @@ -859,7 +861,7 @@ gboolean nm_platform_ip6_address_add (NMPlatform *self, struct in6_addr peer_address, guint32 lifetime, guint32 preferred_lft, - guint flags); + guint32 flags); gboolean nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, int plen); gboolean nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known_addresses, GPtrArray **out_added_addresses); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 892fd9dd..b7b04490 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -18,16 +18,17 @@ * Copyright (C) 2015 Red Hat, Inc. */ -#include "config.h" +#include "nm-default.h" + +#include "nmp-object.h" #include <unistd.h> -#include "nm-default.h" -#include "nmp-object.h" -#include "nm-platform-utils.h" -#include "NetworkManagerUtils.h" #include "nm-utils.h" +#include "nm-core-utils.h" +#include "nm-platform-utils.h" + /*********************************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM @@ -1256,7 +1257,7 @@ nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *m /* if native IFF_LOWER_UP is down, link.connected must also be down * regardless of the slaves. */ - if (!NM_FLAGS_HAS (master->link.flags, IFF_LOWER_UP)) + if (!NM_FLAGS_HAS (master->link.n_ifi_flags, IFF_LOWER_UP)) return !!master->link.connected; if (potential_slave && NMP_OBJECT_GET_TYPE (potential_slave) != NMP_OBJECT_TYPE_LINK) diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index ab1cc2fe..7758798f 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -21,15 +21,11 @@ #ifndef __NMP_OBJECT_H__ #define __NMP_OBJECT_H__ -#include "config.h" - -#include "nm-platform.h" -#include "nm-multi-index.h" -#include "nm-macros-internal.h" - #include <netlink/netlink.h> #include <gudev/gudev.h> +#include "nm-platform.h" +#include "nm-multi-index.h" typedef enum { /*< skip >*/ NMP_OBJECT_TO_STRING_ID, diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index 5cc3114c..3af34be4 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -1,9 +1,28 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2015 Red Hat, Inc. + */ + +#include "nm-default.h" #include <stdlib.h> #include <syslog.h> -#include "nm-default.h" #include "nm-linux-platform.h" #include "nm-test-utils.h" diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 566bb479..3b52a7be 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -1,4 +1,24 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2015 Red Hat, Inc. + */ + +#include "nm-default.h" #include "test-common.h" @@ -255,7 +275,8 @@ test_ip4_address_peer (void) /* Add/delete notification */ nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, NULL); accept_signal (address_added); - g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer))); + a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer); + g_assert (a); g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)); nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred); @@ -263,7 +284,8 @@ test_ip4_address_peer (void) nmtstp_ip4_address_add (EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, NULL); accept_signal (address_added); g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); - g_assert ((a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2))); + a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2); + g_assert (a); nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred); diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 9e624a02..6ad24478 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -1,4 +1,24 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2016 Red Hat, Inc. + */ + +#include "nm-default.h" #include "test-common.h" @@ -25,7 +45,7 @@ test_cleanup_internal (void) int preferred = NM_PLATFORM_LIFETIME_PERMANENT; int metric = 20; int mss = 1000; - guint flags = 0; + guint32 flags = 0; inet_pton (AF_INET, "192.0.2.1", &addr4); inet_pton (AF_INET, "192.0.3.0", &network4); diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 09a57f87..268a5c92 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1,4 +1,24 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2016 Red Hat, Inc. + */ + +#include "nm-default.h" #include <sys/mount.h> #include <sched.h> @@ -39,7 +59,7 @@ add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCall data->ifindex = ifindex; data->ifname = ifname; - g_assert (data->handler_id >= 0); + g_assert (data->handler_id > 0); return data; } @@ -544,7 +564,7 @@ _ip_address_add (gboolean external_command, guint32 lifetime, guint32 preferred, const char *label, - guint flags) + guint32 flags) { gint64 end_time; @@ -1008,7 +1028,7 @@ nmtstp_ip6_address_add (gboolean external_command, struct in6_addr peer_address, guint32 lifetime, guint32 preferred, - guint flags) + guint32 flags) { _ip_address_add (external_command, FALSE, @@ -1262,7 +1282,7 @@ nmtstp_link_set_updown (gboolean external_command, plink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); g_assert (plink); - if (NM_FLAGS_HAS (plink->flags, IFF_UP) == !!up) + if (NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP) == !!up) break; /* for internal command, we expect not to reach this line.*/ diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 8b496262..3fa5ad50 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1,4 +1,24 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2016 Red Hat, Inc. + */ + +#include "nm-default.h" #include <sched.h> @@ -290,9 +310,17 @@ test_slave (int master, int type, SignalData *master_changed) ensure_no_signal (link_removed); g_assert (nm_platform_link_release (NM_PLATFORM_GET, master, ifindex)); g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, 0); - accept_signals (link_added, 0, 1); - accept_signals (link_changed, 1, 3); - accept_signals (link_removed, 0, 1); + if (link_changed->received_count > 0) { + accept_signals (link_added, 0, 1); + accept_signals (link_changed, 1, 3); + accept_signals (link_removed, 0, 1); + } else { + /* Due to https://bugzilla.redhat.com/show_bug.cgi?id=1285719 , kernel might send a + * wrong RTM_DELLINK message so that we instead see an removed+added signal. */ + accept_signal (link_added); + ensure_no_signal (link_changed); + accept_signal (link_removed); + } accept_signals (master_changed, 1, 2); ensure_no_signal (master_changed); diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c index eba2383b..3b44abb8 100644 --- a/src/platform/tests/test-nmp-object.c +++ b/src/platform/tests/test-nmp-object.c @@ -18,10 +18,10 @@ * Copyright (C) 2015 Red Hat, Inc. */ -#include "nmp-object.h" - #include "nm-default.h" +#include "nmp-object.h" + #include "nm-test-utils.h" struct { diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 60a0c15c..f5fa024b 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -1,10 +1,31 @@ -#include "config.h" +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager audit support + * + * 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 2016 Red Hat, Inc. + */ + +#include "nm-default.h" #include <linux/rtnetlink.h> +#include "nm-core-utils.h" #include "test-common.h" + #include "nm-test-utils.h" -#include "NetworkManagerUtils.h" #define DEVICE_NAME "nm-test-device" diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index e05104f3..79f217a8 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -20,7 +20,7 @@ * Copyright (C) 2011 Intel Corporation. All rights reserved. */ -#include "config.h" +#include "nm-default.h" #include <errno.h> #include <string.h> @@ -32,7 +32,6 @@ #include <netlink/msg.h> #include <linux/nl80211.h> -#include "nm-default.h" #include "wifi-utils-private.h" #include "wifi-utils-nl80211.h" #include "nm-platform.h" diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index 96bcf53d..029601e4 100644 --- a/src/platform/wifi/wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -19,7 +19,7 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include "config.h" +#include "nm-default.h" #include <errno.h> #include <string.h> @@ -28,8 +28,6 @@ #include <unistd.h> #include <math.h> - -#include "nm-default.h" #include "wifi-utils-private.h" #include "wifi-utils-wext.h" #include "nm-utils.h" @@ -315,7 +313,7 @@ wext_qual_to_percent (const struct iw_quality *qual, noise = qual->noise - 0x100; else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) noise = max_qual->noise - 0x100; - noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM - 1); /* A sort of signal-to-noise ratio calculation */ level_percent = (int) (100 - 70 * (((double)max_level - (double)level) / diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index 5f2f61b0..38e5a054 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -19,13 +19,12 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#include "config.h" +#include "nm-default.h" #include <sys/stat.h> #include <stdio.h> #include <string.h> -#include "nm-default.h" #include "wifi-utils.h" #include "wifi-utils-private.h" #include "wifi-utils-nl80211.h" |