diff options
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/Makefile.in | 14 | ||||
| -rw-r--r-- | src/platform/nm-fake-platform.c | 27 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 316 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.h | 6 | ||||
| -rw-r--r-- | src/platform/nm-platform-utils.c | 134 | ||||
| -rw-r--r-- | src/platform/nm-platform-utils.h | 7 | ||||
| -rw-r--r-- | src/platform/nm-platform.c | 199 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 49 | ||||
| -rw-r--r-- | src/platform/nmp-object.c | 14 | ||||
| -rw-r--r-- | src/platform/nmp-object.h | 6 | ||||
| -rw-r--r-- | src/platform/tests/Makefile.am | 6 | ||||
| -rw-r--r-- | src/platform/tests/Makefile.in | 25 | ||||
| -rw-r--r-- | src/platform/tests/monitor.c | 2 | ||||
| -rw-r--r-- | src/platform/tests/test-common.h | 4 | ||||
| -rw-r--r-- | src/platform/tests/test-general.c | 2 | ||||
| -rw-r--r-- | src/platform/tests/test-link.c | 73 | ||||
| -rw-r--r-- | src/platform/tests/test-nmp-object.c | 2 | ||||
| -rw-r--r-- | src/platform/tests/test-route.c | 16 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-private.h | 2 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.c | 21 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.h | 3 |
21 files changed, 590 insertions, 338 deletions
diff --git a/src/platform/Makefile.in b/src/platform/Makefile.in index a528da66..bf094348 100644 --- a/src/platform/Makefile.in +++ b/src/platform/Makefile.in @@ -89,8 +89,9 @@ build_triplet = @build@ host_triplet = @host@ subdir = src/platform ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -225,6 +226,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -281,13 +283,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -299,6 +302,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -359,6 +364,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -394,6 +401,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 7b545076..8a4f69b6 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -31,9 +31,10 @@ #include "nm-utils.h" #include "nm-core-utils.h" +#include "nm-platform-utils.h" #include "nmp-object.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /*********************************************************************************************/ @@ -505,7 +506,7 @@ link_set_noarp (NMPlatform *platform, int ifindex) return TRUE; } -static gboolean +static NMPlatformError link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t len) { NMFakePlatformLink *device = link_get (platform, ifindex); @@ -514,7 +515,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t || len == 0 || len > NM_UTILS_HWADDR_LEN_MAX || !addr) - g_return_val_if_reached (FALSE); + g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); if ( device->link.addr.len != len || ( len > 0 @@ -524,7 +525,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t link_changed (platform, link_get (platform, ifindex), TRUE); } - return TRUE; + return NM_PLATFORM_ERROR_SUCCESS; } static gboolean @@ -709,12 +710,13 @@ static gboolean infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) { NMFakePlatformLink *device, *parent_device; - gs_free char *name = NULL; + char name[IFNAMSIZ]; parent_device = link_get (platform, parent); g_return_val_if_fail (parent_device != NULL, FALSE); - name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); + nm_utils_new_infiniband_name (name, parent_device->link.name, p_key); + if (!link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0, out_link)) return FALSE; @@ -726,7 +728,6 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMP device->lnk->lnk_infiniband.p_key = p_key; device->lnk->lnk_infiniband.mode = "datagram"; device->link.parent = parent; - return TRUE; } @@ -739,7 +740,7 @@ infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) parent_device = link_get (platform, parent); g_return_val_if_fail (parent_device != NULL, FALSE); - name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key); + nm_utils_new_infiniband_name (name, parent_device->link.name, p_key); return link_delete (platform, nm_platform_link_get_ifindex (platform, name)); } @@ -911,7 +912,7 @@ ip4_address_add (NMPlatform *platform, int i; memset (&address, 0, sizeof (address)); - address.source = NM_IP_CONFIG_SOURCE_KERNEL; + address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = peer_addr; @@ -962,7 +963,7 @@ ip6_address_add (NMPlatform *platform, int i; memset (&address, 0, sizeof (address)); - address.source = NM_IP_CONFIG_SOURCE_KERNEL; + address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; address.ifindex = ifindex; address.address = addr; address.peer_address = (IN6_IS_ADDR_UNSPECIFIED (&peer_addr) || IN6_ARE_ADDR_EQUAL (&addr, &peer_addr)) ? in6addr_any : peer_addr; @@ -1207,9 +1208,8 @@ ip4_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, scope = gateway == 0 ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE; memset (&route, 0, sizeof (route)); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; - route.source = source; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source); route.network = nm_utils_ip4_address_clear_host_address (network, plen); route.plen = plen; route.gateway = gateway; @@ -1273,9 +1273,8 @@ ip6_route_add (NMPlatform *platform, int ifindex, NMIPConfigSource source, metric = nm_utils_ip6_route_metric_normalize (metric); memset (&route, 0, sizeof (route)); - route.source = NM_IP_CONFIG_SOURCE_KERNEL; route.ifindex = ifindex; - route.source = source; + route.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (source); nm_utils_ip6_address_clear_host_address (&route.network, &network, plen); route.plen = plen; route.gateway = gateway; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f6f7be80..98c4e461 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -176,6 +176,11 @@ * Forward declarations and enums ******************************************************************/ +typedef enum { + INFINIBAND_ACTION_CREATE_CHILD, + INFINIBAND_ACTION_DELETE_CHILD, +} InfinibandAction; + enum { DELAYED_ACTION_IDX_REFRESH_ALL_LINKS, DELAYED_ACTION_IDX_REFRESH_ALL_IP4_ADDRESSES, @@ -303,23 +308,6 @@ _support_user_ipv6ll_detect (struct nlattr **tb) * Various utilities ******************************************************************/ -static void -clear_host_address (int family, const void *network, guint8 plen, void *dst) -{ - g_return_if_fail (network); - - switch (family) { - case AF_INET: - *((in_addr_t *) dst) = nm_utils_ip4_address_clear_host_address (*((in_addr_t *) network), plen); - break; - case AF_INET6: - nm_utils_ip6_address_clear_host_address ((struct in6_addr *) dst, (const struct in6_addr *) network, plen); - break; - default: - g_assert_not_reached (); - } -} - static int _vlan_qos_mapping_cmp_from (gconstpointer a, gconstpointer b, gpointer user_data) { @@ -372,7 +360,7 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_INFINIBAND, "infiniband", NULL, NULL }, { NM_LINK_TYPE_OLPC_MESH, "olpc-mesh", NULL, NULL }, { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" }, - { NM_LINK_TYPE_WWAN_ETHERNET, "wwan", NULL, "wwan" }, + { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" }, { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" }, { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL }, @@ -588,12 +576,17 @@ _lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_fro #define DEVTYPE_PREFIX "DEVTYPE=" static char * -_linktype_read_devtype (const char *sysfs_path) +_linktype_read_devtype (const char *ifname) { - gs_free char *uevent = g_strdup_printf ("%s/uevent", sysfs_path); + char uevent[NM_STRLEN ("/sys/class/net/123456789012345/uevent\0") + 100 /*safety*/]; char *contents = NULL; char *cont, *end; + nm_sprintf_buf (uevent, + "/sys/class/net/%s/uevent", + NM_ASSERT_VALID_PATH_COMPONENT (ifname)); + nm_assert (strlen (uevent) < sizeof (uevent) - 1); + if (!g_file_get_contents (uevent, &contents, NULL, NULL)) return NULL; for (cont = contents; cont; cont = end) { @@ -690,9 +683,8 @@ _linktype_get_type (NMPlatform *platform, return NM_LINK_TYPE_IP6TNL; if (ifname) { + char anycast_mask[NM_STRLEN ("/sys/class/net/123456789012345/anycast_mask\0") + 100 /*safety*/]; gs_free char *driver = NULL; - gs_free char *sysfs_path = NULL; - gs_free char *anycast_mask = NULL; gs_free char *devtype = NULL; /* Fallback OVS detection for kernel <= 3.16 */ @@ -709,12 +701,15 @@ _linktype_get_type (NMPlatform *platform, } } - sysfs_path = g_strdup_printf ("/sys/class/net/%s", ifname); - anycast_mask = g_strdup_printf ("%s/anycast_mask", sysfs_path); + nm_sprintf_buf (anycast_mask, + "/sys/class/net/%s/anycast_mask", + NM_ASSERT_VALID_PATH_COMPONENT (ifname)); + nm_assert (strlen (anycast_mask) < sizeof (anycast_mask) - 1); + if (g_file_test (anycast_mask, G_FILE_TEST_EXISTS)) return NM_LINK_TYPE_OLPC_MESH; - devtype = _linktype_read_devtype (sysfs_path); + devtype = _linktype_read_devtype (ifname); for (i = 0; devtype && i < G_N_ELEMENTS (linktypes); i++) { if (g_strcmp0 (devtype, linktypes[i].devtype) == 0) { if (linktypes[i].nm_type == NM_LINK_TYPE_BNEP) { @@ -729,10 +724,19 @@ _linktype_get_type (NMPlatform *platform, } /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ - if (wifi_utils_is_wifi (ifname, sysfs_path)) + if (wifi_utils_is_wifi (ifname)) return NM_LINK_TYPE_WIFI; if (arptype == ARPHRD_ETHER) { + /* Misc non-upstream WWAN drivers. rmnet is Qualcomm's proprietary + * modem interface, ccmni is MediaTek's. FIXME: these drivers should + * really set devtype=WWAN. + */ + if (g_str_has_prefix (ifname, "rmnet") || + g_str_has_prefix (ifname, "rev_rmnet") || + g_str_has_prefix (ifname, "ccmni")) + return NM_LINK_TYPE_WWAN_NET; + /* 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 @@ -803,9 +807,10 @@ _nl_nlmsg_type_to_str (guint16 type, char *buf, gsize len) static gboolean _parse_af_inet6 (NMPlatform *platform, struct nlattr *attr, - NMUtilsIPv6IfaceId *out_iid, - guint8 *out_iid_is_valid, - guint8 *out_addr_gen_mode_inv) + NMUtilsIPv6IfaceId *out_token, + gboolean *out_token_valid, + guint8 *out_addr_gen_mode_inv, + gboolean *out_addr_gen_mode_valid) { static struct nla_policy policy[IFLA_INET6_MAX+1] = { [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, @@ -819,7 +824,8 @@ _parse_af_inet6 (NMPlatform *platform, struct nlattr *tb[IFLA_INET6_MAX+1]; int err; struct in6_addr i6_token; - gboolean iid_is_valid = FALSE; + gboolean token_valid = FALSE; + gboolean addr_gen_mode_valid = FALSE; guint8 i6_addr_gen_mode_inv = 0; gboolean success = FALSE; @@ -836,8 +842,7 @@ _parse_af_inet6 (NMPlatform *platform, 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)); - if (!IN6_IS_ADDR_UNSPECIFIED (&i6_token)) - iid_is_valid = TRUE; + token_valid = TRUE; } /* Hack to detect support addrgenmode of the kernel. We only parse @@ -852,21 +857,18 @@ _parse_af_inet6 (NMPlatform *platform, * to signal "unset". */ goto errout; } + addr_gen_mode_valid = TRUE; } success = TRUE; - if (iid_is_valid) { - out_iid->id_u8[7] = i6_token.s6_addr[15]; - out_iid->id_u8[6] = i6_token.s6_addr[14]; - out_iid->id_u8[5] = i6_token.s6_addr[13]; - out_iid->id_u8[4] = i6_token.s6_addr[12]; - out_iid->id_u8[3] = i6_token.s6_addr[11]; - out_iid->id_u8[2] = i6_token.s6_addr[10]; - out_iid->id_u8[1] = i6_token.s6_addr[9]; - out_iid->id_u8[0] = i6_token.s6_addr[8]; - *out_iid_is_valid = TRUE; - } - *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; + if (token_valid) { + *out_token_valid = token_valid; + nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token); + } + if (addr_gen_mode_valid) { + *out_addr_gen_mode_valid = addr_gen_mode_valid; + *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; + } errout: return success; } @@ -1441,6 +1443,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean lnk_data_complete_from_cache = TRUE; + gboolean af_inet6_token_valid = FALSE; + gboolean af_inet6_addr_gen_mode_valid = FALSE; if (!nlmsg_valid_hdr (nlh, sizeof (*ifi))) return NULL; @@ -1472,6 +1476,15 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr nl_info_data = li[IFLA_INFO_DATA]; } + if (tb[IFLA_STATS64]) { + struct rtnl_link_stats64 *stats = nla_data (tb[IFLA_STATS64]); + + obj->link.rx_packets = stats->rx_packets; + obj->link.rx_bytes = stats->rx_bytes; + obj->link.tx_packets = stats->tx_packets; + obj->link.tx_bytes = stats->tx_bytes; + } + 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; @@ -1517,9 +1530,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case AF_INET6: _parse_af_inet6 (platform, af_attr, - &obj->link.inet6_token.iid, - &obj->link.inet6_token.is_valid, - &obj->link.inet6_addr_gen_mode_inv); + &obj->link.inet6_token, + &af_inet6_token_valid, + &obj->link.inet6_addr_gen_mode_inv, + &af_inet6_addr_gen_mode_valid); break; } } @@ -1561,7 +1575,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr if ( completed_from_cache && ( lnk_data_complete_from_cache - || address_complete_from_cache)) { + || 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) { if ( lnk_data_complete_from_cache @@ -1580,6 +1597,16 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr } if (address_complete_from_cache) obj->link.addr = link_cached->link.addr; + if (!af_inet6_token_valid) + obj->link.inet6_token = link_cached->link.inet6_token; + if (!af_inet6_addr_gen_mode_valid) + obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv; + if (!tb[IFLA_STATS64]) { + obj->link.rx_packets = link_cached->link.rx_packets; + obj->link.rx_bytes = link_cached->link.rx_bytes; + obj->link.tx_packets = link_cached->link.tx_packets; + obj->link.tx_bytes = link_cached->link.tx_bytes; + } } } @@ -1666,7 +1693,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) } } - obj->ip_address.source = NM_IP_CONFIG_SOURCE_KERNEL; + obj->ip_address.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; obj->ip_address.n_ifa_flags = tb[IFA_FLAGS] ? nla_get_u32 (tb[IFA_FLAGS]) @@ -1896,9 +1923,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) * * This happens, because this route is not nmp_object_is_alive(). * */ - obj->ip_route.source = _NM_IP_CONFIG_SOURCE_RTM_F_CLONED; - } else - obj->ip_route.source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); + obj->ip_route.rt_cloned = TRUE; + } + + obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); obj_result = obj; obj = NULL; @@ -1951,7 +1979,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m static gboolean _nl_msg_new_link_set_afspec (struct nl_msg *msg, - int addr_gen_mode) + int addr_gen_mode, + NMUtilsIPv6IfaceId *iid) { struct nlattr *af_spec; struct nlattr *af_attr; @@ -1961,11 +1990,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg, if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC))) goto nla_put_failure; - if (addr_gen_mode >= 0) { + if (addr_gen_mode >= 0 || iid) { if (!(af_attr = nla_nest_start (msg, AF_INET6))) goto nla_put_failure; - NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + if (addr_gen_mode >= 0) + NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + + if (iid) { + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid); + NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token); + } nla_nest_end (msg, af_attr); } @@ -2258,7 +2295,7 @@ _nl_msg_new_route (int nlmsg_type, .rtm_family = family, .rtm_tos = 0, .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ - .rtm_protocol = nmp_utils_ip_config_source_to_rtprot (source), + .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (source), .rtm_scope = scope, .rtm_type = RTN_UNICAST, .rtm_flags = 0, @@ -2282,7 +2319,7 @@ _nl_msg_new_route (int nlmsg_type, addr_len = family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr); - clear_host_address (family, network, plen, &network_clean); + nm_utils_ipx_address_clear_host_address (family, &network_clean, network, plen); NLA_PUT (msg, RTA_DST, addr_len, &network_clean); NLA_PUT_U32 (msg, RTA_PRIORITY, metric); @@ -2485,6 +2522,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) gsize len; char *actual; gs_free char *actual_free = NULL; + int errsv; g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); @@ -2495,18 +2533,22 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) /* Don't write to suspicious locations */ g_assert (!strstr (path, "/../")); - if (!nm_platform_netns_push (platform, &netns)) + if (!nm_platform_netns_push (platform, &netns)) { + errno = ENETDOWN; return FALSE; + } fd = open (path, O_WRONLY | O_TRUNC); if (fd == -1) { - if (errno == ENOENT) { + errsv = errno; + if (errsv == ENOENT) { _LOGD ("sysctl: failed to open '%s': (%d) %s", - path, errno, strerror (errno)); + path, errsv, strerror (errsv)); } else { _LOGE ("sysctl: failed to open '%s': (%d) %s", - path, errno, strerror (errno)); + path, errsv, strerror (errsv)); } + errno = errsv; return FALSE; } @@ -2527,26 +2569,43 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) actual[len] = '\0'; /* Try to write the entire value three times if a partial write occurs */ + errsv = 0; for (tries = 0, nwrote = 0; tries < 3 && nwrote != len; tries++) { nwrote = write (fd, actual, len); if (nwrote == -1) { - if (errno == EINTR) { + errsv = errno; + if (errsv == EINTR) { _LOGD ("sysctl: interrupted, will try again"); continue; } break; } } - if (nwrote == -1 && errno != EEXIST) { + if (nwrote == -1 && errsv != EEXIST) { _LOGE ("sysctl: failed to set '%s' to '%s': (%d) %s", - path, value, errno, strerror (errno)); + path, value, errsv, strerror (errsv)); } else if (nwrote < len) { _LOGE ("sysctl: failed to set '%s' to '%s' after three attempts", path, value); } - close (fd); - return (nwrote == len); + if (nwrote != len) { + if (close (fd) != 0) { + if (errsv != 0) + errno = errsv; + } else if (errsv != 0) + errno = errsv; + else + errno = EIO; + return FALSE; + } + if (close (fd) != 0) { + /* errno is already properly set. */ + return FALSE; + } + + /* success. errno is undefined (no need to set). */ + return TRUE; } static GSList *sysctl_clear_cache_list; @@ -3689,6 +3748,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event case RTM_NEWLINK: case RTM_NEWADDR: case RTM_NEWROUTE: + case RTM_GETLINK: cache_op = nmp_cache_update_netlink (priv->cache, obj, &obj_cache, &was_visible, cache_pre_hook, platform); cache_post (platform, msghdr, cache_op, obj, obj_cache); @@ -3724,6 +3784,16 @@ cache_lookup_link (NMPlatform *platform, int ifindex) return obj_cache; } +const NMPlatformObject *const* +nm_linux_platform_lookup (NMPlatform *platform, const NMPCacheId *cache_id, guint *out_len) +{ + g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), NULL); + g_return_val_if_fail (cache_id, NULL); + + return nmp_cache_lookup_multi (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, + cache_id, out_len); +} + static GArray * link_get_all (NMPlatform *platform) { @@ -4036,6 +4106,9 @@ retry: } else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) { log_detail = ", firmware not found"; result = NM_PLATFORM_ERROR_NO_FIRMWARE; + } else if (NM_IN_SET (-((int) seq_result), ENODEV)) { + log_level = LOGL_DEBUG; + result = NM_PLATFORM_ERROR_NOT_FOUND; } else { log_level = LOGL_ERR; result = NM_PLATFORM_ERROR_UNSPECIFIED; @@ -4272,7 +4345,7 @@ link_get_udev_device (NMPlatform *platform, int ifindex) return obj_cache ? (GObject *) obj_cache->_link.udev.device : NULL; } -static gboolean +static NMPlatformError link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -4280,7 +4353,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable if (!_support_user_ipv6ll_get ()) { _LOGD ("link: change %d: user-ipv6ll: not supported", ifindex); - return FALSE; + return NM_PLATFORM_ERROR_OPNOTSUPP; } _LOGD ("link: change %d: user-ipv6ll: set IPv6 address generation mode to %s", @@ -4294,8 +4367,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable 0, 0); if ( !nlmsg - || !_nl_msg_new_link_set_afspec (nlmsg, - mode)) + || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) + g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + + return do_change_link (platform, ifindex, nlmsg); +} + +static gboolean +link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + _LOGD ("link: change %d: token: set IPv6 address generation token to %s", + ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL)); + + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0); + if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid)) g_return_val_if_reached (FALSE); return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; @@ -4338,14 +4425,14 @@ link_supports_vlans (NMPlatform *platform, int ifindex) return nmp_utils_ethtool_supports_vlans (obj->link.name); } -static gboolean +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; if (!address || !length) - g_return_val_if_reached (FALSE); + 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)), @@ -4358,13 +4445,13 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size 0, 0); if (!nlmsg) - return FALSE; + g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); NLA_PUT (nlmsg, IFLA_ADDRESS, length, address); - return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; + return do_change_link (platform, ifindex, nlmsg); nla_put_failure: - g_return_val_if_reached (FALSE); + g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); } static gboolean @@ -5095,57 +5182,67 @@ link_release (NMPlatform *platform, int master, int slave) /******************************************************************/ static gboolean -_infiniband_partition_action (NMPlatform *platform, int parent, int p_key, const char *action, char **ifname) +_infiniband_partition_action (NMPlatform *platform, + InfinibandAction action, + int parent, + int p_key, + const NMPlatformLink **out_link) { NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); const NMPObject *obj_parent; - gs_free char *path = NULL; - gs_free char *id = NULL; + const NMPObject *obj; + char path[NM_STRLEN ("/sys/class/net/%s/%s") + IFNAMSIZ + 100]; + char id[20]; + char name[IFNAMSIZ]; + gboolean success; + + nm_assert (NM_IN_SET (action, INFINIBAND_ACTION_CREATE_CHILD, INFINIBAND_ACTION_DELETE_CHILD)); + nm_assert (p_key > 0 && p_key <= 0xffff && p_key != 0x8000); obj_parent = nmp_cache_lookup_link (priv->cache, parent); - if (!obj_parent || !obj_parent->link.name[0]) - g_return_val_if_reached (FALSE); + if (!obj_parent || !obj_parent->link.name[0]) { + errno = ENOENT; + return FALSE; + } + + nm_sprintf_buf (path, + "/sys/class/net/%s/%s", + NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name), + (action == INFINIBAND_ACTION_CREATE_CHILD + ? "create_child" + : "delete_child")); + nm_sprintf_buf (id, "0x%04x", p_key); + success = nm_platform_sysctl_set (platform, path, id); + if (!success) { + if ( action == INFINIBAND_ACTION_DELETE_CHILD + && errno == ENODEV) + return TRUE; + return FALSE; + } - *ifname = g_strdup_printf ("%s.%04x", obj_parent->link.name, p_key); + nm_utils_new_infiniband_name (name, obj_parent->link.name, p_key); + do_request_link (platform, 0, name); - path = g_strdup_printf ("/sys/class/net/%s/%s", - NM_ASSERT_VALID_PATH_COMPONENT (obj_parent->link.name), - action); - id = g_strdup_printf ("0x%04x", p_key); + if (action == INFINIBAND_ACTION_DELETE_CHILD) + return TRUE; - return nm_platform_sysctl_set (platform, path, id); + obj = nmp_cache_lookup_link_full (priv->cache, 0, name, FALSE, + NM_LINK_TYPE_INFINIBAND, NULL, NULL); + if (out_link) + *out_link = obj ? &obj->link : NULL; + return !!obj; } - static gboolean infiniband_partition_add (NMPlatform *platform, int parent, int p_key, const NMPlatformLink **out_link) { - const NMPObject *obj; - gs_free char *ifname = NULL; - - if (!_infiniband_partition_action (platform, parent, p_key, "create_child", &ifname)) - return FALSE; - - do_request_link (platform, 0, ifname); - - obj = nmp_cache_lookup_link_full (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->cache, - 0, ifname, FALSE, NM_LINK_TYPE_INFINIBAND, NULL, NULL); - if (out_link) - *out_link = obj ? &obj->link : NULL; - return !!obj; + return _infiniband_partition_action (platform, INFINIBAND_ACTION_CREATE_CHILD, parent, p_key, out_link); } static gboolean infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) { - gs_free char *ifname = NULL; - - if (!_infiniband_partition_action (platform, parent, p_key, "delete_child", &ifname)) { - if (errno != ENODEV) - return FALSE; - } - - return TRUE; + return _infiniband_partition_action (platform, INFINIBAND_ACTION_DELETE_CHILD, parent, p_key, NULL); } /******************************************************************/ @@ -5587,7 +5684,7 @@ ipx_route_get_all (NMPlatform *platform, int ifindex, NMPObjectType obj_type, NM nm_assert (NMP_OBJECT_GET_CLASS (NMP_OBJECT_UP_CAST (routes[i])) == klass); if ( with_rtprot_kernel - || routes[i]->source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) + || routes[i]->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) g_array_append_vals (array, routes[i], 1); } return array; @@ -6421,6 +6518,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_udev_device = link_get_udev_device; platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_token = link_set_token; platform_class->link_set_address = link_set_address; platform_class->link_get_permanent_address = link_get_permanent_address; diff --git a/src/platform/nm-linux-platform.h b/src/platform/nm-linux-platform.h index 4ae2fd14..3b2a440e 100644 --- a/src/platform/nm-linux-platform.h +++ b/src/platform/nm-linux-platform.h @@ -52,4 +52,10 @@ NMPlatform *nm_linux_platform_new (gboolean netns_support); void nm_linux_platform_setup (void); +struct _NMPCacheId; + +const NMPlatformObject *const *nm_linux_platform_lookup (NMPlatform *platform, + const struct _NMPCacheId *cache_id, + guint *out_len); + #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index b4542adf..068801ee 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -144,8 +144,7 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, struct ethtool_perm_addr e; guint8 _extra_data[NM_UTILS_HWADDR_LEN_MAX + 1]; } edata; - static const guint8 zeros[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; - static guint8 ones[NM_UTILS_HWADDR_LEN_MAX] = { 0 }; + guint i; if (!ifname) return FALSE; @@ -157,18 +156,23 @@ nmp_utils_ethtool_get_permanent_address (const char *ifname, if (!ethtool_get (ifname, &edata.e)) return FALSE; - g_assert (edata.e.size <= NM_UTILS_HWADDR_LEN_MAX); - - /* Some drivers might return a permanent address of all zeros. - * Reject that (rh#1264024) */ - if (memcmp (edata.e.data, zeros, edata.e.size) == 0) + if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX) + return FALSE; + if (edata.e.size < 1) 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) + if (NM_IN_SET (edata.e.data[0], 0, 0xFF)) { + /* Some drivers might return a permanent address of all zeros. + * Reject that (rh#1264024) + * + * Some drivers return a permanent address of all ones. Reject that too */ + for (i = 1; i < edata.e.size; i++) { + if (edata.e.data[0] != edata.e.data[i]) + goto not_all_0or1; + } return FALSE; + } +not_all_0or1: memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; @@ -433,14 +437,35 @@ nmp_utils_device_exists (const char *name) return g_file_test (sysdir, G_FILE_TEST_EXISTS); } -guint -nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source) +NMIPConfigSource +nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) { - switch (source) { - case NM_IP_CONFIG_SOURCE_UNKNOWN: + return ((int) rtprot) + 1; +} + +NMIPConfigSource +nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) +{ + /* when adding a route to kernel for a give @source, the resulting route + * will be put into the cache with a source of NM_IP_CONFIG_SOURCE_RTPROT_*. + * This function returns that. */ + return nmp_utils_ip_config_source_from_rtprot (nmp_utils_ip_config_source_coerce_to_rtprot (source)); +} + +guint8 +nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) +{ + /* when adding a route to kernel, we coerce the @source field + * to rtm_protocol. This is not lossless as we map different + * source values to the same RTPROT uint8 value. */ + if (source <= NM_IP_CONFIG_SOURCE_UNKNOWN) return RTPROT_UNSPEC; + + if (source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST) + return source - 1; + + switch (source) { case NM_IP_CONFIG_SOURCE_KERNEL: - case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: return RTPROT_KERNEL; case NM_IP_CONFIG_SOURCE_DHCP: return RTPROT_DHCP; @@ -453,18 +478,32 @@ nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source) } NMIPConfigSource -nmp_utils_ip_config_source_from_rtprot (guint rtprot) +nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) { - switch (rtprot) { - case RTPROT_UNSPEC: + /* When we receive a route from kernel and put it into the platform cache, + * we preserve the protocol field by converting it to a NMIPConfigSource + * via nmp_utils_ip_config_source_from_rtprot(). + * + * However, that is not the inverse of nmp_utils_ip_config_source_coerce_to_rtprot(). + * Instead, to go back to the original value, you need another step: + * nmp_utils_ip_config_source_coerce_from_rtprot (nmp_utils_ip_config_source_from_rtprot (rtprot)). + * + * This might partly restore the original source value, but of course that + * is not really possible because nmp_utils_ip_config_source_coerce_to_rtprot() + * is not injective. + * */ + switch (source) { + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: return NM_IP_CONFIG_SOURCE_UNKNOWN; - case RTPROT_KERNEL: - return NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; - case RTPROT_REDIRECT: + + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: return NM_IP_CONFIG_SOURCE_KERNEL; - case RTPROT_RA: + + case NM_IP_CONFIG_SOURCE_RTPROT_RA: return NM_IP_CONFIG_SOURCE_RDISC; - case RTPROT_DHCP: + + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: return NM_IP_CONFIG_SOURCE_DHCP; default: @@ -472,3 +511,50 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot) } } +const char * +nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len) +{ + const char *s = NULL; + nm_utils_to_string_buffer_init (&buf, &len); \ + + if (!len) + return buf; + + switch (source) { + case NM_IP_CONFIG_SOURCE_UNKNOWN: s = "unknown"; break; + + case NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC: s = "rt-unspec"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_REDIRECT: s = "rt-redirect"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: s = "rt-kernel"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_BOOT: s = "rt-boot"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_STATIC: s = "rt-static"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: s = "rt-dhcp"; break; + case NM_IP_CONFIG_SOURCE_RTPROT_RA: s = "rt-ra"; break; + + case NM_IP_CONFIG_SOURCE_KERNEL: s = "kernel"; break; + case NM_IP_CONFIG_SOURCE_SHARED: s = "shared"; break; + case NM_IP_CONFIG_SOURCE_IP4LL: s = "ipv4ll"; break; + case NM_IP_CONFIG_SOURCE_PPP: s = "ppp"; break; + case NM_IP_CONFIG_SOURCE_WWAN: s = "wwan"; break; + case NM_IP_CONFIG_SOURCE_VPN: s = "vpn"; break; + case NM_IP_CONFIG_SOURCE_DHCP: s = "dhcp"; break; + case NM_IP_CONFIG_SOURCE_RDISC: s = "rdisc"; break; + case NM_IP_CONFIG_SOURCE_USER: s = "user"; break; + default: + break; + } + + if (source >= 1 && source <= 0x100) { + if (s) + g_snprintf (buf, len, "%s", s); + else + g_snprintf (buf, len, "rt-%d", ((int) source) - 1); + } else { + if (s) + g_strlcpy (buf, s, len); + else + g_snprintf (buf, len, "(%d)", source); + } + return buf; +} + diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index f2594747..456c0865 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -54,7 +54,10 @@ const char *nmp_utils_udev_get_driver (GUdevDevice *device); gboolean nmp_utils_device_exists (const char *name); -guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source); -NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot); +NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint8 rtprot) _nm_const; +guint8 nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) _nm_const; +NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const; +const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len); #endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 26ac766d..9dace699 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -205,6 +205,7 @@ NM_UTILS_LOOKUP_STR_DEFINE (_nm_platform_error_to_string, NMPlatformError, 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_STR_ITEM (NM_PLATFORM_ERROR_OPNOTSUPP, "not-supported"), NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT), ); @@ -387,6 +388,20 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint ba /******************************************************************/ +static int +_link_get_all_presort (gconstpointer p_a, + gconstpointer p_b) +{ + const NMPlatformLink *a = p_a; + const NMPlatformLink *b = p_b; + + if (a->ifindex < b->ifindex) + return -1; + if (a->ifindex > b->ifindex) + return 1; + return 0; +} + /** * nm_platform_link_get_all: * self: platform instance @@ -409,15 +424,17 @@ nm_platform_link_get_all (NMPlatform *self) if (!links || links->len == 0) return links; + /* first sort the links by their ifindex. Below we will sort further by moving + * children/slaves to the end. */ + g_array_sort (links, _link_get_all_presort); + unseen = g_hash_table_new (g_direct_hash, g_direct_equal); for (i = 0; i < links->len; i++) { item = &g_array_index (links, NMPlatformLink, i); - _LOGt ("link-get: %3d: %s", i, nm_platform_link_to_string (item, NULL, 0)); - - nm_assert (item->ifindex > 0 && !g_hash_table_contains (unseen, GINT_TO_POINTER (item->ifindex))); - - g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL); + nm_assert (item->ifindex > 0); + if (!nm_g_hash_table_insert (unseen, GINT_TO_POINTER (item->ifindex), NULL)) + nm_assert_not_reached (); } #ifndef G_DISABLE_ASSERT @@ -468,8 +485,6 @@ nm_platform_link_get_all (NMPlatform *self) if (item->parent > 0 && g_hash_table_contains (unseen, GINT_TO_POINTER (item->parent))) continue; - _LOGt ("link-get: add %3d -> %3d: %s", i, j, nm_platform_link_to_string (item, NULL, 0)); - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); g_array_index (result, NMPlatformLink, j++) = *item; item->ifindex = 0; @@ -481,8 +496,6 @@ nm_platform_link_get_all (NMPlatform *self) * This can happen for veth pairs where each peer is parent of the other end. */ item = &g_array_index (links, NMPlatformLink, first_idx); - _LOGt ("link-get: add (loop) %3d -> %3d: %s", first_idx, j, nm_platform_link_to_string (item, NULL, 0)); - g_hash_table_remove (unseen, GINT_TO_POINTER (item->ifindex)); g_array_index (result, NMPlatformLink, j++) = *item; item->ifindex = 0; @@ -888,33 +901,25 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex) } /** - * nm_platform_link_get_ipv6_token: + * nm_platform_link_set_ipv6_token: * @self: platform instance * @ifindex: Interface index * @iid: Tokenized interface identifier * - * Returns IPv6 tokenized interface identifier. If the platform or OS doesn't - * support IPv6 tokenized interface identifiers, or the token is not set - * this call will fail and return %FALSE. + * Sets then IPv6 tokenized interface identifier. * * Returns: %TRUE a tokenized identifier was available */ gboolean -nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid) +nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) { - const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex >= 0, FALSE); - g_return_val_if_fail (iid, FALSE); + g_return_val_if_fail (iid.id, FALSE); - - pllink = nm_platform_link_get (self, ifindex); - if (pllink && pllink->inet6_token.is_valid) { - *iid = pllink->inet6_token.iid; - return TRUE; - } + if (klass->link_set_token) + return klass->link_set_token (self, ifindex, iid); return FALSE; } @@ -977,18 +982,16 @@ nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex) * platform or OS doesn't support changing the IPv6LL address mode, this call * will fail and return %FALSE. * - * Returns: %TRUE if the operation was successful, %FALSE if it failed. + * Returns: %NM_PLATFORM_ERROR_SUCCESS if the operation was successful or an error code otherwise. */ -gboolean +NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); - if (klass->link_set_user_ipv6ll_enabled) - return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); - return FALSE; + return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); } /** @@ -999,16 +1002,18 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea * * Set interface MAC address. */ -gboolean +NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) { - _CHECK_SELF (self, klass, FALSE); + _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (address, FALSE); - g_return_val_if_fail (length > 0, FALSE); + 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", nm_platform_link_get_name (self, ifindex), ifindex); + _LOGD ("link: setting %s (%d) hardware address", + nm_strquote_a (20, nm_platform_link_get_name (self, ifindex)), + ifindex); return klass->link_set_address (self, ifindex, address, length); } @@ -1895,21 +1900,27 @@ _infiniband_add_add_or_delete (NMPlatform *self, gboolean add, const NMPlatformLink **out_link) { - gs_free char *parent_name = NULL; - gs_free char *name = NULL; + char name[IFNAMSIZ]; + const NMPlatformLink *parent_link; NMPlatformError plerr; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (parent >= 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (p_key >= 0, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NM_PLATFORM_ERROR_BUG); + + /* the special keys 0x0000 and 0x8000 are not allowed. */ + if (NM_IN_SET (p_key, 0, 0x8000)) + return NM_PLATFORM_ERROR_UNSPECIFIED; - parent_name = g_strdup (nm_platform_link_get_name (self, parent)); - if ( !parent_name - || nm_platform_link_get_type (self, parent) != NM_LINK_TYPE_INFINIBAND) + parent_link = nm_platform_link_get (self, parent); + if (!parent_link) + return NM_PLATFORM_ERROR_NOT_FOUND; + + if (parent_link->type != NM_LINK_TYPE_INFINIBAND) return NM_PLATFORM_ERROR_WRONG_TYPE; - name = g_strdup_printf ("%s.%04x", parent_name, p_key); + nm_utils_new_infiniband_name (name, parent_link->name, p_key); if (add) { plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); @@ -1917,7 +1928,7 @@ _infiniband_add_add_or_delete (NMPlatform *self, return plerr; _LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d", - name, parent_name, parent, p_key); + name, parent_link->name, parent, p_key); if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; } else { @@ -2894,7 +2905,7 @@ nm_platform_ip4_route_add (NMPlatform *self, NMPlatformIP4Route route = { 0 }; route.ifindex = ifindex; - route.source = source; + route.rt_source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -2921,7 +2932,7 @@ nm_platform_ip6_route_add (NMPlatform *self, NMPlatformIP6Route route = { 0 }; route.ifindex = ifindex; - route.source = source; + route.rt_source = source; route.network = network; route.plen = plen; route.gateway = gateway; @@ -3012,38 +3023,6 @@ nm_platform_vlan_qos_mapping_to_string (const char *name, } static const char * -source_to_string (NMIPConfigSource source) -{ - switch (source) { - case NM_IP_CONFIG_SOURCE_RTPROT_KERNEL: - return "rtprot-kernel"; - case _NM_IP_CONFIG_SOURCE_RTM_F_CLONED: - return "rtm-f-cloned"; - case NM_IP_CONFIG_SOURCE_KERNEL: - return "kernel"; - case NM_IP_CONFIG_SOURCE_SHARED: - return "shared"; - case NM_IP_CONFIG_SOURCE_IP4LL: - return "ipv4ll"; - case NM_IP_CONFIG_SOURCE_PPP: - return "ppp"; - case NM_IP_CONFIG_SOURCE_WWAN: - return "wwan"; - case NM_IP_CONFIG_SOURCE_VPN: - return "vpn"; - case NM_IP_CONFIG_SOURCE_DHCP: - return "dhcp"; - case NM_IP_CONFIG_SOURCE_RDISC: - return "rdisc"; - case NM_IP_CONFIG_SOURCE_USER: - return "user"; - default: - break; - } - return "unknown"; -} - -static const char * _lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) { if (lifetime == NM_PLATFORM_LIFETIME_PERMANENT) @@ -3081,7 +3060,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) GString *str_flags; char str_addrmode[30]; gs_free char *str_addr = NULL; - gs_free char *str_inet6_token = NULL; + char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; const char *str_link_type; if (!nm_utils_to_string_buffer_init_null (link, &buf, &len)) @@ -3118,8 +3097,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) 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) - str_inet6_token = nm_utils_hwaddr_ntoa (&link->inet6_token.iid, sizeof (link->inet6_token.iid)); str_link_type = nm_link_type_to_string (link->type); @@ -3138,6 +3115,8 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) "%s%s" /* addr */ "%s%s" /* inet6_token */ "%s%s" /* driver */ + " rx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT + " tx:%"G_GUINT64_FORMAT",%"G_GUINT64_FORMAT , link->ifindex, link->name, @@ -3153,10 +3132,12 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) 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 " : "", - str_inet6_token ? str_inet6_token : "", + link->inet6_token.id ? " inet6token " : "", + link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "", link->driver ? " driver " : "", - link->driver ? link->driver : ""); + link->driver ? link->driver : "", + link->rx_packets, link->rx_bytes, + link->tx_packets, link->tx_bytes); g_string_free (str_flags, TRUE); return buf; } @@ -3471,7 +3452,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu char s_peer[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; char str_label[32]; - char str_lft[30], str_pref[30], str_time[50]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; gint32 now = nm_utils_get_monotonic_timestamp_s (); @@ -3510,7 +3491,7 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu str_dev, _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), str_label, - source_to_string (address->source)); + nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source))); g_free (str_peer); return buf; } @@ -3582,7 +3563,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; char s_address[INET6_ADDRSTRLEN]; char s_peer[INET6_ADDRSTRLEN]; - char str_lft[30], str_pref[30], str_time[50]; + char str_lft[30], str_pref[30], str_time[50], s_source[50]; char str_dev[TO_STRING_DEV_BUF_SIZE]; char *str_peer = NULL; const char *str_lft_p, *str_pref_p, *str_time_p; @@ -3616,7 +3597,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu str_peer ? str_peer : "", str_dev, _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), - source_to_string (address->source)); + nmp_utils_ip_config_source_to_string (address->addr_source, s_source, sizeof (s_source))); g_free (str_peer); return buf; } @@ -3639,7 +3620,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi char s_network[INET_ADDRSTRLEN], s_gateway[INET_ADDRSTRLEN]; char s_pref_src[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; - char str_scope[30]; + char str_scope[30], s_source[50]; if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) return buf; @@ -3656,6 +3637,7 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi " metric %"G_GUINT32_FORMAT " mss %"G_GUINT32_FORMAT " src %s" /* source */ + "%s" /* cloned */ "%s%s" /* scope */ "%s%s" /* pref-src */ "", @@ -3665,7 +3647,8 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi str_dev, route->metric, route->mss, - source_to_string (route->source), + nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), + route->rt_cloned ? " cloned" : "", route->scope_inv ? " scope " : "", route->scope_inv ? (nm_platform_route_scope2str (nm_platform_route_scope_inv (route->scope_inv), str_scope, sizeof (str_scope))) : "", route->pref_src ? " pref-src " : "", @@ -3689,7 +3672,7 @@ const char * nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len) { char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN]; - char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50]; if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) return buf; @@ -3706,6 +3689,7 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi " metric %"G_GUINT32_FORMAT " mss %"G_GUINT32_FORMAT " src %s" /* source */ + "%s" /* cloned */ "", s_network, route->plen, @@ -3713,7 +3697,8 @@ nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsi str_dev, route->metric, route->mss, - source_to_string (route->source)); + nmp_utils_ip_config_source_to_string (route->rt_source, s_source, sizeof (s_source)), + route->rt_cloned ? " cloned" : ""); return buf; } @@ -3808,13 +3793,15 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) _CMP_FIELD (a, b, arptype); _CMP_FIELD (a, b, addr.len); _CMP_FIELD (a, b, inet6_addr_gen_mode_inv); - _CMP_FIELD (a, b, inet6_token.is_valid); _CMP_FIELD_STR_INTERNED (a, b, kind); _CMP_FIELD_STR_INTERNED (a, b, driver); if (a->addr.len) _CMP_FIELD_MEMCMP_LEN (a, b, addr.data, a->addr.len); - if (a->inet6_token.is_valid) - _CMP_FIELD_MEMCMP (a, b, inet6_token.iid); + _CMP_FIELD_MEMCMP (a, b, inet6_token); + _CMP_FIELD (a, b, rx_packets); + _CMP_FIELD (a, b, rx_bytes); + _CMP_FIELD (a, b, tx_packets); + _CMP_FIELD (a, b, tx_bytes); return 0; } @@ -3935,10 +3922,10 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD (a, b, address); _CMP_FIELD (a, b, plen); _CMP_FIELD (a, b, peer_address); + _CMP_FIELD (a, b, addr_source); _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); @@ -3954,14 +3941,12 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD_MEMCMP (a, b, address); - + _CMP_FIELD (a, b, plen); p_a = nm_platform_ip6_address_get_peer (a); p_b = nm_platform_ip6_address_get_peer (b); _CMP_DIRECT_MEMCMP (p_a, p_b, sizeof (*p_a)); - - _CMP_FIELD (a, b, plen); + _CMP_FIELD (a, b, addr_source); _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); @@ -3974,14 +3959,15 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD (a, b, network); _CMP_FIELD (a, b, plen); - _CMP_FIELD (a, b, gateway); _CMP_FIELD (a, b, metric); + _CMP_FIELD (a, b, gateway); + _CMP_FIELD (a, b, rt_source); _CMP_FIELD (a, b, mss); _CMP_FIELD (a, b, scope_inv); _CMP_FIELD (a, b, pref_src); + _CMP_FIELD (a, b, rt_cloned); return 0; } @@ -3990,12 +3976,13 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route { _CMP_SELF (a, b); _CMP_FIELD (a, b, ifindex); - _CMP_FIELD (a, b, source); _CMP_FIELD_MEMCMP (a, b, network); _CMP_FIELD (a, b, plen); - _CMP_FIELD_MEMCMP (a, b, gateway); _CMP_FIELD (a, b, metric); + _CMP_FIELD_MEMCMP (a, b, gateway); + _CMP_FIELD (a, b, rt_source); _CMP_FIELD (a, b, mss); + _CMP_FIELD (a, b, rt_cloned); return 0; } @@ -4128,7 +4115,7 @@ _vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout { return nm_platform_ip4_route_add (self, ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.source, + route->rx.rt_source, route->r4.network, route->rx.plen, route->r4.gateway, @@ -4142,7 +4129,7 @@ _vtr_v6_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *rout { return nm_platform_ip6_route_add (self, ifindex > 0 ? ifindex : route->rx.ifindex, - route->rx.source, + route->rx.rt_source, route->r6.network, route->rx.plen, route->r6.gateway, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 19724f1c..fc6965e9 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -49,8 +49,6 @@ /******************************************************************/ -typedef struct _NMPlatform NMPlatform; - /* workaround for older libnl version, that does not define these flags. */ #ifndef IFA_F_MANAGETEMPADDR #define IFA_F_MANAGETEMPADDR 0x100 @@ -90,6 +88,7 @@ typedef enum { /*< skip >*/ NM_PLATFORM_ERROR_WRONG_TYPE, NM_PLATFORM_ERROR_NOT_SLAVE, NM_PLATFORM_ERROR_NO_FIRMWARE, + NM_PLATFORM_ERROR_OPNOTSUPP, } NMPlatformError; @@ -98,6 +97,11 @@ typedef struct { guint8 addr_ptr[1]; in_addr_t addr4; struct in6_addr addr6; + + /* NMIPAddr is really a union for IP addresses. + * However, as ethernet addresses fit in here nicely, ruse + * it also for an ethernet MAC address. */ + guint8 addr_eth[6 /*ETH_ALEN*/]; }; } NMIPAddr; @@ -144,17 +148,20 @@ struct _NMPlatformLink { guint8 len; } addr; - /* rtnl_link_inet6_get_token() */ - struct { - NMUtilsIPv6IfaceId iid; - guint8 is_valid; - } inet6_token; + /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */ + NMUtilsIPv6IfaceId inet6_token; /* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse * to have a default of 0 -- meaning: unspecified. That way, a struct * initialized with memset(0) has and unset value.*/ guint8 inet6_addr_gen_mode_inv; + /* Statistics */ + guint64 rx_packets; + guint64 rx_bytes; + guint64 tx_packets; + guint64 tx_bytes; + /* @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. */ bool connected:1; @@ -200,7 +207,7 @@ typedef struct { #define __NMPlatformIPAddress_COMMON \ __NMPlatformObject_COMMON; \ - NMIPConfigSource source; \ + NMIPConfigSource addr_source; \ \ /* Timestamp in seconds in the reference system of nm_utils_get_monotonic_timestamp_*(). * @@ -303,8 +310,21 @@ typedef union { #define __NMPlatformIPRoute_COMMON \ __NMPlatformObject_COMMON; \ - NMIPConfigSource source; \ + \ + /* The NMIPConfigSource. For routes that we receive from cache this corresponds + * to the rtm_protocol field (and is one of the NM_IP_CONFIG_SOURCE_RTPROT_* values). + * When adding a route, the source will be coerced to the protocol using + * nmp_utils_ip_config_source_coerce_to_rtprot(). */ \ + NMIPConfigSource rt_source; \ + \ guint8 plen; \ + \ + /* the route has rtm_flags set to RTM_F_CLONED. Such a route + * is hidden by platform and does not exist from the point-of-view + * of platform users. This flag is internal to track those hidden + * routes. Such a route is not alive, according to nmp_object_is_alive(). */ \ + bool rt_cloned:1; \ + \ guint32 metric; \ guint32 mss; \ ; @@ -506,13 +526,14 @@ typedef struct { const char *(*link_get_udi) (NMPlatform *self, int ifindex); GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex); - gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + NMPlatformError (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid); gboolean (*link_get_permanent_address) (NMPlatform *, int ifindex, guint8 *buf, size_t *length); - gboolean (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); + NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); @@ -717,7 +738,6 @@ gboolean nm_platform_link_is_up (NMPlatform *self, int ifindex); gboolean nm_platform_link_is_connected (NMPlatform *self, int ifindex); gboolean nm_platform_link_uses_arp (NMPlatform *self, int ifindex); guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex); -gboolean nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid); gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex); gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length); int nm_platform_link_get_master (NMPlatform *self, int slave); @@ -740,10 +760,11 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex); GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex); -gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length); -gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); +NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); gboolean nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index eb7e1ca4..30a52c25 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -47,6 +47,10 @@ } \ } G_STMT_END +/* logging to trace object lifetime and references. + * Disabled by default. */ +#define _LOGr(...) G_STMT_START { if (FALSE) { _LOGt (__VA_ARGS__); } } G_STMT_END + /*********************************************************************************************/ struct _NMPCache { @@ -211,7 +215,7 @@ nmp_object_ref (NMPObject *obj) g_return_val_if_fail (obj->_ref_count != NMP_REF_COUNT_STACKINIT, NULL); obj->_ref_count++; - _LOGt (obj, "ref: %d", obj->_ref_count); + _LOGr (obj, "ref: %d", obj->_ref_count); return obj; } @@ -222,7 +226,7 @@ nmp_object_unref (NMPObject *obj) if (obj) { g_return_if_fail (obj->_ref_count > 0); g_return_if_fail (obj->_ref_count != NMP_REF_COUNT_STACKINIT); - _LOGt (obj, "%s: %d", + _LOGr (obj, "%s: %d", obj->_ref_count <= 1 ? "destroy" : "unref", obj->_ref_count - 1); if (--obj->_ref_count <= 0) { @@ -262,7 +266,7 @@ _nmp_object_new_from_class (const NMPClass *klass) obj = g_slice_alloc0 (klass->sizeof_data + G_STRUCT_OFFSET (NMPObject, object)); obj->_class = klass; obj->_ref_count = 1; - _LOGt (obj, "new"); + _LOGr (obj, "new"); return obj; } @@ -915,12 +919,12 @@ _vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj) * * If nmp_object_from_nl() would just return NULL, we couldn't look * into the cache to see if it contains a route that now disappears - * (because it is cloned). + * (because it changed to be cloned). * * Instead we create a dead object, and nmp_cache_update_netlink() * will remove the old version of the update. **/ - return obj->object.ifindex > 0 && (obj->ip_route.source != _NM_IP_CONFIG_SOURCE_RTM_F_CLONED); + return obj->object.ifindex > 0 && !obj->ip_route.rt_cloned; } gboolean diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index c5241037..d295f7a0 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -94,9 +94,9 @@ typedef enum { /*< skip >*/ NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, } NMPCacheIdType; -typedef struct _NMPObject NMPObject; +typedef struct _NMPCacheId NMPCacheId; -typedef struct { +struct _NMPCacheId { union { NMMultiIndexId base; guint8 _id_type; /* NMPCacheIdType as guint8 */ @@ -136,7 +136,7 @@ typedef struct { struct in6_addr _misaligned_network; } routes_by_destination_ip6; }; -} NMPCacheId; +}; extern NMPCacheId _nmp_cache_id_static; #define NMP_CACHE_ID_STATIC (&_nmp_cache_id_static) diff --git a/src/platform/tests/Makefile.am b/src/platform/tests/Makefile.am index 5af4ce91..0633dd28 100644 --- a/src/platform/tests/Makefile.am +++ b/src/platform/tests/Makefile.am @@ -28,7 +28,7 @@ TEST_SOURCES = \ AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(CODE_COVERAGE_LDFLAGS) PLATFORM_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @GNOME_CODE_COVERAGE_RULES@ @@ -109,12 +109,12 @@ test_cleanup_linux_LDADD = $(PLATFORM_LDADD) test_nmp_object_SOURCES = \ test-nmp-object.c test_nmp_object_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_general_SOURCES = \ test-general.c test_general_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la @VALGRIND_RULES@ diff --git a/src/platform/tests/Makefile.in b/src/platform/tests/Makefile.in index 49f2fa09..4922a3dc 100644 --- a/src/platform/tests/Makefile.in +++ b/src/platform/tests/Makefile.in @@ -102,8 +102,9 @@ TESTS = test-address-fake$(EXEEXT) test-address-linux$(EXEEXT) \ test-route-fake$(EXEEXT) test-route-linux$(EXEEXT) subdir = src/platform/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ - $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ + $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_options.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -170,7 +171,8 @@ test_cleanup_linux_OBJECTS = $(am_test_cleanup_linux_OBJECTS) test_cleanup_linux_DEPENDENCIES = $(PLATFORM_LDADD) am_test_general_OBJECTS = test-general.$(OBJEXT) test_general_OBJECTS = $(am_test_general_OBJECTS) -test_general_DEPENDENCIES = $(top_builddir)/src/libNetworkManager.la +test_general_DEPENDENCIES = \ + $(top_builddir)/src/libNetworkManagerTest.la am__objects_10 = test_link_fake-nm-platform.$(OBJEXT) \ test_link_fake-nm-fake-platform.$(OBJEXT) \ test_link_fake-nm-linux-platform.$(OBJEXT) @@ -192,7 +194,7 @@ test_link_linux_DEPENDENCIES = $(PLATFORM_LDADD) am_test_nmp_object_OBJECTS = test-nmp-object.$(OBJEXT) test_nmp_object_OBJECTS = $(am_test_nmp_object_OBJECTS) test_nmp_object_DEPENDENCIES = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la am__objects_14 = test_route_fake-nm-platform.$(OBJEXT) \ test_route_fake-nm-fake-platform.$(OBJEXT) \ test_route_fake-nm-linux-platform.$(OBJEXT) @@ -522,6 +524,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ DNSMASQ_PATH = @DNSMASQ_PATH@ DNSSEC_TRIGGER_SCRIPT = @DNSSEC_TRIGGER_SCRIPT@ DSYMUTIL = @DSYMUTIL@ @@ -578,13 +581,14 @@ INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ +JANSSON_CFLAGS = @JANSSON_CFLAGS@ +JANSSON_LIBS = @JANSSON_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAUDIT_CFLAGS = @LIBAUDIT_CFLAGS@ LIBAUDIT_LIBS = @LIBAUDIT_LIBS@ -LIBDL = @LIBDL@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ @@ -596,6 +600,8 @@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ @@ -656,6 +662,8 @@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +SANITIZERS = @SANITIZERS@ +SANITIZER_ENV = @SANITIZER_ENV@ SED = @SED@ SELINUX_CFLAGS = @SELINUX_CFLAGS@ SELINUX_LIBS = @SELINUX_LIBS@ @@ -691,6 +699,7 @@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_RANLIB = @ac_ct_RANLIB@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -772,7 +781,7 @@ TEST_SOURCES = \ AM_CFLAGS = $(CODE_COVERAGE_CFLAGS) AM_LDFLAGS = $(GLIB_LIBS) $(GUDEV_LIBS) $(LIBNL_LIBS) $(CODE_COVERAGE_LDFLAGS) PLATFORM_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la EXTRA_DIST = test-common.h monitor_SOURCES = monitor.c $(PLATFORM_SOURCES) @@ -837,13 +846,13 @@ test_nmp_object_SOURCES = \ test-nmp-object.c test_nmp_object_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la test_general_SOURCES = \ test-general.c test_general_LDADD = \ - $(top_builddir)/src/libNetworkManager.la + $(top_builddir)/src/libNetworkManagerTest.la all: all-am diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index 3af34be4..937eea11 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -25,7 +25,7 @@ #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" NMTST_DEFINE (); diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 0e3cf10b..87fccee2 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -8,7 +8,7 @@ #include "nm-fake-platform.h" #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define DEVICE_NAME "nm-test-device" @@ -84,7 +84,7 @@ void link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, N /*****************************************************************************/ -int nmtstp_run_command (const char *format, ...) __attribute__((__format__ (__printf__, 1, 2))); +int nmtstp_run_command (const char *format, ...) _nm_printf (1, 2); #define nmtstp_run_command_check(...) do { g_assert_cmpint (nmtstp_run_command (__VA_ARGS__), ==, 0); } while (0) /*****************************************************************************/ diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index d8d92561..f67f0089 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -25,7 +25,7 @@ #include "nm-platform-utils.h" #include "nm-linux-platform.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" /******************************************************************/ diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 9d548aab..99873620 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -30,7 +30,7 @@ #include "nm-platform-utils.h" #include "test-common.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" #define LO_INDEX 1 #define LO_NAME "lo" @@ -60,16 +60,12 @@ test_bogus(void) g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX)); g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX)); g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX)); @@ -80,7 +76,6 @@ test_bogus(void) g_assert (!addrlen); g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*failure changing link: *"); g_assert (!nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU)); g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX)); @@ -226,7 +221,7 @@ test_slave (int master, int type, SignalData *master_changed) g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, master); accept_signals (link_changed, 1, 3); - accept_signals (master_changed, 0, 1); + accept_signals (master_changed, 0, 2); /* enslaveing brings put the slave */ if (NM_IN_SET (link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) @@ -515,13 +510,13 @@ test_bridge_addr (void) g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); - g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE)); + g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE) == NM_PLATFORM_ERROR_SUCCESS); g_assert (nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); g_assert (plink); g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE); - g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE)); + g_assert (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE) == NM_PLATFORM_ERROR_SUCCESS); g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); g_assert (plink); @@ -572,7 +567,7 @@ test_internal (void) g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); + accept_signals (link_changed, 1, 2); g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); @@ -592,7 +587,7 @@ test_internal (void) g_assert (nm_platform_link_supports_vlans (NM_PLATFORM_GET, ifindex)); /* Set MAC address */ - g_assert (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac))); + g_assert (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac)) == NM_PLATFORM_ERROR_SUCCESS); address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addrlen); g_assert (addrlen == sizeof(mac)); g_assert (!memcmp (address, mac, addrlen)); @@ -778,11 +773,32 @@ test_software_detect (gconstpointer user_data) } case NM_LINK_TYPE_MACVLAN: { NMPlatformLnkMacvlan lnk_macvlan = { }; + const NMPlatformLink *dummy; + char buf[256]; + int i; lnk_macvlan.mode = MACVLAN_MODE_BRIDGE; lnk_macvlan.no_promisc = FALSE; lnk_macvlan.tap = FALSE; + /* Since in old kernel versions sysfs files for macvtaps are not + * namespaced, the creation can fail if a macvtap in another namespace + * has the same index. Try to detect this situation and skip already + * used indexes. + * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=17af2bce88d31e65ed73d638bb752d2e13c66ced + */ + for (i = ifindex_parent + 1; i < ifindex_parent + 100; i++) { + snprintf (buf, sizeof (buf), "/sys/class/macvtap/tap%d", i); + if (!g_file_test (buf, G_FILE_TEST_IS_SYMLINK)) + break; + + _LOGD ("skipping ifindex %d as already used by a macvtap", i); + + dummy = nmtstp_link_dummy_add (NM_PLATFORM_GET, FALSE, "dummy-tmp"); + g_assert_cmpint (dummy->ifindex, ==, i); + nmtstp_link_del (NM_PLATFORM_GET, FALSE, dummy->ifindex, NULL); + } + if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) g_error ("Failed adding MACVLAN interface"); break; @@ -1861,7 +1877,7 @@ _test_netns_setup (gpointer fixture, gconstpointer test_data) { /* the singleton platform instance has netns support disabled. * Destroy the instance before the test and re-create it afterwards. */ - g_object_unref (nm_platform_get ()); + g_object_unref (NM_PLATFORM_GET); } static void @@ -1919,6 +1935,14 @@ _test_netns_check_skip (void) /******************************************************************/ +#define _sysctl_assert_eq(plat, path, value) \ + G_STMT_START { \ + gs_free char *_val = NULL; \ + \ + _val = nm_platform_sysctl_get (plat, path); \ + g_assert_cmpstr (_val, ==, value); \ + } G_STMT_END + static void test_netns_general (gpointer fixture, gconstpointer test_data) { @@ -1954,13 +1978,19 @@ test_netns_general (gpointer fixture, gconstpointer test_data) _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-c-%s-%02d", id, i)); } - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, NULL); + _sysctl_assert_eq (platform_1,"/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex", + NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex"), ==, NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex"), ==, nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex", + NULL); + _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex", + nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); for (i = 0; i < 10; i++) { NMPlatform *pl; @@ -1982,10 +2012,11 @@ test_netns_general (gpointer fixture, gconstpointer test_data) path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; } g_assert (nm_platform_sysctl_set (pl, path, nm_sprintf_buf (sbuf, "%d", j))); - g_assert_cmpstr (nm_platform_sysctl_get (pl, path), ==, nm_sprintf_buf (sbuf, "%d", j)); + _sysctl_assert_eq (pl, path, nm_sprintf_buf (sbuf, "%d", j)); } - g_assert_cmpstr (nm_platform_sysctl_get (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"), ==, NULL); - g_assert_cmpstr (nm_platform_sysctl_get (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6"), ==, NULL); + + _sysctl_assert_eq (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6", NULL); + _sysctl_assert_eq (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6", NULL); /* older kernels (Ubuntu 12.04) don't support ethtool -i for dummy devices. Work around that and * skip asserts that are known to fail. */ diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c index d77170b3..9d4f69de 100644 --- a/src/platform/tests/test-nmp-object.c +++ b/src/platform/tests/test-nmp-object.c @@ -22,7 +22,7 @@ #include "nmp-object.h" -#include "nm-test-utils.h" +#include "nm-test-utils-core.h" struct { GList *udev_devices; diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index a50392a6..360404e9 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -23,9 +23,9 @@ #include <linux/rtnetlink.h> #include "nm-core-utils.h" -#include "test-common.h" +#include "nm-platform-utils.h" -#include "nm-test-utils.h" +#include "test-common.h" #define DEVICE_NAME "nm-test-device" @@ -178,7 +178,7 @@ test_ip4_route (void) /* Test route listing */ routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_IP_CONFIG_SOURCE_USER; + rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; rts[0].plen = 32; rts[0].ifindex = ifindex; @@ -186,7 +186,7 @@ test_ip4_route (void) rts[0].metric = metric; rts[0].mss = mss; rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK); - rts[1].source = NM_IP_CONFIG_SOURCE_USER; + rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; @@ -194,7 +194,7 @@ test_ip4_route (void) rts[1].metric = metric; rts[1].mss = mss; rts[1].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE); - rts[2].source = NM_IP_CONFIG_SOURCE_USER; + rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[2].network = 0; rts[2].plen = 0; rts[2].ifindex = ifindex; @@ -265,21 +265,21 @@ test_ip6_route (void) /* Test route listing */ routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); memset (rts, 0, sizeof (rts)); - rts[0].source = NM_IP_CONFIG_SOURCE_USER; + rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; rts[0].plen = 128; rts[0].ifindex = ifindex; rts[0].gateway = in6addr_any; rts[0].metric = nm_utils_ip6_route_metric_normalize (metric); rts[0].mss = mss; - rts[1].source = NM_IP_CONFIG_SOURCE_USER; + rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[1].network = network; rts[1].plen = plen; rts[1].ifindex = ifindex; rts[1].gateway = gateway; rts[1].metric = nm_utils_ip6_route_metric_normalize (metric); rts[1].mss = mss; - rts[2].source = NM_IP_CONFIG_SOURCE_USER; + rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[2].network = in6addr_any; rts[2].plen = 0; rts[2].ifindex = ifindex; diff --git a/src/platform/wifi/wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index 21a4c57b..ebe76f1b 100644 --- a/src/platform/wifi/wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -21,8 +21,6 @@ #ifndef __WIFI_UTILS_PRIVATE_H__ #define __WIFI_UTILS_PRIVATE_H__ - -#include "nm-default.h" #include "nm-dbus-interface.h" #include "wifi-utils.h" diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index 4f04041a..b7fe86bb 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -21,16 +21,18 @@ #include "nm-default.h" +#include "wifi-utils.h" + #include <sys/stat.h> #include <stdio.h> #include <string.h> -#include "wifi-utils.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" gpointer wifi_data_new (const char *iface, int ifindex, gsize len) @@ -178,19 +180,20 @@ wifi_utils_deinit (WifiData *data) } gboolean -wifi_utils_is_wifi (const char *iface, const char *sysfs_path) +wifi_utils_is_wifi (const char *iface) { - char phy80211_path[255]; + char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/]; struct stat s; g_return_val_if_fail (iface != NULL, FALSE); - if (sysfs_path) { - /* Check for nl80211 sysfs paths */ - g_snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path); - if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) - return TRUE; - } + nm_sprintf_buf (phy80211_path, + "/sys/class/net/%s/phy80211", + NM_ASSERT_VALID_PATH_COMPONENT (iface)); + nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1); + + if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + return TRUE; #if HAVE_WEXT if (wifi_wext_is_wifi (iface)) diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index 9555bbee..8e2b93f1 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -24,12 +24,11 @@ #include <net/ethernet.h> -#include "nm-default.h" #include "nm-dbus-interface.h" typedef struct WifiData WifiData; -gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path); +gboolean wifi_utils_is_wifi (const char *iface); WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); |