diff options
| author | Michael Biebl <biebl@debian.org> | 2016-03-30 00:56:30 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-03-30 00:56:30 +0200 |
| commit | d9c99a29a0d3384c9c3d2adce430f5cb1134ab6a (patch) | |
| tree | fa41baf72753961e71dd8d5bdbe2b89c9109e4f1 /src/platform/nm-platform.c | |
| parent | c2de0d98ba39e0a1a970d066fd19be786092f376 (diff) | |
Imported Upstream version 1.1.92 upstream/1.1.92
Diffstat (limited to 'src/platform/nm-platform.c')
| -rw-r--r-- | src/platform/nm-platform.c | 199 |
1 files changed, 164 insertions, 35 deletions
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index e3126442..d5ee48d4 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -41,6 +41,7 @@ #include "nm-enum-types.h" #include "nm-platform-utils.h" #include "nmp-object.h" +#include "nmp-netns.h" /*****************************************************************************/ @@ -48,8 +49,6 @@ const NMIPAddr nm_ip_addr_zero = NMIPAddrInit; /*****************************************************************************/ -#define ADDRESS_LIFETIME_PADDING 5 - G_STATIC_ASSERT (sizeof ( ((NMPlatformLink *) NULL)->addr.data ) == NM_UTILS_HWADDR_LEN_MAX); G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP4Address, address)); G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPAddress, address_ptr) == G_STRUCT_OFFSET (NMPlatformIP6Address, address)); @@ -89,6 +88,7 @@ static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = { 0 }; enum { PROP_0, + PROP_NETNS_SUPPORT, PROP_REGISTER_SINGLETON, LAST_PROP, }; @@ -666,6 +666,32 @@ nm_platform_link_delete (NMPlatform *self, int ifindex) } /** + * nm_platform_link_set_netns: + * @self: platform instance + * @ifindex: Interface index + * @netns_fd: the file descriptor for the new netns. + * + * Returns: %TRUE on success. + */ +gboolean +nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) +{ + const NMPlatformLink *pllink; + + _CHECK_SELF (self, klass, FALSE); + + g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail (netns_fd > 0, FALSE); + + pllink = nm_platform_link_get (self, ifindex); + if (!pllink) + return FALSE; + + _LOGD ("link: ifindex %d changing network namespace to %d", ifindex, netns_fd); + return klass->link_set_netns (self, ifindex, netns_fd); +} + +/** * nm_platform_link_get_index: * @self: platform instance * @name: Interface name @@ -1625,9 +1651,9 @@ link_option_path (NMPlatform *self, int master, const char *category, const char return NULL; return g_strdup_printf ("/sys/class/net/%s/%s/%s", - ASSERT_VALID_PATH_COMPONENT (name), - ASSERT_VALID_PATH_COMPONENT (category), - ASSERT_VALID_PATH_COMPONENT (option)); + NM_ASSERT_VALID_PATH_COMPONENT (name), + NM_ASSERT_VALID_PATH_COMPONENT (category), + NM_ASSERT_VALID_PATH_COMPONENT (option)); } static gboolean @@ -1916,7 +1942,7 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self, /* Could not get the link information via netlink. To support older kernels, * fallback to reading sysfs. */ - iface = ASSERT_VALID_PATH_COMPONENT (plink->name); + iface = NM_ASSERT_VALID_PATH_COMPONENT (plink->name); /* Fall back to reading sysfs */ path = g_strdup_printf ("/sys/class/net/%s/mode", iface); @@ -2128,6 +2154,10 @@ nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_pe /* Pre-4.1 kernel did not expose the peer_ifindex as IFA_LINK. Lookup via ethtool. */ if (out_peer_ifindex) { + nm_auto_pop_netns NMPNetns *netns = NULL; + + if (!nm_platform_netns_push (self, &netns)) + return FALSE; peer_ifindex = nmp_utils_ethtool_get_peer_ifindex (plink->name); if (peer_ifindex <= 0) return FALSE; @@ -2368,6 +2398,52 @@ _to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size) return buf; } +#define TO_STRING_IFA_FLAGS_BUF_SIZE 256 + +static const char * +_to_string_ifa_flags (guint32 ifa_flags, char *buf, gsize size) +{ +#define S_FLAGS_PREFIX " flags " + nm_assert (buf && size >= TO_STRING_IFA_FLAGS_BUF_SIZE && size > NM_STRLEN (S_FLAGS_PREFIX)); + + if (!ifa_flags) + buf[0] = '\0'; + else { + nm_platform_addr_flags2str (ifa_flags, &buf[NM_STRLEN (S_FLAGS_PREFIX)], size - NM_STRLEN (S_FLAGS_PREFIX)); + if (buf[NM_STRLEN (S_FLAGS_PREFIX)] == '\0') + buf[0] = '\0'; + else + memcpy (buf, S_FLAGS_PREFIX, NM_STRLEN (S_FLAGS_PREFIX)); + } + return buf; +} + +/******************************************************************/ + +gboolean +nm_platform_ethtool_set_wake_on_lan (NMPlatform *self, const char *ifname, NMSettingWiredWakeOnLan wol, const char *wol_password) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + _CHECK_SELF (self, klass, FALSE); + + if (!nm_platform_netns_push (self, &netns)) + return FALSE; + + return nmp_utils_ethtool_set_wake_on_lan (ifname, wol, wol_password); +} + +gboolean +nm_platform_ethtool_get_link_speed (NMPlatform *self, const char *ifname, guint32 *out_speed) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + _CHECK_SELF (self, klass, FALSE); + + if (!nm_platform_netns_push (self, &netns)) + return FALSE; + + return nmp_utils_ethtool_get_link_speed (ifname, out_speed); +} + /******************************************************************/ void @@ -2415,6 +2491,7 @@ nm_platform_ip4_address_add (NMPlatform *self, in_addr_t peer_address, guint32 lifetime, guint32 preferred, + guint32 flags, const char *label) { _CHECK_SELF (self, klass, FALSE); @@ -2435,12 +2512,13 @@ nm_platform_ip4_address_add (NMPlatform *self, addr.timestamp = 0; /* set it at zero, which to_string will treat as *now* */ addr.lifetime = lifetime; addr.preferred = preferred; + addr.n_ifa_flags = flags; if (label) g_strlcpy (addr.label, label, sizeof (addr.label)); _LOGD ("address: adding or updating IPv4 address: %s", nm_platform_ip4_address_to_string (&addr, NULL, 0)); } - return klass->ip4_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, label); + return klass->ip4_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, flags, label); } gboolean @@ -2535,7 +2613,7 @@ nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr addr } static gboolean -array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address *address, gint64 now, guint32 padding) +array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address *address, gint32 now) { guint len = addresses ? addresses->len : 0; guint i; @@ -2548,8 +2626,8 @@ array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address && ((candidate->peer_address ^ address->peer_address) & nm_utils_ip4_prefix_to_netmask (address->plen)) == 0) { guint32 lifetime, preferred; - if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, - now, padding, &lifetime, &preferred)) + if (nm_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, + now, &lifetime, &preferred)) return TRUE; } } @@ -2558,7 +2636,7 @@ array_contains_ip4_address (const GArray *addresses, const NMPlatformIP4Address } static gboolean -array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address *address, gint64 now, guint32 padding) +array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address *address, gint32 now) { guint len = addresses ? addresses->len : 0; guint i; @@ -2569,8 +2647,8 @@ array_contains_ip6_address (const GArray *addresses, const NMPlatformIP6Address if (IN6_ARE_ADDR_EQUAL (&candidate->address, &address->address) && candidate->plen == address->plen) { guint32 lifetime, preferred; - if (nmp_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, - now, padding, &lifetime, &preferred)) + if (nm_utils_lifetime_get (candidate->timestamp, candidate->lifetime, candidate->preferred, + now, &lifetime, &preferred)) return TRUE; } } @@ -2599,7 +2677,7 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known { GArray *addresses; NMPlatformIP4Address *address; - guint32 now = nm_utils_get_monotonic_timestamp_s (); + gint32 now = nm_utils_get_monotonic_timestamp_s (); int i; _CHECK_SELF (self, klass, FALSE); @@ -2609,7 +2687,7 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known for (i = 0; i < addresses->len; i++) { address = &g_array_index (addresses, NMPlatformIP4Address, i); - if (!array_contains_ip4_address (known_addresses, address, now, ADDRESS_LIFETIME_PADDING)) + if (!array_contains_ip4_address (known_addresses, address, now)) nm_platform_ip4_address_delete (self, ifindex, address->address, address->plen, address->peer_address); } g_array_free (addresses, TRUE); @@ -2625,11 +2703,13 @@ nm_platform_ip4_address_sync (NMPlatform *self, int ifindex, const GArray *known const NMPlatformIP4Address *known_address = &g_array_index (known_addresses, NMPlatformIP4Address, i); guint32 lifetime, preferred; - if (!nmp_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, ADDRESS_LIFETIME_PADDING, &lifetime, &preferred)) + if (!nm_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, + now, &lifetime, &preferred)) continue; - if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->plen, known_address->peer_address, lifetime, preferred, known_address->label)) + if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->plen, + known_address->peer_address, lifetime, preferred, + 0, known_address->label)) return FALSE; if (out_added_addresses) { @@ -2660,7 +2740,7 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known { GArray *addresses; NMPlatformIP6Address *address; - guint32 now = nm_utils_get_monotonic_timestamp_s (); + gint32 now = nm_utils_get_monotonic_timestamp_s (); int i; /* Delete unknown addresses */ @@ -2672,7 +2752,7 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known if (keep_link_local && IN6_IS_ADDR_LINKLOCAL (&address->address)) continue; - if (!array_contains_ip6_address (known_addresses, address, now, ADDRESS_LIFETIME_PADDING)) + if (!array_contains_ip6_address (known_addresses, address, now)) nm_platform_ip6_address_delete (self, ifindex, address->address, address->plen); } g_array_free (addresses, TRUE); @@ -2685,8 +2765,8 @@ nm_platform_ip6_address_sync (NMPlatform *self, int ifindex, const GArray *known const NMPlatformIP6Address *known_address = &g_array_index (known_addresses, NMPlatformIP6Address, i); guint32 lifetime, preferred; - if (!nmp_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, - now, ADDRESS_LIFETIME_PADDING, &lifetime, &preferred)) + if (!nm_utils_lifetime_get (known_address->timestamp, known_address->lifetime, known_address->preferred, + now, &lifetime, &preferred)) continue; if (!nm_platform_ip6_address_add (self, ifindex, known_address->address, @@ -2930,7 +3010,7 @@ _lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, return "forever"; g_snprintf (buf, buf_size, "%usec", - nmp_utils_lifetime_rebase_relative_time_on_now (timestamp, lifetime, now, 0)); + nm_utils_lifetime_rebase_relative_time_on_now (timestamp, lifetime, now)); return buf; } @@ -3025,7 +3105,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) str_flags->str, link->mtu, master, link->arptype, - str_if_set (str_link_type, "???"), + str_link_type ?: "???", 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", @@ -3346,6 +3426,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize const char * nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len) { + char s_flags[TO_STRING_IFA_FLAGS_BUF_SIZE]; char s_address[INET_ADDRSTRLEN]; char s_peer[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; @@ -3383,10 +3464,11 @@ nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *bu str_time_p = _lifetime_summary_to_string (now, address->timestamp, address->preferred, address->lifetime, str_time, sizeof (str_time)); g_snprintf (buf, len, - "%s/%d lft %s pref %s%s%s%s%s src %s", + "%s/%d lft %s pref %s%s%s%s%s%s src %s", s_address, address->plen, str_lft_p, str_pref_p, str_time_p, str_peer ? str_peer : "", str_dev, + _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), str_label, source_to_string (address->source)); g_free (str_peer); @@ -3457,8 +3539,7 @@ NM_UTILS_ENUM2STR_DEFINE (nm_platform_route_scope2str, int, const char * nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *buf, gsize len) { -#define S_FLAGS_PREFIX " flags " - char s_flags[256]; + 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]; @@ -3479,12 +3560,6 @@ 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->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, NM_STRLEN (S_FLAGS_PREFIX)); - str_lft_p = _lifetime_to_string (address->timestamp, address->lifetime ? address->lifetime : NM_PLATFORM_LIFETIME_PERMANENT, now, str_lft, sizeof (str_lft)), @@ -3500,7 +3575,7 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *bu s_address, address->plen, str_lft_p, str_pref_p, str_time_p, str_peer ? str_peer : "", str_dev, - s_flags, + _to_string_ifa_flags (address->n_ifa_flags, s_flags, sizeof (s_flags)), source_to_string (address->source)); g_free (str_peer); return buf; @@ -3825,6 +3900,7 @@ nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4A _CMP_FIELD (a, b, timestamp); _CMP_FIELD (a, b, lifetime); _CMP_FIELD (a, b, preferred); + _CMP_FIELD (a, b, n_ifa_flags); _CMP_FIELD_STR (a, b, label); return 0; } @@ -3980,6 +4056,31 @@ log_ip6_route (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatform /******************************************************************/ +NMPNetns * +nm_platform_netns_get (NMPlatform *self) +{ + _CHECK_SELF (self, klass, NULL); + + return self->_netns; +} + +gboolean +nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns) +{ + g_return_val_if_fail (NM_IS_PLATFORM (platform), FALSE); + + if ( platform->_netns + && !nmp_netns_push (platform->_netns)) { + NM_SET_OUT (netns, NULL); + return FALSE; + } + + NM_SET_OUT (netns, platform->_netns); + return TRUE; +} + +/******************************************************************/ + static gboolean _vtr_v4_route_add (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric) { @@ -4079,9 +4180,20 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (object); + NMPlatform *self = NM_PLATFORM (object); + NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE (self); switch (prop_id) { + case PROP_NETNS_SUPPORT: + /* construct-only */ + if (g_value_get_boolean (value)) { + NMPNetns *netns; + + netns = nmp_netns_get_current (); + if (netns) + self->_netns = g_object_ref (netns); + } + break; case PROP_REGISTER_SINGLETON: /* construct-only */ priv->register_singleton = g_value_get_boolean (value); @@ -4110,6 +4222,14 @@ nm_platform_init (NMPlatform *object) } static void +finalize (GObject *object) +{ + NMPlatform *self = NM_PLATFORM (object); + + g_clear_object (&self->_netns); +} + +static void nm_platform_class_init (NMPlatformClass *platform_class) { GObjectClass *object_class = G_OBJECT_CLASS (platform_class); @@ -4118,10 +4238,19 @@ nm_platform_class_init (NMPlatformClass *platform_class) object_class->set_property = set_property; object_class->constructed = constructed; + object_class->finalize = finalize; platform_class->wifi_set_powersave = wifi_set_powersave; g_object_class_install_property + (object_class, PROP_NETNS_SUPPORT, + g_param_spec_boolean (NM_PLATFORM_NETNS_SUPPORT, "", "", + FALSE, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, PROP_REGISTER_SINGLETON, g_param_spec_boolean (NM_PLATFORM_REGISTER_SINGLETON, "", "", FALSE, |