diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2019-01-25 11:26:25 +0100 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2019-01-25 11:26:25 +0100 |
| commit | f54a568880bf47c2ea54c9b30d291156b34d6539 (patch) | |
| tree | aab9bb44b306da7651e8caf38bbab5cfeeb81b7d /src/platform | |
| parent | e8ac7dacdcf4b38addef4f8ac6ab038f9d29582c (diff) | |
| parent | bbae86d3d2997a853ca0365e8eb7a3ca7489ee09 (diff) | |
Update upstream source from tag 'upstream/1.15.2'
Update to upstream version '1.15.2' with Debian dir b4be4b7cfce96679a31cb9d423107789761e3b49
Diffstat (limited to 'src/platform')
| -rw-r--r-- | src/platform/nm-fake-platform.c | 33 | ||||
| -rw-r--r-- | src/platform/nm-linux-platform.c | 644 | ||||
| -rw-r--r-- | src/platform/nm-netlink.c | 262 | ||||
| -rw-r--r-- | src/platform/nm-netlink.h | 83 | ||||
| -rw-r--r-- | src/platform/nm-platform-utils.c | 12 | ||||
| -rw-r--r-- | src/platform/nm-platform.c | 1130 | ||||
| -rw-r--r-- | src/platform/nm-platform.h | 333 | ||||
| -rw-r--r-- | src/platform/nmp-object.c | 253 | ||||
| -rw-r--r-- | src/platform/nmp-object.h | 48 | ||||
| -rw-r--r-- | src/platform/tests/meson.build | 2 | ||||
| -rw-r--r-- | src/platform/tests/test-address.c | 2 | ||||
| -rw-r--r-- | src/platform/tests/test-cleanup.c | 5 | ||||
| -rw-r--r-- | src/platform/tests/test-common.c | 115 | ||||
| -rw-r--r-- | src/platform/tests/test-common.h | 18 | ||||
| -rw-r--r-- | src/platform/tests/test-link.c | 354 | ||||
| -rw-r--r-- | src/platform/tests/test-route.c | 14 | ||||
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils-nl80211.c | 197 | ||||
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils-wext.c | 6 | ||||
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils.h | 2 | ||||
| -rw-r--r-- | src/platform/wpan/nm-wpan-utils.c | 71 | ||||
| -rw-r--r-- | src/platform/wpan/nm-wpan-utils.h | 2 |
21 files changed, 2214 insertions, 1372 deletions
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 82f9e2fb..814d9cea 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -26,6 +26,7 @@ #include <unistd.h> #include <netinet/icmp6.h> #include <netinet/in.h> +#include <linux/if.h> #include <linux/rtnetlink.h> #include "nm-utils.h" @@ -194,7 +195,7 @@ link_add_prepare (NMPlatform *platform, { gboolean connected; - /* we must clear the driver, because platform cache want's to set it */ + /* we must clear the driver, because platform cache wants to set it */ g_assert (obj_tmp->link.driver == g_intern_string (obj_tmp->link.driver)); obj_tmp->link.driver = NULL; @@ -282,7 +283,7 @@ link_add_pre (NMPlatform *platform, return device; } -static gboolean +static int link_add (NMPlatform *platform, const char *name, NMLinkType type, @@ -334,7 +335,7 @@ link_add (NMPlatform *platform, if (veth_peer) link_changed (platform, device_veth, cache_op_veth, NULL); - return TRUE; + return 0; } static NMFakePlatformLink * @@ -562,7 +563,7 @@ link_set_noarp (NMPlatform *platform, int ifindex) return TRUE; } -static NMPlatformError +static int link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t len) { NMFakePlatformLink *device = link_get (platform, ifindex); @@ -571,10 +572,10 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t if ( len == 0 || len > NM_UTILS_HWADDR_LEN_MAX || !addr) - g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + g_return_val_if_reached (-NME_BUG); if (!device) - return NM_PLATFORM_ERROR_EXISTS; + return -NME_PL_EXISTS; obj_tmp = nmp_object_clone (device->obj, FALSE); obj_tmp->link.addr.len = len; @@ -582,10 +583,10 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer addr, size_t memcpy (obj_tmp->link.addr.data, addr, len); link_set_obj (platform, device, obj_tmp); - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } -static NMPlatformError +static int link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) { NMFakePlatformLink *device = link_get (platform, ifindex); @@ -593,13 +594,13 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) if (!device) { _LOGE ("failure changing link: netlink error (No such device)"); - return NM_PLATFORM_ERROR_EXISTS; + return -NME_PL_EXISTS; } obj_tmp = nmp_object_clone (device->obj, FALSE); obj_tmp->link.mtu = mtu; link_set_obj (platform, device, obj_tmp); - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } static const char * @@ -1186,7 +1187,7 @@ object_delete (NMPlatform *platform, const NMPObject *obj) return ipx_route_delete (platform, AF_UNSPEC, -1, obj); } -static NMPlatformError +static int ip_route_add (NMPlatform *platform, NMPNlmFlags flags, int addr_family, @@ -1266,14 +1267,16 @@ ip_route_add (NMPlatform *platform, } } if (!has_route_to_gw) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + if (addr_family == AF_INET) { nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip4-route '%d: %s/%d %d': Network Unreachable", - r->ifindex, nm_utils_inet4_ntop (r4->network, NULL), r->plen, r->metric); + r->ifindex, nm_utils_inet4_ntop (r4->network, sbuf), r->plen, r->metric); } else { nm_log_warn (LOGD_PLATFORM, "Fake platform: failure adding ip6-route '%d: %s/%d %d': Network Unreachable", - r->ifindex, nm_utils_inet6_ntop (&r6->network, NULL), r->plen, r->metric); + r->ifindex, nm_utils_inet6_ntop (&r6->network, sbuf), r->plen, r->metric); } - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; } } @@ -1335,7 +1338,7 @@ ip_route_add (NMPlatform *platform, } } - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } /*****************************************************************************/ diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e73d5d8c..85214ec8 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -44,6 +44,7 @@ #include "nm-core-internal.h" #include "nm-setting-vlan.h" +#include "nm-utils/nm-errno.h" #include "nm-utils/nm-secret-utils.h" #include "nm-netlink.h" #include "nm-core-utils.h" @@ -186,6 +187,12 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1)); #define WG_CMD_GET_DEVICE 0 #define WG_CMD_SET_DEVICE 1 +#define WGDEVICE_F_REPLACE_PEERS ((guint32) (1U << 0)) + +#define WGPEER_F_REMOVE_ME ((guint32) (1U << 0)) +#define WGPEER_F_REPLACE_ALLOWEDIPS ((guint32) (1U << 1)) + + #define WGDEVICE_A_UNSPEC 0 #define WGDEVICE_A_IFINDEX 1 #define WGDEVICE_A_IFNAME 2 @@ -447,7 +454,7 @@ G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) if (nm_logging_enabled (__level, __domain)) { \ int __errsv = (errsv); \ \ - /* The %m format specifier (GNU extension) would alread allow you to specify the error + /* The %m format specifier (GNU extension) would already allow you to specify the error * message conveniently (and nm_log would get that right too). But we don't want to depend * on that, so instead append the message at the end. * Currently users are expected not to use %m in the format string. */ \ @@ -474,14 +481,14 @@ static struct nl_sock *_genl_sock (NMLinuxPlatform *platform); /*****************************************************************************/ -static NMPlatformError -wait_for_nl_response_to_plerr (WaitForNlResponseResult seq_result) +static int +wait_for_nl_response_to_nmerr (WaitForNlResponseResult seq_result) { if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) - return NM_PLATFORM_ERROR_SUCCESS; + return 0; if (seq_result < 0) - return (NMPlatformError) seq_result; - return NM_PLATFORM_ERROR_NETLINK; + return (int) seq_result; + return -NME_PL_NETLINK; } static const char * @@ -1942,9 +1949,10 @@ _wireguard_update_from_allowed_ips_nla (NMPWireGuardAllowedIP *allowed_ip, _check_addr_or_return_val (tb, WGALLOWEDIP_A_IPADDR, addr_len, FALSE); - memset (allowed_ip, 0, sizeof (NMPWireGuardAllowedIP)); + *allowed_ip = (NMPWireGuardAllowedIP) { + .family = family, + }; - allowed_ip->family = family; nm_assert ((int) allowed_ip->family == family); if (tb[WGALLOWEDIP_A_IPADDR]) @@ -2006,30 +2014,11 @@ _wireguard_update_from_peers_nla (CList *peers, nm_explicit_bzero (nla_data (tb[WGPEER_A_PRESHARED_KEY]), nla_len (tb[WGPEER_A_PRESHARED_KEY])); } - if (tb[WGPEER_A_ENDPOINT]) { - const struct sockaddr *addr = nla_data (tb[WGPEER_A_ENDPOINT]); - unsigned short family; - - G_STATIC_ASSERT (sizeof (addr->sa_family) == sizeof (family)); - memcpy (&family, &addr->sa_family, sizeof (addr->sa_family)); - - if ( family == AF_INET - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in)) { - const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr; - - peer_c->data.endpoint_family = AF_INET; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr4->sin_port); - peer_c->data.endpoint_addr.addr4 = unaligned_read_ne32 (&addr4->sin_addr.s_addr); - memcpy (&peer_c->data.endpoint_addr.addr4, &addr4->sin_addr.s_addr, 4); - } else if ( family == AF_INET6 - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in6)) { - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr; - - peer_c->data.endpoint_family = AF_INET6; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr6->sin6_port); - memcpy (&peer_c->data.endpoint_addr.addr6, &addr6->sin6_addr, 16); - } - } + + nm_sock_addr_union_cpy_untrusted (&peer_c->data.endpoint, + tb[WGPEER_A_ENDPOINT] ? nla_data (tb[WGPEER_A_ENDPOINT]) : NULL, + tb[WGPEER_A_ENDPOINT] ? nla_len (tb[WGPEER_A_ENDPOINT]) : 0); + if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); if (tb[WGPEER_A_LAST_HANDSHAKE_TIME]) @@ -2157,9 +2146,9 @@ _wireguard_get_device_cb (struct nl_msg *msg, void *arg) static const NMPObject * _wireguard_read_info (NMPlatform *platform /* used only as logging context */, - struct nl_sock *genl, - int wireguard_family_id, - int ifindex) + struct nl_sock *genl, + int wireguard_family_id, + int ifindex) { nm_auto_nlmsg struct nl_msg *msg = NULL; NMPObject *obj = NULL; @@ -2175,6 +2164,8 @@ _wireguard_read_info (NMPlatform *platform /* used only as logging context */, nm_assert (wireguard_family_id >= 0); nm_assert (ifindex > 0); + _LOGT ("wireguard: fetching infomation for ifindex %d (genl-id %d)...", ifindex, wireguard_family_id); + msg = nlmsg_alloc (); if (!genlmsg_put (msg, @@ -2227,7 +2218,7 @@ _wireguard_read_info (NMPlatform *platform /* used only as logging context */, * there. The realloc/resize of the GArray is fine there. However, * while we build the GArray, we don't yet have the final pointers. * Hence, while constructing, we track the indexes with peer->_construct_idx_* - * fields. These indexes must be convered to actual pointers blow. + * fields. These indexes must be converted to actual pointers blow. * * This is all done during parsing. In the final NMPObjectLnkWireGuard we * don't want the CList anymore and repackage the NMPObject tightly. The @@ -2283,6 +2274,336 @@ nla_put_failure: g_return_val_if_reached (NULL); } +static int +_wireguard_get_family_id (NMPlatform *platform, int ifindex_try) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + int wireguard_family_id = -1; + + if (ifindex_try > 0) { + const NMPlatformLink *plink; + + if (nm_platform_link_get_lnk_wireguard (platform, ifindex_try, &plink)) + wireguard_family_id = NMP_OBJECT_UP_CAST (plink)->_link.wireguard_family_id; + } + if (wireguard_family_id < 0) + wireguard_family_id = genl_ctrl_resolve (priv->genl, "wireguard"); + return wireguard_family_id; +} + +static const NMPObject * +_wireguard_refresh_link (NMPlatform *platform, + int wireguard_family_id, + int ifindex) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + nm_auto_nmpobj const NMPObject *obj_old = NULL; + nm_auto_nmpobj const NMPObject *obj_new = NULL; + nm_auto_nmpobj const NMPObject *lnk_new = NULL; + NMPCacheOpsType cache_op; + const NMPObject *plink = NULL; + nm_auto_nmpobj NMPObject *obj = NULL; + + nm_assert (wireguard_family_id >= 0); + nm_assert (ifindex > 0); + + nm_platform_process_events (platform); + + plink = nm_platform_link_get_obj (platform, ifindex, TRUE); + + if ( !plink + || plink->link.type != NM_LINK_TYPE_WIREGUARD) { + nm_platform_link_refresh (platform, ifindex); + plink = nm_platform_link_get_obj (platform, ifindex, TRUE); + if ( !plink + || plink->link.type != NM_LINK_TYPE_WIREGUARD) + return NULL; + if (NMP_OBJECT_GET_TYPE (plink->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_WIREGUARD) + lnk_new = nmp_object_ref (plink->_link.netlink.lnk); + } else { + lnk_new = _wireguard_read_info (platform, + priv->genl, + wireguard_family_id, + ifindex); + if (!lnk_new) { + if (NMP_OBJECT_GET_TYPE (plink->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_WIREGUARD) + lnk_new = nmp_object_ref (plink->_link.netlink.lnk); + } else if (nmp_object_equal (plink->_link.netlink.lnk, lnk_new)) { + nmp_object_unref (lnk_new); + lnk_new = nmp_object_ref (plink->_link.netlink.lnk); + } + } + + if ( plink->_link.wireguard_family_id == wireguard_family_id + && plink->_link.netlink.lnk == lnk_new) + return plink; + + /* we use nmp_cache_update_netlink() to re-inject the new object into the cache. + * For that, we need to clone it, and tweak it so that it's suitable. It's a bit + * of a hack, in particular that we need to clear driver and udev-device. */ + obj = nmp_object_clone (plink, FALSE); + obj->_link.wireguard_family_id = wireguard_family_id; + nmp_object_unref (obj->_link.netlink.lnk); + obj->_link.netlink.lnk = g_steal_pointer (&lnk_new); + obj->link.driver = NULL; + nm_clear_pointer (&obj->_link.udev.device, udev_device_unref); + + cache_op = nmp_cache_update_netlink (nm_platform_get_cache (platform), + obj, + FALSE, + &obj_old, + &obj_new); + nm_assert (NM_IN_SET (cache_op, NMP_CACHE_OPS_UPDATED)); + if (cache_op != NMP_CACHE_OPS_UNCHANGED) { + cache_on_change (platform, cache_op, obj_old, obj_new); + nm_platform_cache_update_emit_signal (platform, cache_op, obj_old, obj_new); + } + + nm_assert ( !obj_new + || ( NMP_OBJECT_GET_TYPE (obj_new) == NMP_OBJECT_TYPE_LINK + && obj_new->link.type == NM_LINK_TYPE_WIREGUARD + && ( !obj_new->_link.netlink.lnk + || NMP_OBJECT_GET_TYPE (obj_new->_link.netlink.lnk) == NMP_OBJECT_TYPE_LNK_WIREGUARD))); + return obj_new; +} + +static int +_wireguard_create_change_nlmsgs (NMPlatform *platform, + int ifindex, + int wireguard_family_id, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, + guint peers_len, + gboolean replace_peers, + GPtrArray **out_msgs) +{ + gs_unref_ptrarray GPtrArray *msgs = NULL; + nm_auto_nlmsg struct nl_msg *msg = NULL; + const guint IDX_NIL = G_MAXUINT; + guint idx_peer_curr; + guint idx_allowed_ips_curr; + struct nlattr *nest_peers; + struct nlattr *nest_curr_peer; + struct nlattr *nest_allowed_ips; + struct nlattr *nest_curr_allowed_ip; + +#define _nla_nest_end(msg, nest_start) \ + G_STMT_START { \ + if (nla_nest_end ((msg), (nest_start)) < 0) \ + g_return_val_if_reached (-NME_BUG); \ + } G_STMT_END + + /* Adapted from LGPL-2.1+ code [1]. + * + * [1] https://git.zx2c4.com/WireGuard/tree/contrib/examples/embeddable-wg-library/wireguard.c?id=5e99a6d43fe2351adf36c786f5ea2086a8fe7ab8#n1073 */ + + idx_peer_curr = IDX_NIL; + idx_allowed_ips_curr = IDX_NIL; + + /* TODO: for the moment, we always reset all peers and allowed-ips (WGDEVICE_F_REPLACE_PEERS, WGPEER_F_REPLACE_ALLOWEDIPS). + * The platform API should be extended to also support partial updates. In particular, configuring the same configuration + * multiple times, should not clear and re-add all settings, but rather sync the existing settings with the desired configuration. */ + +again: + + msg = nlmsg_alloc (); + if (!genlmsg_put (msg, + NL_AUTO_PORT, + NL_AUTO_SEQ, + wireguard_family_id, + 0, + NLM_F_REQUEST, + WG_CMD_SET_DEVICE, + 1)) + g_return_val_if_reached (-NME_BUG); + + NLA_PUT_U32 (msg, WGDEVICE_A_IFINDEX, (guint32) ifindex); + + if (idx_peer_curr == IDX_NIL) { + NLA_PUT (msg, WGDEVICE_A_PRIVATE_KEY, sizeof (lnk_wireguard->private_key), lnk_wireguard->private_key); + NLA_PUT_U16 (msg, WGDEVICE_A_LISTEN_PORT, lnk_wireguard->listen_port); + NLA_PUT_U32 (msg, WGDEVICE_A_FWMARK, lnk_wireguard->fwmark); + + NLA_PUT_U32 (msg, WGDEVICE_A_FLAGS, + replace_peers ? WGDEVICE_F_REPLACE_PEERS : ((guint32) 0u)); + } + + if (peers_len == 0) + goto send; + + nest_curr_peer = NULL; + nest_allowed_ips = NULL; + nest_curr_allowed_ip = NULL; + + nest_peers = nla_nest_start (msg, WGDEVICE_A_PEERS); + if (!nest_peers) + g_return_val_if_reached (-NME_BUG); + + if (idx_peer_curr == IDX_NIL) + idx_peer_curr = 0; + for (; idx_peer_curr < peers_len; idx_peer_curr++) { + const NMPWireGuardPeer *p = &peers[idx_peer_curr]; + + nest_curr_peer = nla_nest_start (msg, 0); + if (!nest_curr_peer) + goto toobig_peers; + + if (nla_put (msg, WGPEER_A_PUBLIC_KEY, NMP_WIREGUARD_PUBLIC_KEY_LEN, p->public_key) < 0) + goto toobig_peers; + + if (idx_allowed_ips_curr == IDX_NIL) { + + if (nla_put (msg, WGPEER_A_PRESHARED_KEY, sizeof (p->preshared_key), p->preshared_key) < 0) + goto toobig_peers; + + if (nla_put_uint16 (msg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, p->persistent_keepalive_interval) < 0) + goto toobig_peers; + + if (nla_put_uint32 (msg, WGPEER_A_FLAGS, WGPEER_F_REPLACE_ALLOWEDIPS) < 0) + goto toobig_peers; + + if (NM_IN_SET (p->endpoint.sa.sa_family, AF_INET, AF_INET6)) { + if (nla_put (msg, + WGPEER_A_ENDPOINT, + p->endpoint.sa.sa_family == AF_INET + ? sizeof (p->endpoint.in) + : sizeof (p->endpoint.in6), + &p->endpoint) < 0) + goto toobig_peers; + } else + nm_assert (p->endpoint.sa.sa_family == AF_UNSPEC); + } + + if (p->allowed_ips_len > 0) { + if (idx_allowed_ips_curr == IDX_NIL) + idx_allowed_ips_curr = 0; + + nest_allowed_ips = nla_nest_start (msg, WGPEER_A_ALLOWEDIPS); + if (!nest_allowed_ips) + goto toobig_allowedips; + + for (; idx_allowed_ips_curr < p->allowed_ips_len; idx_allowed_ips_curr++) { + const NMPWireGuardAllowedIP *aip = &p->allowed_ips[idx_allowed_ips_curr]; + + nest_curr_allowed_ip = nla_nest_start (msg, 0); + if (!nest_curr_allowed_ip) + goto toobig_allowedips; + + g_return_val_if_fail (NM_IN_SET (aip->family, AF_INET, AF_INET6), -NME_BUG); + + if (nla_put_uint16 (msg, WGALLOWEDIP_A_FAMILY, aip->family) < 0) + goto toobig_allowedips; + if (nla_put (msg, + WGALLOWEDIP_A_IPADDR, + nm_utils_addr_family_to_size (aip->family), + &aip->addr) < 0) + goto toobig_allowedips; + if (nla_put_uint8 (msg, WGALLOWEDIP_A_CIDR_MASK, aip->mask) < 0) + goto toobig_allowedips; + + _nla_nest_end (msg, nest_curr_allowed_ip); + nest_curr_allowed_ip = NULL; + } + idx_allowed_ips_curr = IDX_NIL; + + _nla_nest_end (msg, nest_allowed_ips); + nest_allowed_ips = NULL; + } + + _nla_nest_end (msg, nest_curr_peer); + nest_curr_peer = NULL; + } + + _nla_nest_end (msg, nest_peers); + goto send; + +toobig_allowedips: + if (nest_curr_allowed_ip) + nla_nest_cancel (msg, nest_curr_allowed_ip); + if (nest_allowed_ips) + nla_nest_cancel (msg, nest_allowed_ips); + _nla_nest_end (msg, nest_curr_peer); + _nla_nest_end (msg, nest_peers); + goto send; + +toobig_peers: + if (nest_curr_peer) + nla_nest_cancel (msg, nest_curr_peer); + _nla_nest_end (msg, nest_peers); + goto send; + +send: + if (!msgs) + msgs = g_ptr_array_new_with_free_func ((GDestroyNotify) nlmsg_free); + g_ptr_array_add (msgs, g_steal_pointer (&msg)); + + if ( idx_peer_curr != IDX_NIL + && idx_peer_curr < peers_len) + goto again; + + NM_SET_OUT (out_msgs, g_steal_pointer (&msgs)); + return 0; + +nla_put_failure: + g_return_val_if_reached (-NME_BUG); + +#undef _nla_nest_end +} + +static int +link_wireguard_change (NMPlatform *platform, + int ifindex, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, + guint peers_len, + gboolean replace_peers) +{ + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + gs_unref_ptrarray GPtrArray *msgs = NULL; + int wireguard_family_id; + guint i; + int r; + + wireguard_family_id = _wireguard_get_family_id (platform, ifindex); + if (wireguard_family_id < 0) + return -NME_PL_NO_FIRMWARE; + + r = _wireguard_create_change_nlmsgs (platform, + ifindex, + wireguard_family_id, + lnk_wireguard, + peers, + peers_len, + replace_peers, + &msgs); + if (r < 0) { + _LOGW ("wireguard: set-device, cannot construct netlink message: %s", nm_strerror (r)); + return r; + } + + for (i = 0; i < msgs->len; i++) { + r = nl_send_auto (priv->genl, msgs->pdata[i]); + if (r < 0) { + _LOGW ("wireguard: set-device, send netlink message #%u failed: %s", i, nm_strerror (r)); + return r; + } + + do { + r = nl_recvmsgs (priv->genl, NULL); + } while (r == -EAGAIN); + if (r < 0) { + _LOGW ("wireguard: set-device, message #%u was rejected: %s", i, nm_strerror (r)); + return r; + } + + _LOGT ("wireguard: set-device, message #%u sent and confirmed", i); + } + + _wireguard_refresh_link (platform, wireguard_family_id, ifindex); + + return 0; +} + /*****************************************************************************/ /* Copied and heavily modified from libnl3's link_msg_parser(). */ @@ -4745,7 +5066,7 @@ _nl_send_nlmsg (NMPlatform *platform, nle = nl_send_auto (priv->nlh, nlmsg); if (nle < 0) { - _LOGD ("netlink: nl-send-nlmsg: failed sending message: %s (%d)", nl_geterror (nle), nle); + _LOGD ("netlink: nl-send-nlmsg: failed sending message: %s (%d)", nm_strerror (nle), nle); return nle; } @@ -4791,7 +5112,7 @@ do_request_link_no_delayed_actions (NMPlatform *platform, int ifindex, const cha if (nle < 0) { _LOGE ("do-request-link: %d %s: failed sending netlink request \"%s\" (%d)", ifindex, name ?: "", - nl_geterror (nle), -nle); + nm_strerror (nle), -nle); return; } } @@ -5121,7 +5442,7 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event /*****************************************************************************/ -static gboolean +static int do_add_link_with_lookup (NMPlatform *platform, NMLinkType link_type, const char *name, @@ -5142,9 +5463,9 @@ do_add_link_with_lookup (NMPlatform *platform, _LOGE ("do-add-link[%s/%s]: failed sending netlink request \"%s\" (%d)", name, nm_link_type_to_string (link_type), - nl_geterror (nle), -nle); + nm_strerror (nle), -nle); NM_SET_OUT (out_link, NULL); - return FALSE; + return nle; } delayed_action_handle_all (platform, FALSE); @@ -5164,10 +5485,10 @@ do_add_link_with_lookup (NMPlatform *platform, *out_link = NMP_OBJECT_CAST_LINK (obj); } - return seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK; + return wait_for_nl_response_to_nmerr (seq_result); } -static NMPlatformError +static int do_add_addrroute (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg *nlmsg, @@ -5189,8 +5510,8 @@ do_add_addrroute (NMPlatform *platform, _LOGE ("do-add-%s[%s]: failure sending netlink request \"%s\" (%d)", NMP_OBJECT_GET_CLASS (obj_id)->obj_type_name, nmp_object_to_string (obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), - nl_geterror (nle), -nle); - return NM_PLATFORM_ERROR_NETLINK; + nm_strerror (nle), -nle); + return -NME_PL_NETLINK; } delayed_action_handle_all (platform, FALSE); @@ -5219,7 +5540,7 @@ do_add_addrroute (NMPlatform *platform, do_request_one_type (platform, NMP_OBJECT_GET_TYPE (obj_id)); } - return wait_for_nl_response_to_plerr (seq_result); + return wait_for_nl_response_to_nmerr (seq_result); } static gboolean @@ -5239,7 +5560,7 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * _LOGE ("do-delete-%s[%s]: failure sending netlink request \"%s\" (%d)", NMP_OBJECT_GET_CLASS (obj_id)->obj_type_name, nmp_object_to_string (obj_id, NMP_OBJECT_TO_STRING_ID, NULL, 0), - nl_geterror (nle), -nle); + nm_strerror (nle), -nle); return FALSE; } @@ -5287,7 +5608,7 @@ do_delete_object (NMPlatform *platform, const NMPObject *obj_id, struct nl_msg * return success; } -static NMPlatformError +static int do_change_link (NMPlatform *platform, ChangeLinkType change_link_type, int ifindex, @@ -5299,7 +5620,7 @@ do_change_link (NMPlatform *platform, WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; gs_free char *errmsg = NULL; char s_buf[256]; - NMPlatformError result = NM_PLATFORM_ERROR_SUCCESS; + int result = 0; NMLogLevel log_level = LOGL_DEBUG; const char *log_result = "failure"; const char *log_detail = ""; @@ -5317,7 +5638,7 @@ retry: if (nle < 0) { log_level = LOGL_ERR; log_detail_free = g_strdup_printf (", failure sending netlink request: %s (%d)", - nl_geterror (nle), -nle); + nm_strerror (nle), -nle); log_detail = log_detail_free; goto out; } @@ -5342,11 +5663,11 @@ retry: /* */ } else if (NM_IN_SET (-((int) seq_result), ESRCH, ENOENT)) { log_detail = ", firmware not found"; - result = NM_PLATFORM_ERROR_NO_FIRMWARE; + result = -NME_PL_NO_FIRMWARE; } else if ( NM_IN_SET (-((int) seq_result), ERANGE) && change_link_type == CHANGE_LINK_TYPE_SET_MTU) { log_detail = ", setting MTU to requested size is not possible"; - result = NM_PLATFORM_ERROR_CANT_SET_MTU; + result = -NME_PL_CANT_SET_MTU; } else if ( NM_IN_SET (-((int) seq_result), ENFILE) && change_link_type == CHANGE_LINK_TYPE_SET_ADDRESS && (obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex)) @@ -5356,16 +5677,16 @@ retry: * If the MAC address is as expected, assume success? */ log_result = "success"; log_detail = " (assume success changing address)"; - result = NM_PLATFORM_ERROR_SUCCESS; + result = 0; } else if (NM_IN_SET (-((int) seq_result), ENODEV)) { log_level = LOGL_DEBUG; - result = NM_PLATFORM_ERROR_NOT_FOUND; + result = -NME_PL_NOT_FOUND; } else if (-((int) seq_result) == EAFNOSUPPORT) { log_level = LOGL_DEBUG; - result = NM_PLATFORM_ERROR_OPNOTSUPP; + result = -NME_PL_OPNOTSUPP; } else { log_level = LOGL_WARN; - result = NM_PLATFORM_ERROR_UNSPECIFIED; + result = -NME_UNSPEC; } out: @@ -5378,7 +5699,7 @@ out: return result; } -static gboolean +static int link_add (NMPlatform *platform, const char *name, NMLinkType type, @@ -5408,17 +5729,17 @@ link_add (NMPlatform *platform, 0, 0); if (!nlmsg) - return FALSE; + return -NME_UNSPEC; if (address && address_len) NLA_PUT (nlmsg, IFLA_ADDRESS, address_len, address); if (!_nl_msg_new_link_set_linkinfo (nlmsg, type, veth_peer)) - return FALSE; + return -NME_UNSPEC; return do_add_link_with_lookup (platform, type, name, nlmsg, out_link); nla_put_failure: - g_return_val_if_reached (FALSE); + g_return_val_if_reached (-NME_BUG); } static gboolean @@ -5473,13 +5794,13 @@ link_set_netns (NMPlatform *platform, return FALSE; NLA_PUT (nlmsg, IFLA_NET_NS_FD, 4, &netns_fd); - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } -static NMPlatformError +static int link_change_flags (NMPlatform *platform, int ifindex, unsigned flags_mask, @@ -5502,37 +5823,36 @@ link_change_flags (NMPlatform *platform, flags_mask, flags_set); if (!nlmsg) - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL); } static gboolean link_set_up (NMPlatform *platform, int ifindex, gboolean *out_no_firmware) { - NMPlatformError plerr; + int r; - plerr = link_change_flags (platform, ifindex, IFF_UP, IFF_UP); - if (out_no_firmware) - *out_no_firmware = plerr == NM_PLATFORM_ERROR_NO_FIRMWARE; - return plerr == NM_PLATFORM_ERROR_SUCCESS; + r = link_change_flags (platform, ifindex, IFF_UP, IFF_UP); + NM_SET_OUT (out_no_firmware, (r == -NME_PL_NO_FIRMWARE)); + return r >= 0; } static gboolean link_set_down (NMPlatform *platform, int ifindex) { - return link_change_flags (platform, ifindex, IFF_UP, 0) == NM_PLATFORM_ERROR_SUCCESS; + return (link_change_flags (platform, ifindex, IFF_UP, 0) >= 0); } static gboolean link_set_arp (NMPlatform *platform, int ifindex) { - return link_change_flags (platform, ifindex, IFF_NOARP, 0) == NM_PLATFORM_ERROR_SUCCESS; + return (link_change_flags (platform, ifindex, IFF_NOARP, 0) >= 0); } static gboolean link_set_noarp (NMPlatform *platform, int ifindex) { - return link_change_flags (platform, ifindex, IFF_NOARP, IFF_NOARP) == NM_PLATFORM_ERROR_SUCCESS; + return (link_change_flags (platform, ifindex, IFF_NOARP, IFF_NOARP) >= 0); } static const char * @@ -5547,7 +5867,7 @@ link_get_udi (NMPlatform *platform, int ifindex) return udev_device_get_syspath (obj->_link.udev.device); } -static NMPlatformError +static int link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enabled) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5559,7 +5879,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 NM_PLATFORM_ERROR_OPNOTSUPP; + return -NME_PL_OPNOTSUPP; } nlmsg = _nl_msg_new_link (RTM_NEWLINK, @@ -5570,7 +5890,7 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable 0); if ( !nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) - g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + g_return_val_if_reached (-NME_BUG); return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL); } @@ -5579,15 +5899,16 @@ static gboolean link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; _LOGD ("link: change %d: token: set IPv6 address generation token to %s", - ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL)); + ifindex, nm_utils_inet6_interface_identifier_to_token (iid, sbuf)); 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, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); } static gboolean @@ -5647,7 +5968,7 @@ link_supports_sriov (NMPlatform *platform, int ifindex) return total > 0; } -static NMPlatformError +static int link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5659,7 +5980,7 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size }; if (!address || !length) - g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + g_return_val_if_reached (-NME_BUG); nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, @@ -5668,16 +5989,16 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size 0, 0); if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); + g_return_val_if_reached (-NME_BUG); NLA_PUT (nlmsg, IFLA_ADDRESS, length, address); return do_change_link (platform, CHANGE_LINK_TYPE_SET_ADDRESS, ifindex, nlmsg, &d); nla_put_failure: - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); + g_return_val_if_reached (-NME_BUG); } -static NMPlatformError +static int link_set_name (NMPlatform *platform, int ifindex, const char *name) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5689,11 +6010,11 @@ link_set_name (NMPlatform *platform, int ifindex, const char *name) 0, 0); if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); + g_return_val_if_reached (-NME_BUG); NLA_PUT (nlmsg, IFLA_IFNAME, strlen (name) + 1, name); - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -5712,7 +6033,7 @@ link_get_permanent_address (NMPlatform *platform, return nmp_utils_ethtool_get_permanent_address (ifindex, buf, length); } -static NMPlatformError +static int link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; @@ -5737,12 +6058,13 @@ static gboolean link_set_sriov_params (NMPlatform *platform, int ifindex, guint num_vfs, - int autoprobe) + NMTernary autoprobe) { nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_close int dirfd = -1; - gboolean current_autoprobe; - guint total, current_num; + int current_autoprobe; + guint total; + gint64 current_num; char ifname[IFNAMSIZ]; char buf[64]; @@ -5775,14 +6097,14 @@ link_set_sriov_params (NMPlatform *platform, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), - 10, 0, G_MAXUINT, 0); + 10, 0, G_MAXUINT, -1); current_autoprobe = nm_platform_sysctl_get_int_checked (platform, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_drivers_autoprobe"), - 10, 0, G_MAXUINT, 0); + 10, 0, 1, -1); if ( current_num == num_vfs - && (autoprobe == -1 || current_autoprobe == autoprobe)) + && (autoprobe == NM_TERNARY_DEFAULT || current_autoprobe == autoprobe)) return TRUE; if (current_num != 0) { @@ -5800,14 +6122,14 @@ link_set_sriov_params (NMPlatform *platform, if (num_vfs == 0) return TRUE; - if ( autoprobe >= 0 + if ( NM_IN_SET (autoprobe, NM_TERNARY_TRUE, NM_TERNARY_FALSE) && current_autoprobe != autoprobe && !nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_drivers_autoprobe"), - nm_sprintf_buf (buf, "%d", autoprobe))) { - _LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", autoprobe, strerror (errno)); + nm_sprintf_buf (buf, "%d", (int) autoprobe))) { + _LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", (int) autoprobe, strerror (errno)); return FALSE; } @@ -5837,7 +6159,7 @@ link_set_sriov_vfs (NMPlatform *platform, int ifindex, const NMPlatformVF *const 0, 0); if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); + g_return_val_if_reached (-NME_BUG); if (!(list = nla_nest_start (nlmsg, IFLA_VFINFO_LIST))) goto nla_put_failure; @@ -5913,7 +6235,7 @@ link_set_sriov_vfs (NMPlatform *platform, int ifindex, const NMPlatformVF *const } nla_nest_end (nlmsg, list); - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -5981,7 +6303,7 @@ vlan_add (NMPlatform *platform, 0)) return FALSE; - return do_add_link_with_lookup (platform, NM_LINK_TYPE_VLAN, name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, NM_LINK_TYPE_VLAN, name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6028,9 +6350,9 @@ link_gre_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, - name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, + props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, + name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6086,7 +6408,7 @@ link_ip6tnl_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, NM_LINK_TYPE_IP6TNL, name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, NM_LINK_TYPE_IP6TNL, name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6146,9 +6468,9 @@ link_ip6gre_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, + props->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, + name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6191,7 +6513,7 @@ link_ipip_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, NM_LINK_TYPE_IPIP, name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, NM_LINK_TYPE_IPIP, name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6246,9 +6568,9 @@ link_macsec_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - NM_LINK_TYPE_MACSEC, - name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, + NM_LINK_TYPE_MACSEC, + name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6289,9 +6611,9 @@ link_macvlan_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN, - name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, + props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN, + name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6334,7 +6656,7 @@ link_sit_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, NM_LINK_TYPE_SIT, name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, NM_LINK_TYPE_SIT, name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6460,7 +6782,7 @@ link_vxlan_add (NMPlatform *platform, nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, NM_LINK_TYPE_VXLAN, name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, NM_LINK_TYPE_VXLAN, name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6492,9 +6814,9 @@ link_6lowpan_add (NMPlatform *platform, nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - NM_LINK_TYPE_6LOWPAN, - name, nlmsg, out_link); + return (do_add_link_with_lookup (platform, + NM_LINK_TYPE_6LOWPAN, + name, nlmsg, out_link) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6641,7 +6963,7 @@ link_vlan_change (NMPlatform *platform, new_n_egress_map)) g_return_val_if_reached (FALSE); - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); } static gboolean @@ -6661,7 +6983,7 @@ link_enslave (NMPlatform *platform, int master, int slave) NLA_PUT_U32 (nlmsg, IFLA_MASTER, master); - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return (do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0); nla_put_failure: g_return_val_if_reached (FALSE); } @@ -6947,6 +7269,13 @@ wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr) return nm_wpan_utils_set_short_addr (wpan_data, short_addr); } +static gboolean +wpan_set_channel (NMPlatform *platform, int ifindex, guint8 page, guint8 channel) +{ + WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, FALSE); + return nm_wpan_utils_set_channel (wpan_data, page, channel); +} + /*****************************************************************************/ static gboolean @@ -7022,7 +7351,7 @@ ip4_address_add (NMPlatform *platform, label); nmp_object_stackinit_id_ip4_address (&obj_id, ifindex, addr, plen, peer_addr); - return do_add_addrroute (platform, &obj_id, nlmsg, FALSE) == NM_PLATFORM_ERROR_SUCCESS; + return (do_add_addrroute (platform, &obj_id, nlmsg, FALSE) >= 0); } static gboolean @@ -7052,7 +7381,7 @@ ip6_address_add (NMPlatform *platform, NULL); nmp_object_stackinit_id_ip6_address (&obj_id, ifindex, &addr); - return do_add_addrroute (platform, &obj_id, nlmsg, FALSE) == NM_PLATFORM_ERROR_SUCCESS; + return (do_add_addrroute (platform, &obj_id, nlmsg, FALSE) >= 0); } static gboolean @@ -7107,7 +7436,7 @@ ip6_address_delete (NMPlatform *platform, int ifindex, struct in6_addr addr, gui /*****************************************************************************/ -static NMPlatformError +static int ip_route_add (NMPlatform *platform, NMPNlmFlags flags, int addr_family, @@ -7131,7 +7460,7 @@ ip_route_add (NMPlatform *platform, nlmsg = _nl_msg_new_route (RTM_NEWROUTE, flags & NMP_NLM_FLAG_FMASK, &obj); if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + g_return_val_if_reached (-NME_BUG); return do_add_addrroute (platform, &obj, nlmsg, @@ -7170,7 +7499,7 @@ object_delete (NMPlatform *platform, /*****************************************************************************/ -static NMPlatformError +static int ip_route_get (NMPlatform *platform, int addr_family, gconstpointer address, @@ -7220,7 +7549,7 @@ ip_route_get (NMPlatform *platform, if (nle < 0) { _LOGE ("get-route: failure sending netlink request \"%s\" (%d)", g_strerror (-nle), -nle); - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; } delayed_action_handle_all (platform, FALSE); @@ -7232,24 +7561,24 @@ ip_route_get (NMPlatform *platform, if (seq_result < 0) { /* negative seq_result is an errno from kernel. Map it to negative - * NMPlatformError (which are also errno). */ - return (NMPlatformError) seq_result; + * int (which are also errno). */ + return (int) seq_result; } if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) { if (route) { NM_SET_OUT (out_route, g_steal_pointer (&route)); - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } seq_result = WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_UNKNOWN; } - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; } /*****************************************************************************/ -static NMPlatformError +static int qdisc_add (NMPlatform *platform, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) @@ -7267,8 +7596,8 @@ qdisc_add (NMPlatform *platform, nle = _nl_send_nlmsg (platform, msg, &seq_result, &errmsg, DELAYED_ACTION_RESPONSE_TYPE_VOID, NULL); if (nle < 0) { _LOGE ("do-add-qdisc: failed sending netlink request \"%s\" (%d)", - nl_geterror (nle), -nle); - return NM_PLATFORM_ERROR_NETLINK; + nm_strerror (nle), -nle); + return -NME_PL_NETLINK; } delayed_action_handle_all (platform, FALSE); @@ -7282,14 +7611,14 @@ qdisc_add (NMPlatform *platform, wait_for_nl_response_to_string (seq_result, errmsg, s_buf, sizeof (s_buf))); if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) - return NM_PLATFORM_ERROR_SUCCESS; + return 0; - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; } /*****************************************************************************/ -static NMPlatformError +static int tfilter_add (NMPlatform *platform, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) @@ -7307,8 +7636,8 @@ tfilter_add (NMPlatform *platform, nle = _nl_send_nlmsg (platform, msg, &seq_result, &errmsg, DELAYED_ACTION_RESPONSE_TYPE_VOID, NULL); if (nle < 0) { _LOGE ("do-add-tfilter: failed sending netlink request \"%s\" (%d)", - nl_geterror (nle), -nle); - return NM_PLATFORM_ERROR_NETLINK; + nm_strerror (nle), -nle); + return -NME_PL_NETLINK; } delayed_action_handle_all (platform, FALSE); @@ -7322,9 +7651,9 @@ tfilter_add (NMPlatform *platform, wait_for_nl_response_to_string (seq_result, errmsg, s_buf, sizeof (s_buf))); if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK) - return NM_PLATFORM_ERROR_SUCCESS; + return 0; - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; } /*****************************************************************************/ @@ -7357,17 +7686,17 @@ event_handler_recvmsgs (NMPlatform *platform, gboolean handle_events) struct nlmsghdr *hdr; WaitForNlResponseResult seq_result; struct sockaddr_nl nla = {0}; - nm_auto_free struct ucred *creds = NULL; + struct ucred creds; + gboolean creds_has; nm_auto_free unsigned char *buf = NULL; continue_reading: g_clear_pointer (&buf, free); - g_clear_pointer (&creds, free); - n = nl_recv (sk, &nla, &buf, &creds); + n = nl_recv (sk, &nla, &buf, &creds, &creds_has); if (n <= 0) { - if (n == -NLE_MSG_TRUNC) { + if (n == -NME_NL_MSG_TRUNC) { int buf_size; /* the message receive buffer was too small. We lost one message, which @@ -7400,11 +7729,11 @@ continue_reading: nlmsg_set_proto (msg, NETLINK_ROUTE); nlmsg_set_src (msg, &nla); - if (!creds || creds->pid) { - if (creds) - _LOGT ("netlink: recvmsg: received non-kernel message (pid %d)", creds->pid); - else + if (!creds_has || creds.pid) { + if (!creds_has) _LOGT ("netlink: recvmsg: received message without credentials"); + else + _LOGT ("netlink: recvmsg: received non-kernel message (pid %d)", creds.pid); err = 0; goto stop; } @@ -7412,8 +7741,7 @@ continue_reading: _LOGt ("netlink: recvmsg: new message %s", nl_nlmsghdr_to_str (hdr, buf_nlmsghdr, sizeof (buf_nlmsghdr))); - if (creds) - nlmsg_set_creds (msg, creds); + nlmsg_set_creds (msg, &creds); if (hdr->nlmsg_flags & NLM_F_MULTI) multipart = TRUE; @@ -7450,7 +7778,7 @@ continue_reading: /* Data got lost, report back to user. The default action is to * quit parsing. The user may overrule this action by retuning * NL_SKIP or NL_PROCEED (dangerous) */ - err = -NLE_MSG_OVERFLOW; + err = -NME_NL_MSG_OVERFLOW; abort_parsing = TRUE; } else if (hdr->nlmsg_type == NLMSG_ERROR) { /* Message carries a nlmsgerr */ @@ -7461,7 +7789,7 @@ continue_reading: * is to stop parsing. The user may overrule * this action by returning NL_SKIP or * NL_PROCEED (dangerous) */ - err = -NLE_MSG_TRUNC; + err = -NME_NL_MSG_TRUNC; abort_parsing = TRUE; } else if (e->error) { int errsv = e->error > 0 ? e->error : -e->error; @@ -7538,7 +7866,7 @@ stop: } if (interrupted) - return -NLE_DUMP_INTR; + return -NME_NL_DUMP_INTR; return err; } @@ -7575,16 +7903,16 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) switch (nle) { case -EAGAIN: goto after_read; - case -NLE_DUMP_INTR: - _LOGD ("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); + case -NME_NL_DUMP_INTR: + _LOGD ("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", nm_strerror (nle), nle); break; - case -NLE_MSG_TRUNC: + case -NME_NL_MSG_TRUNC: case -ENOBUFS: _LOGI ("netlink: read: %s. Need to resynchronize platform cache", ({ const char *_reason = "unknown"; switch (nle) { - case -NLE_MSG_TRUNC: _reason = "message truncated"; break; + case -NME_NL_MSG_TRUNC: _reason = "message truncated"; break; case -ENOBUFS: _reason = "too many netlink events"; break; } _reason; @@ -7604,7 +7932,7 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) NULL); break; default: - _LOGE ("netlink: read: failed to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); + _LOGE ("netlink: read: failed to retrieve incoming events: %s (%d)", nm_strerror (nle), nle); break; } } @@ -7832,7 +8160,7 @@ constructed (GObject *_object) nle = nl_connect (priv->genl, NETLINK_GENERIC); if (nle) { _LOGE ("unable to connect the generic netlink socket \"%s\" (%d)", - nl_geterror (nle), -nle); + nm_strerror (nle), -nle); nl_socket_free (priv->genl); priv->genl = NULL; } @@ -7858,7 +8186,7 @@ constructed (GObject *_object) _LOGD ("could not enable extended acks on netlink socket"); /* explicitly set the msg buffer size and disable MSG_PEEK. - * If we later encounter NLE_MSG_TRUNC, we will adjust the buffer size. */ + * If we later encounter NME_NL_MSG_TRUNC, we will adjust the buffer size. */ nl_socket_disable_msg_peek (priv->nlh); nle = nl_socket_set_msg_buf_size (priv->nlh, 32 * 1024); g_assert (!nle); @@ -8041,6 +8369,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->vlan_add = vlan_add; platform_class->link_vlan_change = link_vlan_change; + platform_class->link_wireguard_change = link_wireguard_change; platform_class->link_vxlan_add = link_vxlan_add; platform_class->infiniband_partition_add = infiniband_partition_add; @@ -8067,6 +8396,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->wpan_set_pan_id = wpan_set_pan_id; platform_class->wpan_get_short_addr = wpan_get_short_addr; platform_class->wpan_set_short_addr = wpan_set_short_addr; + platform_class->wpan_set_channel = wpan_set_channel; platform_class->link_gre_add = link_gre_add; platform_class->link_ip6tnl_add = link_ip6tnl_add; diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c index 3e2ad911..6abc1c3a 100644 --- a/src/platform/nm-netlink.c +++ b/src/platform/nm-netlink.c @@ -25,6 +25,8 @@ #include <unistd.h> #include <fcntl.h> +#include "nm-utils/nm-errno.h" + /*****************************************************************************/ #ifndef SOL_NETLINK @@ -42,16 +44,14 @@ #define NETLINK_EXT_ACK 11 #endif -#define NL_MSG_CRED_PRESENT 1 - struct nl_msg { int nm_protocol; - int nm_flags; struct sockaddr_nl nm_src; struct sockaddr_nl nm_dst; struct ucred nm_creds; struct nlmsghdr * nm_nlh; size_t nm_size; + bool nm_creds_has:1; }; struct nl_sock { @@ -67,38 +67,6 @@ struct nl_sock { /*****************************************************************************/ -NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_geterror, int, - NM_UTILS_LOOKUP_DEFAULT (NULL), - NM_UTILS_LOOKUP_ITEM (NLE_UNSPEC, "NLE_UNSPEC"), - NM_UTILS_LOOKUP_ITEM (NLE_BUG, "NLE_BUG"), - NM_UTILS_LOOKUP_ITEM (NLE_NATIVE_ERRNO, "NLE_NATIVE_ERRNO"), - - NM_UTILS_LOOKUP_ITEM (NLE_ATTRSIZE, "NLE_ATTRSIZE"), - NM_UTILS_LOOKUP_ITEM (NLE_BAD_SOCK, "NLE_BAD_SOCK"), - NM_UTILS_LOOKUP_ITEM (NLE_DUMP_INTR, "NLE_DUMP_INTR"), - NM_UTILS_LOOKUP_ITEM (NLE_MSG_OVERFLOW, "NLE_MSG_OVERFLOW"), - NM_UTILS_LOOKUP_ITEM (NLE_MSG_TOOSHORT, "NLE_MSG_TOOSHORT"), - NM_UTILS_LOOKUP_ITEM (NLE_MSG_TRUNC, "NLE_MSG_TRUNC"), - NM_UTILS_LOOKUP_ITEM (NLE_SEQ_MISMATCH, "NLE_SEQ_MISMATCH"), -) - -const char * -nl_geterror (int nlerr) -{ - const char *s; - - nlerr = nl_errno (nlerr); - - if (nlerr >= _NLE_BASE) { - s = _geterror (nlerr); - if (s) - return s; - } - return g_strerror (nlerr); -} - -/*****************************************************************************/ - NM_UTILS_ENUM2STR_DEFINE (nl_nlmsgtype2str, int, NM_UTILS_ENUM2STR (NLMSG_NOOP, "NOOP"), NM_UTILS_ENUM2STR (NLMSG_ERROR, "ERROR"), @@ -285,20 +253,6 @@ nla_reserve (struct nl_msg *msg, int attrtype, int attrlen) /*****************************************************************************/ -static int -get_default_page_size (void) -{ - static int val = 0; - int v; - - if (G_UNLIKELY (val == 0)) { - v = getpagesize (); - g_assert (v > 0); - val = v; - } - return val; -} - struct nl_msg * nlmsg_alloc_size (size_t len) { @@ -328,7 +282,7 @@ nlmsg_alloc_size (size_t len) struct nl_msg * nlmsg_alloc (void) { - return nlmsg_alloc_size (get_default_page_size ()); + return nlmsg_alloc_size (nm_utils_getpagesize ()); } struct nl_msg * @@ -385,7 +339,7 @@ nlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy) { if (!nlmsg_valid_hdr (nlh, hdrlen)) - return -NLE_MSG_TOOSHORT; + return -NME_NL_MSG_TOOSHORT; return nla_parse (tb, maxtype, nlmsg_attrdata (nlh, hdrlen), nlmsg_attrlen (nlh, hdrlen), policy); @@ -465,7 +419,7 @@ nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data) nla = nla_reserve (msg, attrtype, datalen); if (!nla) { if (datalen < 0) - g_return_val_if_reached (-NLE_BUG); + g_return_val_if_reached (-NME_BUG); return -ENOMEM; } @@ -531,7 +485,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) nla_nest_cancel (msg, start); /* Return error only if nlattr size was exceeded */ - return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE; + return (len == NLA_HDRLEN) ? 0 : -NME_NL_ATTRSIZE; } start->nla_len = len; @@ -539,13 +493,13 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) pad = NLMSG_ALIGN (msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; if (pad > 0) { /* - * Data inside attribute does not end at a alignment boundry. + * Data inside attribute does not end at a alignment boundary. * Pad accordingly and accoun for the additional space in * the message. nlmsg_reserve() may never fail in this situation, * the allocate message buffer must be a multiple of NLMSG_ALIGNTO. */ if (!nlmsg_reserve (msg, pad, 0)) - g_return_val_if_reached (-NLE_BUG); + g_return_val_if_reached (-NME_BUG); } return 0; @@ -580,7 +534,7 @@ validate_nla (const struct nlattr *nla, int maxtype, pt = &policy[type]; if (pt->type > NLA_TYPE_MAX) - g_return_val_if_reached (-NLE_BUG); + g_return_val_if_reached (-NME_BUG); if (pt->minlen) minlen = pt->minlen; @@ -588,15 +542,15 @@ validate_nla (const struct nlattr *nla, int maxtype, minlen = nla_attr_minlen[pt->type]; if (nla_len (nla) < minlen) - return -NLE_UNSPEC; + return -NME_UNSPEC; if (pt->maxlen && nla_len (nla) > pt->maxlen) - return -NLE_UNSPEC; + return -NME_UNSPEC; if (pt->type == NLA_STRING) { const char *data = nla_data (nla); if (data[nla_len (nla) - 1] != '\0') - return -NLE_UNSPEC; + return -NME_UNSPEC; } return 0; @@ -607,7 +561,7 @@ nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy) { struct nlattr *nla; - int rem, nlerr; + int rem, nmerr; memset (tb, 0, sizeof (struct nlattr *) * (maxtype + 1)); @@ -618,17 +572,17 @@ nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len, continue; if (policy) { - nlerr = validate_nla (nla, maxtype, policy); - if (nlerr < 0) + nmerr = validate_nla (nla, maxtype, policy); + if (nmerr < 0) goto errout; } tb[type] = nla; } - nlerr = 0; + nmerr = 0; errout: - return nlerr; + return nmerr; } /*****************************************************************************/ @@ -654,7 +608,7 @@ nlmsg_set_src (struct nl_msg *msg, struct sockaddr_nl *addr) struct ucred * nlmsg_get_creds (struct nl_msg *msg) { - if (msg->nm_flags & NL_MSG_CRED_PRESENT) + if (msg->nm_creds_has) return &msg->nm_creds; return NULL; } @@ -662,8 +616,11 @@ nlmsg_get_creds (struct nl_msg *msg) void nlmsg_set_creds (struct nl_msg *msg, struct ucred *creds) { - memcpy (&msg->nm_creds, creds, sizeof (*creds)); - msg->nm_flags |= NL_MSG_CRED_PRESENT; + if (creds) { + memcpy (&msg->nm_creds, creds, sizeof (*creds)); + msg->nm_creds_has = TRUE; + } else + msg->nm_creds_has = FALSE; } /*****************************************************************************/ @@ -754,7 +711,7 @@ genlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], struct genlmsghdr *ghdr; if (!genlmsg_valid_hdr (nlh, hdrlen)) - return -NLE_MSG_TOOSHORT; + return -NME_NL_MSG_TOOSHORT; ghdr = nlmsg_data (nlh); return nla_parse (tb, maxtype, genlmsg_attrdata (ghdr, hdrlen), @@ -791,7 +748,7 @@ int genl_ctrl_resolve (struct nl_sock *sk, const char *name) { nm_auto_nlmsg struct nl_msg *msg = NULL; - int nlerr; + int nmerr; gint32 response_data = -1; const struct nl_cb cb = { .valid_cb = _genl_parse_getfamily, @@ -804,25 +761,25 @@ genl_ctrl_resolve (struct nl_sock *sk, const char *name) 0, 0, CTRL_CMD_GETFAMILY, 1)) return -ENOMEM; - nlerr = nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name); - if (nlerr < 0) - return nlerr; + nmerr = nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name); + if (nmerr < 0) + return nmerr; - nlerr = nl_send_auto (sk, msg); - if (nlerr < 0) - return nlerr; + nmerr = nl_send_auto (sk, msg); + if (nmerr < 0) + return nmerr; - nlerr = nl_recvmsgs (sk, &cb); - if (nlerr < 0) - return nlerr; + nmerr = nl_recvmsgs (sk, &cb); + if (nmerr < 0) + return nmerr; /* If search was successful, request may be ACKed after data */ - nlerr = nl_wait_for_ack (sk, NULL); - if (nlerr < 0) - return nlerr; + nmerr = nl_wait_for_ack (sk, NULL); + if (nmerr < 0) + return nmerr; if (response_data < 0) - return -NLE_UNSPEC; + return -NME_UNSPEC; return response_data; } @@ -879,12 +836,12 @@ nl_socket_set_passcred (struct nl_sock *sk, int state) int err; if (sk->s_fd == -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; err = setsockopt (sk->s_fd, SOL_SOCKET, SO_PASSCRED, &state, sizeof (state)); if (err < 0) - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); if (state) sk->s_flags |= NL_SOCK_PASSCRED; @@ -912,10 +869,10 @@ int nl_socket_set_nonblocking (const struct nl_sock *sk) { if (sk->s_fd == -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; if (fcntl (sk->s_fd, F_SETFL, O_NONBLOCK) < 0) - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); return 0; } @@ -932,18 +889,18 @@ nl_socket_set_buffer_size (struct nl_sock *sk, int rxbuf, int txbuf) txbuf = 32768; if (sk->s_fd == -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; err = setsockopt (sk->s_fd, SOL_SOCKET, SO_SNDBUF, &txbuf, sizeof (txbuf)); if (err < 0) { - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); } err = setsockopt (sk->s_fd, SOL_SOCKET, SO_RCVBUF, &rxbuf, sizeof (rxbuf)); if (err < 0) { - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); } return 0; @@ -956,14 +913,14 @@ nl_socket_add_memberships (struct nl_sock *sk, int group, ...) va_list ap; if (sk->s_fd == -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; va_start (ap, group); while (group != 0) { if (group < 0) { va_end (ap); - g_return_val_if_reached (-NLE_BUG); + g_return_val_if_reached (-NME_BUG); } err = setsockopt (sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, @@ -972,7 +929,7 @@ nl_socket_add_memberships (struct nl_sock *sk, int group, ...) int errsv = errno; va_end (ap); - return -nl_syserr2nlerr (errsv); + return -nm_errno_from_native (errsv); } group = va_arg (ap, int); @@ -989,12 +946,12 @@ nl_socket_set_ext_ack (struct nl_sock *sk, gboolean enable) int err, val; if (sk->s_fd == -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; val = !!enable; err = setsockopt (sk->s_fd, SOL_NETLINK, NETLINK_EXT_ACK, &val, sizeof (val)); if (err < 0) - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); return 0; } @@ -1008,21 +965,21 @@ void nl_socket_disable_msg_peek (struct nl_sock *sk) int nl_connect (struct nl_sock *sk, int protocol) { - int err, nlerr; + int err, nmerr; socklen_t addrlen; struct sockaddr_nl local = { 0 }; if (sk->s_fd != -1) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; sk->s_fd = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); if (sk->s_fd < 0) { - nlerr = -nl_syserr2nlerr (errno); + nmerr = -nm_errno_from_native (errno); goto errout; } - nlerr = nl_socket_set_buffer_size (sk, 0, 0); - if (nlerr < 0) + nmerr = nl_socket_set_buffer_size (sk, 0, 0); + if (nmerr < 0) goto errout; nm_assert (sk->s_local.nl_pid == 0); @@ -1030,7 +987,7 @@ nl_connect (struct nl_sock *sk, int protocol) err = bind (sk->s_fd, (struct sockaddr*) &sk->s_local, sizeof (sk->s_local)); if (err != 0) { - nlerr = -nl_syserr2nlerr (errno); + nmerr = -nm_errno_from_native (errno); goto errout; } @@ -1038,17 +995,17 @@ nl_connect (struct nl_sock *sk, int protocol) err = getsockname (sk->s_fd, (struct sockaddr *) &local, &addrlen); if (err < 0) { - nlerr = -nl_syserr2nlerr (errno); + nmerr = -nm_errno_from_native (errno); goto errout; } if (addrlen != sizeof (local)) { - nlerr = -NLE_UNSPEC; + nmerr = -NME_UNSPEC; goto errout; } if (local.nl_family != AF_NETLINK) { - nlerr = -NLE_UNSPEC; + nmerr = -NME_UNSPEC; goto errout; } @@ -1062,7 +1019,7 @@ errout: close (sk->s_fd); sk->s_fd = -1; } - return nlerr; + return nmerr; } /*****************************************************************************/ @@ -1098,22 +1055,22 @@ nl_wait_for_ack (struct nl_sock *sk, do { \ const struct nl_cb *_cb = (cb); \ \ - if (_cb->type##_cb) { \ + if (_cb && _cb->type##_cb) { \ /* the returned value here must be either a negative * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ \ - nlerr = _cb->type##_cb ((msg), _cb->type##_arg); \ - switch (nlerr) { \ + nmerr = _cb->type##_cb ((msg), _cb->type##_arg); \ + switch (nmerr) { \ case NL_OK: \ - nlerr = 0; \ + nmerr = 0; \ break; \ case NL_SKIP: \ goto skip; \ case NL_STOP: \ goto stop; \ default: \ - if (nlerr >= 0) { \ + if (nmerr >= 0) { \ nm_assert_not_reached (); \ - nlerr = -NLE_BUG; \ + nmerr = -NME_BUG; \ } \ goto out; \ } \ @@ -1123,14 +1080,15 @@ do { \ int nl_recvmsgs (struct nl_sock *sk, const struct nl_cb *cb) { - int n, nlerr = 0, multipart = 0, interrupted = 0, nrecv = 0; + int n, nmerr = 0, multipart = 0, interrupted = 0, nrecv = 0; gs_free unsigned char *buf = NULL; struct nlmsghdr *hdr; struct sockaddr_nl nla = { 0 }; - gs_free struct ucred *creds = NULL; + struct ucred creds; + gboolean creds_has; continue_reading: - n = nl_recv (sk, &nla, &buf, &creds); + n = nl_recv (sk, &nla, &buf, &creds, &creds_has); if (n <= 0) return n; @@ -1142,15 +1100,14 @@ continue_reading: nlmsg_set_proto (msg, sk->s_proto); nlmsg_set_src (msg, &nla); - if (creds) - nlmsg_set_creds (msg, creds); + nlmsg_set_creds (msg, creds_has ? &creds : NULL); nrecv++; /* Only do sequence checking if auto-ack mode is enabled */ if (! (sk->s_flags & NL_NO_AUTO_ACK)) { if (hdr->nlmsg_seq != sk->s_seq_expect) { - nlerr = -NLE_SEQ_MISMATCH; + nmerr = -NME_NL_SEQ_MISMATCH; goto out; } } @@ -1196,7 +1153,7 @@ continue_reading: * quit parsing. The user may overrule this action by retuning * NL_SKIP or NL_PROCEED (dangerous) */ else if (hdr->nlmsg_type == NLMSG_OVERRUN) { - nlerr = -NLE_MSG_OVERFLOW; + nmerr = -NME_NL_MSG_OVERFLOW; goto out; } @@ -1209,27 +1166,27 @@ continue_reading: * is to stop parsing. The user may overrule * this action by returning NL_SKIP or * NL_PROCEED (dangerous) */ - nlerr = -NLE_MSG_TRUNC; + nmerr = -NME_NL_MSG_TRUNC; goto out; } if (e->error) { /* Error message reported back from kernel. */ - if (cb->err_cb) { + if (cb && cb->err_cb) { /* the returned value here must be either a negative * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ - nlerr = cb->err_cb (&nla, e, + nmerr = cb->err_cb (&nla, e, cb->err_arg); - if (nlerr < 0) + if (nmerr < 0) goto out; - else if (nlerr == NL_SKIP) + else if (nmerr == NL_SKIP) goto skip; - else if (nlerr == NL_STOP) { - nlerr = -nl_syserr2nlerr (e->error); + else if (nmerr == NL_STOP) { + nmerr = -nm_errno_from_native (e->error); goto out; } - nm_assert (nlerr == NL_OK); + nm_assert (nmerr == NL_OK); } else { - nlerr = -nl_syserr2nlerr (e->error); + nmerr = -nm_errno_from_native (e->error); goto out; } } else @@ -1241,27 +1198,26 @@ continue_reading: NL_CB_CALL (cb, valid, msg); } skip: - nlerr = 0; + nmerr = 0; hdr = nlmsg_next (hdr, &n); } if (multipart) { /* Multipart message not yet complete, continue reading */ - nm_clear_g_free (&creds); nm_clear_g_free (&buf); goto continue_reading; } stop: - nlerr = 0; + nmerr = 0; out: if (interrupted) - nlerr = -NLE_DUMP_INTR; + nmerr = -NME_NL_DUMP_INTR; - nm_assert (nlerr <= 0); - return nlerr ?: nrecv; + nm_assert (nmerr <= 0); + return nmerr ?: nrecv; } int @@ -1270,13 +1226,13 @@ nl_sendmsg (struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) int ret; if (sk->s_fd < 0) - return -NLE_BAD_SOCK; + return -NME_NL_BAD_SOCK; nlmsg_set_src (msg, &sk->s_local); ret = sendmsg (sk->s_fd, hdr, 0); if (ret < 0) - return -nl_syserr2nlerr (errno); + return -nm_errno_from_native (errno); return ret; } @@ -1359,12 +1315,14 @@ int nl_send_auto (struct nl_sock *sk, struct nl_msg *msg) } int -nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, - unsigned char **buf, struct ucred **creds) +nl_recv (struct nl_sock *sk, + struct sockaddr_nl *nla, + unsigned char **buf, + struct ucred *out_creds, + gboolean *out_creds_has) { ssize_t n; int flags = 0; - static int page_size = 0; struct iovec iov; struct msghdr msg = { .msg_name = (void *) nla, @@ -1372,25 +1330,24 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, .msg_iov = &iov, .msg_iovlen = 1, }; - gs_free struct ucred* tmpcreds = NULL; + struct ucred tmpcreds; + gboolean tmpcreds_has = FALSE; int retval; nm_assert (nla); nm_assert (buf && !*buf); - nm_assert (!creds || !*creds); + nm_assert (!out_creds_has == !out_creds); if ( (sk->s_flags & NL_MSG_PEEK) || ( !(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0)) flags |= MSG_PEEK | MSG_TRUNC; - if (page_size == 0) - page_size = getpagesize () * 4; - - iov.iov_len = sk->s_bufsize ?: page_size; + iov.iov_len = sk->s_bufsize + ?: (((size_t) nm_utils_getpagesize ()) * 4u); iov.iov_base = g_malloc (iov.iov_len); - if ( creds + if ( out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) { msg.msg_controllen = CMSG_SPACE (sizeof (struct ucred)); msg.msg_control = g_malloc (msg.msg_controllen); @@ -1407,13 +1364,13 @@ retry: if (errno == EINTR) goto retry; - retval = -nl_syserr2nlerr (errno); + retval = -nm_errno_from_native (errno); goto abort; } if (msg.msg_flags & MSG_CTRUNC) { if (msg.msg_controllen == 0) { - retval = -NLE_MSG_TRUNC; + retval = -NME_NL_MSG_TRUNC; goto abort; } @@ -1426,7 +1383,7 @@ retry: || (msg.msg_flags & MSG_TRUNC)) { /* respond with error to an incomplete message */ if (flags == 0) { - retval = -NLE_MSG_TRUNC; + retval = -NME_NL_MSG_TRUNC; goto abort; } @@ -1446,11 +1403,11 @@ retry: } if (msg.msg_namelen != sizeof (struct sockaddr_nl)) { - retval = -NLE_UNSPEC; + retval = -NME_UNSPEC; goto abort; } - if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) { + if (out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) { struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) { @@ -1458,7 +1415,8 @@ retry: continue; if (cmsg->cmsg_type != SCM_CREDENTIALS) continue; - tmpcreds = nm_memdup (CMSG_DATA (cmsg), sizeof (*tmpcreds)); + memcpy (&tmpcreds, CMSG_DATA (cmsg), sizeof (tmpcreds)); + tmpcreds_has = TRUE; break; } } @@ -1474,6 +1432,8 @@ abort: } *buf = iov.iov_base; - NM_SET_OUT (creds, g_steal_pointer (&tmpcreds)); + if (out_creds && tmpcreds_has) + *out_creds = tmpcreds; + NM_SET_OUT (out_creds_has, tmpcreds_has); return retval; } diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h index d5df7ab9..84bbe27b 100644 --- a/src/platform/nm-netlink.h +++ b/src/platform/nm-netlink.h @@ -26,20 +26,6 @@ #include <linux/genetlink.h> /*****************************************************************************/ -#define _NLE_BASE 100000 -#define NLE_UNSPEC (_NLE_BASE + 0) -#define NLE_BUG (_NLE_BASE + 1) -#define NLE_NATIVE_ERRNO (_NLE_BASE + 2) -#define NLE_SEQ_MISMATCH (_NLE_BASE + 3) -#define NLE_MSG_TRUNC (_NLE_BASE + 4) -#define NLE_MSG_TOOSHORT (_NLE_BASE + 5) -#define NLE_DUMP_INTR (_NLE_BASE + 6) -#define NLE_ATTRSIZE (_NLE_BASE + 7) -#define NLE_BAD_SOCK (_NLE_BASE + 8) -#define NLE_NOADDR (_NLE_BASE + 9) -#define NLE_MSG_OVERFLOW (_NLE_BASE + 10) - -#define _NLE_BASE_END (_NLE_BASE + 11) #define NLMSGERR_ATTR_UNUSED 0 #define NLMSGERR_ATTR_MSG 1 @@ -51,50 +37,6 @@ #define NLM_F_ACK_TLVS 0x200 #endif -static inline int -nl_errno (int nlerr) -{ - /* Normalizes an netlink error to be positive. Various API returns negative - * error codes, and this function converts the negative value to its - * positive. - * - * It's very similar to nm_errno(), but not exactly. The difference is that - * nm_errno() is for plain errno, while nl_errno() is for netlink error numbers. - * Yes, netlink error number are ~almost~ the same as errno, except that a particular - * range (_NLE_BASE, _NLE_BASE_END) is reserved. The difference between the two - * functions is only how G_MININT is mapped. - * - * See also nl_syserr2nlerr() below. */ - return nlerr >= 0 - ? nlerr - : ((nlerr == G_MININT) ? NLE_BUG : -nlerr); -} - -static inline int -nl_syserr2nlerr (int errsv) -{ - /* this maps a native errno to a (always non-negative) netlink error number. - * - * Note that netlink error numbers are embedded into the range of regular - * errno. The only difference is, that netlink error numbers reserve a - * range (_NLE_BASE, _NLE_BASE_END) for their own purpose. - * - * That means, converting an errno to netlink error number means in - * most cases just returning itself (negative values are normalized - * to be positive). Only values G_MININT and [_NLE_BASE, _NLE_BASE_END] - * are coerced to the special value NLE_NATIVE_ERRNO, as they cannot - * otherwise be represented in netlink error number domain. */ - if (errsv == G_MININT) - return NLE_NATIVE_ERRNO; - if (errsv < 0) - errsv = -errsv; - return (errsv >= _NLE_BASE && errsv < _NLE_BASE_END) - ? NLE_NATIVE_ERRNO - : errsv; -} - -const char *nl_geterror (int nlerr); - /*****************************************************************************/ /* Basic attribute data types */ @@ -245,6 +187,24 @@ nla_put_string (struct nl_msg *msg, int attrtype, const char *str) return nla_put(msg, attrtype, strlen(str) + 1, str); } +static inline int +nla_put_uint8 (struct nl_msg *msg, int attrtype, uint8_t val) +{ + return nla_put (msg, attrtype, sizeof (val), &val); +} + +static inline int +nla_put_uint16 (struct nl_msg *msg, int attrtype, uint16_t val) +{ + return nla_put (msg, attrtype, sizeof (val), &val); +} + +static inline int +nla_put_uint32 (struct nl_msg *msg, int attrtype, uint32_t val) +{ + return nla_put (msg, attrtype, sizeof (val), &val); +} + #define NLA_PUT(msg, attrtype, attrlen, data) \ do { \ if (nla_put(msg, attrtype, attrlen, data) < 0) \ @@ -474,8 +434,11 @@ int nl_socket_add_memberships (struct nl_sock *sk, int group, ...); int nl_connect (struct nl_sock *sk, int protocol); -int nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, - unsigned char **buf, struct ucred **creds); +int nl_recv (struct nl_sock *sk, + struct sockaddr_nl *nla, + unsigned char **buf, + struct ucred *out_creds, + gboolean *out_creds_has); int nl_send (struct nl_sock *sk, struct nl_msg *msg); diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 216b1547..772d4667 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -29,6 +29,7 @@ #include <linux/ethtool.h> #include <linux/sockios.h> #include <linux/mii.h> +#include <linux/if.h> #include <linux/version.h> #include <linux/rtnetlink.h> #include <fcntl.h> @@ -664,7 +665,7 @@ nmp_utils_ethtool_set_features (int ifindex, "set-features", success ? "successfully setting features" - : "at least some of the features were not successfuly set"); + : "at least some of the features were not successfully set"); return success; } @@ -1247,7 +1248,7 @@ nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize * @ifindex: the ifindex for which to open "/sys/class/net/%s" * @ifname_guess: (allow-none): optional argument, if present used as initial * guess as the current name for @ifindex. If guessed right, - * it saves an addtional if_indextoname() call. + * it saves an additional if_indextoname() call. * @out_ifname: (allow-none): if present, must be at least IFNAMSIZ * characters. On success, this will contain the actual ifname * found while opening the directory. @@ -1276,7 +1277,6 @@ nmp_utils_sysctl_open_netdir (int ifindex, for (try_count = 0; try_count < 10; try_count++, ifname = NULL) { nm_auto_close int fd_dir = -1; nm_auto_close int fd_ifindex = -1; - int fd; if (!ifname) { ifname = nmp_utils_if_indextoname (ifindex, ifname_buf); @@ -1309,15 +1309,13 @@ nmp_utils_sysctl_open_netdir (int ifindex, continue; fd_buf[nn] = '\0'; - if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) + if (ifindex != (int) _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) continue; if (out_ifname) strcpy (out_ifname, ifname); - fd = fd_dir; - fd_dir = -1; - return fd; + return nm_steal_fd (&fd_dir); } return -1; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index c73631a9..4bb31b17 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -31,6 +31,7 @@ #include <netdb.h> #include <string.h> #include <linux/ip.h> +#include <linux/if.h> #include <linux/if_tun.h> #include <linux/if_tunnel.h> #include <linux/rtnetlink.h> @@ -40,6 +41,7 @@ #include "nm-core-internal.h" #include "nm-utils/nm-dedup-multi.h" #include "nm-utils/nm-udev-utils.h" +#include "nm-utils/nm-errno.h" #include "nm-core-utils.h" #include "nm-platform-utils.h" @@ -57,22 +59,48 @@ G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OF #define _NMLOG_DOMAIN LOGD_PLATFORM #define _NMLOG_PREFIX_NAME "platform" + + +#define NMLOG_COMMON(level, name, ...) \ + char __prefix[32]; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ + const NMPlatform *const __self = (self); \ + const char *__name = name; \ + \ + if (__self && NM_PLATFORM_GET_PRIVATE (__self)->log_with_ptr) { \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log (__level, _NMLOG_DOMAIN, 0, __name, NULL, \ + "%s: %s%s%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ + __p_prefix, \ + NM_PRINT_FMT_QUOTED (__name, "(", __name, ") ", "") \ + _NM_UTILS_MACRO_REST (__VA_ARGS__)); + #define _NMLOG(level, ...) \ G_STMT_START { \ const NMLogLevel __level = (level); \ \ if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const NMPlatform *const __self = (self); \ - \ - if (__self && NM_PLATFORM_GET_PRIVATE (__self)->log_with_ptr) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, _NMLOG_DOMAIN, 0, NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + NMLOG_COMMON(level, NULL, __VA_ARGS__); \ + } \ + } G_STMT_END + +#define _NMLOG2(level, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, name, __VA_ARGS__); \ + } \ + } G_STMT_END + +#define _NMLOG3(level, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ + NMLOG_COMMON(level, ifindex > 0 ? nm_platform_link_get_name (self, ifindex) : NULL, __VA_ARGS__); \ } \ } G_STMT_END @@ -228,58 +256,6 @@ nm_platform_get_multi_idx (NMPlatform *self) /*****************************************************************************/ -NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_nm_platform_error_to_string, NMPlatformError, - NM_UTILS_LOOKUP_DEFAULT (NULL), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_SUCCESS, "success"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_BUG, "bug"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_UNSPECIFIED, "unspecified"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NOT_FOUND, "not-found"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_EXISTS, "exists"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_WRONG_TYPE, "wrong-type"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NOT_SLAVE, "not-slave"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NO_FIRMWARE, "no-firmware"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_OPNOTSUPP, "not-supported"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_NETLINK, "netlink"), - NM_UTILS_LOOKUP_STR_ITEM (NM_PLATFORM_ERROR_CANT_SET_MTU, "cant-set-mtu"), - NM_UTILS_LOOKUP_ITEM_IGNORE (_NM_PLATFORM_ERROR_MININT), -); - -/** - * nm_platform_error_to_string: - * @error_code: the error code to stringify. - * @buf: (allow-none): buffer - * @buf_len: size of buffer - * - * Returns: A string representation of the error. - * For negative numbers, this function interprets - * the code as -errno. - * For invalid (positive) numbers it returns NULL. - */ -const char * -nm_platform_error_to_string (NMPlatformError error_code, char *buf, gsize buf_len) -{ - const char *s; - - if (error_code < 0) { - int errsv = -((int) error_code); - - nm_utils_to_string_buffer_init (&buf, &buf_len); - g_snprintf (buf, buf_len, "%s (%d)", g_strerror (errsv), errsv); - } else { - s = _nm_platform_error_to_string (error_code); - if (s) { - if (!buf) - return s; - g_strlcpy (buf, s, buf_len); - } else { - nm_utils_to_string_buffer_init (&buf, &buf_len); - g_snprintf (buf, buf_len, "(%d)", (int) error_code); - } - } - - return buf; -} - NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_nmp_nlm_flag_to_string_lookup, NMPNlmFlags, NM_UTILS_LOOKUP_DEFAULT (NULL), NM_UTILS_LOOKUP_ITEM (NMP_NLM_FLAG_ADD, "add"), @@ -449,7 +425,9 @@ nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const c } gboolean -nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, int value) +nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self, + const char *iface, + int value) { const char *path; gint64 cur; @@ -543,7 +521,14 @@ nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, c * (inclusive) or @fallback. */ gint64 -nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int dirfd, const char *path, guint base, gint64 min, gint64 max, gint64 fallback) +nm_platform_sysctl_get_int_checked (NMPlatform *self, + const char *pathid, + int dirfd, + const char *path, + guint base, + gint64 min, + gint64 max, + gint64 fallback) { char *value = NULL; gint32 ret; @@ -570,6 +555,81 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int di /*****************************************************************************/ +char * +nm_platform_sysctl_ip_conf_get (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_get (platform, + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, + buf, + ifname, + property))); +} + +gint64 +nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_get_int_checked (platform, + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, + buf, + ifname, + property)), + base, + min, + max, + fallback); +} + +gboolean +nm_platform_sysctl_ip_conf_set (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + const char *value) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + + return nm_platform_sysctl_set (platform, + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, + buf, + ifname, + property)), + value); +} + +gboolean +nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + gint64 value) +{ + char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE]; + char s[64]; + + return nm_platform_sysctl_set (platform, + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_sysctl_ip_conf_path (addr_family, + buf, + ifname, + property)), + nm_sprintf_buf (s, "%"G_GINT64_FORMAT, value)); +} + +/*****************************************************************************/ + static int _link_get_all_presort (gconstpointer p_a, gconstpointer p_b, @@ -727,6 +787,8 @@ nm_platform_link_get_obj (NMPlatform *self, { const NMPObject *obj_cache; + _CHECK_SELF (self, klass, NULL); + obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (self), ifindex); if ( !obj_cache || ( visible_only @@ -752,15 +814,7 @@ nm_platform_link_get_obj (NMPlatform *self, const NMPlatformLink * nm_platform_link_get (NMPlatform *self, int ifindex) { - const NMPObject *obj; - - _CHECK_SELF (self, klass, NULL); - - if (ifindex <= 0) - return NULL; - - obj = nm_platform_link_get_obj (self, ifindex, TRUE); - return NMP_OBJECT_CAST_LINK (obj); + return NMP_OBJECT_CAST_LINK (nm_platform_link_get_obj (self, ifindex, TRUE)); } /** @@ -833,7 +887,7 @@ nm_platform_link_get_by_address (NMPlatform *self, return NMP_OBJECT_CAST_LINK (obj); } -static NMPlatformError +static int _link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, const NMPlatformLink **out_link) { const NMPlatformLink *pllink; @@ -843,20 +897,19 @@ _link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, c gboolean wrong_type; wrong_type = type != NM_LINK_TYPE_NONE && pllink->type != type; - _LOGD ("link: skip adding link due to existing interface '%s' of type %s%s%s", - name, - nm_link_type_to_string (pllink->type), - wrong_type ? ", expected " : "", - wrong_type ? nm_link_type_to_string (type) : ""); + _LOG2D ("link: skip adding link due to existing interface of type %s%s%s", + nm_link_type_to_string (pllink->type), + wrong_type ? ", expected " : "", + wrong_type ? nm_link_type_to_string (type) : ""); if (out_link) *out_link = pllink; if (wrong_type) - return NM_PLATFORM_ERROR_WRONG_TYPE; - return NM_PLATFORM_ERROR_EXISTS; + return -NME_PL_WRONG_TYPE; + return -NME_PL_EXISTS; } if (out_link) *out_link = NULL; - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } /** @@ -870,16 +923,16 @@ _link_add_check_existing (NMPlatform *self, const char *name, NMLinkType type, c * @out_link: on success, the link object * * Add a software interface. If the interface already exists and is of type - * @type, return NM_PLATFORM_ERROR_EXISTS and returns the link + * @type, return -NME_PL_EXISTS and returns the link * in @out_link. If the interface already exists and is not of type @type, - * return NM_PLATFORM_ERROR_WRONG_TYPE. + * return -NME_PL_WRONG_TYPE. * * Any link-changed ADDED signal will be emitted directly, before this * function finishes. * - * Returns: the error reason or NM_PLATFORM_ERROR_SUCCESS. + * Returns: the negative nm-error on failure. */ -static NMPlatformError +static int nm_platform_link_add (NMPlatform *self, const char *name, NMLinkType type, @@ -888,38 +941,35 @@ nm_platform_link_add (NMPlatform *self, size_t address_len, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; char addr_buf[NM_UTILS_HWADDR_LEN_MAX * 3]; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail ((address != NULL) ^ (address_len == 0) , NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (address_len <= NM_UTILS_HWADDR_LEN_MAX, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail ((!!veth_peer) == (type == NM_LINK_TYPE_VETH), NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (name, -NME_BUG); + g_return_val_if_fail ((address != NULL) ^ (address_len == 0) , -NME_BUG); + g_return_val_if_fail (address_len <= NM_UTILS_HWADDR_LEN_MAX, -NME_BUG); + g_return_val_if_fail ((!!veth_peer) == (type == NM_LINK_TYPE_VETH), -NME_BUG); - plerr = _link_add_check_existing (self, name, type, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, type, out_link); + if (r < 0) + return r; - _LOGD ("link: adding link '%s': %s (%d)" - "%s%s" /* address */ - "%s%s" /* veth peer */ - "", - name, - nm_link_type_to_string (type), - (int) type, - address ? ", address: " : "", - address ? nm_utils_hwaddr_ntoa_buf (address, address_len, FALSE, addr_buf, sizeof (addr_buf)) : "", - veth_peer ? ", veth-peer: " : "", - veth_peer ?: ""); + _LOG2D ("link: adding link: %s (%d)" + "%s%s" /* address */ + "%s%s" /* veth peer */ + "", + nm_link_type_to_string (type), + (int) type, + address ? ", address: " : "", + address ? nm_utils_hwaddr_ntoa_buf (address, address_len, FALSE, addr_buf, sizeof (addr_buf)) : "", + veth_peer ? ", veth-peer: " : "", + veth_peer ?: ""); - if (!klass->link_add (self, name, type, veth_peer, address, address_len, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return klass->link_add (self, name, type, veth_peer, address, address_len, out_link); } -NMPlatformError +int nm_platform_link_veth_add (NMPlatform *self, const char *name, const char *peer, @@ -936,7 +986,7 @@ nm_platform_link_veth_add (NMPlatform *self, * * Create a software ethernet-like interface */ -NMPlatformError +int nm_platform_link_dummy_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link) @@ -952,15 +1002,11 @@ nm_platform_link_dummy_add (NMPlatform *self, gboolean nm_platform_link_delete (NMPlatform *self, int ifindex) { - const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); - pllink = nm_platform_link_get (self, ifindex); - if (!pllink) - return FALSE; + g_return_val_if_fail (ifindex > 0, FALSE); - _LOGD ("link: deleting '%s' (%d)", pllink->name, ifindex); + _LOG3D ("link: deleting"); return klass->link_delete (self, ifindex); } @@ -975,18 +1021,12 @@ nm_platform_link_delete (NMPlatform *self, int ifindex) 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: move link %d to network namespace with fd %d", ifindex, netns_fd); + _LOG3D ("link: move link to network namespace with fd %d", netns_fd); return klass->link_set_netns (self, ifindex, netns_fd); } @@ -996,7 +1036,7 @@ nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) * @name: Interface name * * Returns: The interface index corresponding to the given interface name - * or 0. Inteface name is owned by #NMPlatform, don't free it. + * or 0. Interface name is owned by #NMPlatform, don't free it. */ int nm_platform_link_get_ifindex (NMPlatform *self, const char *name) @@ -1036,8 +1076,6 @@ nm_platform_link_get_name (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, NULL); - pllink = nm_platform_link_get (self, ifindex); return pllink ? pllink->name : NULL; } @@ -1055,8 +1093,6 @@ nm_platform_link_get_type (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, NM_LINK_TYPE_NONE); - pllink = nm_platform_link_get (self, ifindex); return pllink ? pllink->type : NM_LINK_TYPE_NONE; } @@ -1075,16 +1111,13 @@ nm_platform_link_get_type_name (NMPlatform *self, int ifindex) { const NMPObject *obj; - _CHECK_SELF (self, klass, NULL); - obj = nm_platform_link_get_obj (self, ifindex, TRUE); - if (!obj) return NULL; if (obj->link.type != NM_LINK_TYPE_UNKNOWN) { /* We could detect the @link_type. In this case the function returns - * our internel module names, which differs from rtnl_link_get_type(): + * our internal module names, which differs from rtnl_link_get_type(): * - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib") * - NM_LINK_TYPE_TAP (gives "tap", instead of "tun"). * Note that this functions is only used by NMDeviceGeneric to @@ -1199,11 +1232,6 @@ nm_platform_link_get_ifi_flags (NMPlatform *self, { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, -EINVAL); - - if (ifindex <= 0) - return -EINVAL; - /* include invisible links (only in netlink, not udev). */ pllink = NMP_OBJECT_CAST_LINK (nm_platform_link_get_obj (self, ifindex, FALSE)); if (!pllink) @@ -1242,8 +1270,6 @@ nm_platform_link_is_connected (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); - pllink = nm_platform_link_get (self, ifindex); return pllink ? pllink->connected : FALSE; } @@ -1309,10 +1335,6 @@ nm_platform_link_get_udev_device (NMPlatform *self, int ifindex) { const NMPObject *obj_cache; - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex >= 0, NULL); - obj_cache = nm_platform_link_get_obj (self, ifindex, FALSE); return obj_cache ? obj_cache->_link.udev.device : NULL; } @@ -1333,10 +1355,6 @@ nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex >= 0, FALSE); - pllink = nm_platform_link_get (self, ifindex); if (pllink && pllink->inet6_addr_gen_mode_inv) return _nm_platform_uint8_inv (pllink->inet6_addr_gen_mode_inv) == NM_IN6_ADDR_GEN_MODE_NONE; @@ -1352,14 +1370,14 @@ 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: %NM_PLATFORM_ERROR_SUCCESS if the operation was successful or an error code otherwise. + * Returns: the negative nm-error on failure. */ -NMPlatformError +int nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled) { - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (ifindex > 0, -NME_BUG); return klass->link_set_user_ipv6ll_enabled (self, ifindex, enabled); } @@ -1372,21 +1390,19 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea * * Set interface MAC address. */ -NMPlatformError +int nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) { gs_free char *mac = NULL; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (address, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (length > 0, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (ifindex > 0, -NME_BUG); + g_return_val_if_fail (address, -NME_BUG); + g_return_val_if_fail (length > 0, -NME_BUG); - _LOGD ("link: setting %s (%d) hardware address to %s", - nm_strquote_a (20, nm_platform_link_get_name (self, ifindex)), - ifindex, - (mac = nm_utils_hwaddr_ntoa (address, length))); + _LOG3D ("link: setting hardware address to %s", + (mac = nm_utils_hwaddr_ntoa (address, length))); return klass->link_set_address (self, ifindex, address, length); } @@ -1404,12 +1420,7 @@ nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, NULL); - - g_return_val_if_fail (ifindex > 0, NULL); - pllink = nm_platform_link_get (self, ifindex); - if ( !pllink || pllink->addr.len <= 0) { NM_SET_OUT (length, 0); @@ -1488,25 +1499,20 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) * @self: platform instance * @ifindex: the index of the interface to change * @num_vfs: the number of VFs to create - * @autoprobe: -1 to keep the current autoprobe-drivers value, - * or {0,1} to set a new value + * @autoprobe: the new autoprobe-drivers value (pass + * %NM_TERNARY_DEFAULT to keep current value) */ gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, - int autoprobe) + NMTernary autoprobe) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (NM_IN_SET (autoprobe, -1, 0, 1), FALSE); - _LOGD ("link: setting %u total VFs and autoprobe %d for %s (%d)", - num_vfs, - autoprobe, - nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), - ifindex); + _LOG3D ("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe); return klass->link_set_sriov_params (self, ifindex, num_vfs, autoprobe); } @@ -1518,14 +1524,11 @@ nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformV g_return_val_if_fail (ifindex > 0, FALSE); - _LOGD ("link: setting VFs for \"%s\" (%d):", - nm_platform_link_get_name (self, ifindex), - ifindex); - + _LOG3D ("link: setting VFs"); for (i = 0; vfs[i]; i++) { const NMPlatformVF *vf = vfs[i]; - _LOGD ("link: VF %s", nm_platform_vf_to_string (vf, NULL, 0)); + _LOG3D ("link: VF %s", nm_platform_vf_to_string (vf, NULL, 0)); } return klass->link_set_sriov_vfs (self, ifindex, vfs); @@ -1546,7 +1549,7 @@ nm_platform_link_set_up (NMPlatform *self, int ifindex, gboolean *out_no_firmwar g_return_val_if_fail (ifindex > 0, FALSE); - _LOGD ("link: setting up %s (%d)", nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); + _LOG3D ("link: setting up"); return klass->link_set_up (self, ifindex, out_no_firmware); } @@ -1564,7 +1567,7 @@ nm_platform_link_set_down (NMPlatform *self, int ifindex) g_return_val_if_fail (ifindex > 0, FALSE); - _LOGD ("link: setting down %s (%d)", nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); + _LOG3D ("link: setting down"); return klass->link_set_down (self, ifindex); } @@ -1582,7 +1585,7 @@ nm_platform_link_set_arp (NMPlatform *self, int ifindex) g_return_val_if_fail (ifindex >= 0, FALSE); - _LOGD ("link: setting arp %s (%d)", nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); + _LOG3D ("link: setting arp"); return klass->link_set_arp (self, ifindex); } @@ -1600,7 +1603,7 @@ nm_platform_link_set_noarp (NMPlatform *self, int ifindex) g_return_val_if_fail (ifindex >= 0, FALSE); - _LOGD ("link: setting noarp '%s' (%d)", nm_platform_link_get_name (self, ifindex), ifindex); + _LOG3D ("link: setting noarp"); return klass->link_set_noarp (self, ifindex); } @@ -1612,7 +1615,7 @@ nm_platform_link_set_noarp (NMPlatform *self, int ifindex) * * Set interface MTU. */ -NMPlatformError +int nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu) { _CHECK_SELF (self, klass, FALSE); @@ -1620,7 +1623,7 @@ nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu) g_return_val_if_fail (ifindex >= 0, FALSE); g_return_val_if_fail (mtu > 0, FALSE); - _LOGD ("link: setting '%s' (%d) mtu %"G_GUINT32_FORMAT, nm_platform_link_get_name (self, ifindex), ifindex, mtu); + _LOG3D ("link: setting mtu %"G_GUINT32_FORMAT, mtu); return klass->link_set_mtu (self, ifindex, mtu); } @@ -1636,8 +1639,6 @@ nm_platform_link_get_mtu (NMPlatform *self, int ifindex) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, 0); - pllink = nm_platform_link_get (self, ifindex); return pllink ? pllink->mtu : 0; } @@ -1658,7 +1659,7 @@ nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name) g_return_val_if_fail (ifindex >= 0, FALSE); g_return_val_if_fail (name, FALSE); - _LOGD ("link: setting '%s' (%d) name %s", nm_platform_link_get_name (self, ifindex), ifindex, name); + _LOG3D ("link: setting name %s", name); if (strlen (name) + 1 > IFNAMSIZ) return FALSE; @@ -1769,47 +1770,43 @@ nm_platform_link_get_driver_info (NMPlatform *self, * nm_platform_link_enslave: * @self: platform instance * @master: Interface index of the master - * @slave: Interface index of the slave + * @ifindex: Interface index of the slave * - * Enslave @slave to @master. + * Enslave @ifindex to @master. */ gboolean -nm_platform_link_enslave (NMPlatform *self, int master, int slave) +nm_platform_link_enslave (NMPlatform *self, int master, int ifindex) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (master > 0, FALSE); - g_return_val_if_fail (slave> 0, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); - _LOGD ("link: enslaving '%s' (%d) to master '%s' (%d)", - nm_platform_link_get_name (self, slave), slave, - nm_platform_link_get_name (self, master), master); - return klass->link_enslave (self, master, slave); + _LOG3D ("link: enslaving to master '%s'", nm_platform_link_get_name (self, master)); + return klass->link_enslave (self, master, ifindex); } /** * nm_platform_link_release: * @self: platform instance * @master: Interface index of the master - * @slave: Interface index of the slave + * @ifindex: Interface index of the slave * * Release @slave from @master. */ gboolean -nm_platform_link_release (NMPlatform *self, int master, int slave) +nm_platform_link_release (NMPlatform *self, int master, int ifindex) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (master > 0, FALSE); - g_return_val_if_fail (slave > 0, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); - if (nm_platform_link_get_master (self, slave) != master) + if (nm_platform_link_get_master (self, ifindex) != master) return FALSE; - _LOGD ("link: releasing '%s' (%d) from master '%s' (%d)", - nm_platform_link_get_name (self, slave), slave, - nm_platform_link_get_name (self, master), master); - return klass->link_release (self, master, slave); + _LOG3D ("link: releasing from master '%s'", nm_platform_link_get_name (self, master)); + return klass->link_release (self, master, ifindex); } /** @@ -1824,10 +1821,6 @@ nm_platform_link_get_master (NMPlatform *self, int slave) { const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, 0); - - g_return_val_if_fail (slave >= 0, FALSE); - pllink = nm_platform_link_get (self, slave); return pllink ? pllink->master : 0; } @@ -1865,7 +1858,7 @@ nm_platform_link_can_assume (NMPlatform *self, int ifindex) * Returns: the internal link lnk object. The returned object * is owned by the platform cache and must not be modified. Note * however, that the object is guaranteed to be immutable, so - * you can savely take a reference and keep it for yourself + * you can safely take a reference and keep it for yourself * (but don't modify it). */ const NMPObject * @@ -1873,15 +1866,11 @@ nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, c { const NMPObject *obj; - _CHECK_SELF (self, klass, FALSE); - - NM_SET_OUT (out_link, NULL); - - g_return_val_if_fail (ifindex > 0, NULL); - obj = nm_platform_link_get_obj (self, ifindex, TRUE); - if (!obj) + if (!obj) { + NM_SET_OUT (out_link, NULL); return NULL; + } NM_SET_OUT (out_link, &obj->link); @@ -1996,6 +1985,64 @@ nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatf /*****************************************************************************/ +int +nm_platform_link_wireguard_add (NMPlatform *self, + const char *name, + const NMPlatformLink **out_link) +{ + return nm_platform_link_add (self, name, NM_LINK_TYPE_WIREGUARD, NULL, NULL, 0, out_link); +} + +int +nm_platform_link_wireguard_change (NMPlatform *self, + int ifindex, + const NMPlatformLnkWireGuard *lnk_wireguard, + const NMPWireGuardPeer *peers, + guint peers_len, + gboolean replace_peers) +{ + _CHECK_SELF (self, klass, -NME_BUG); + + nm_assert (klass->link_wireguard_change); + + if (_LOGD_ENABLED ()) { + char buf_lnk[256]; + char buf_peers[512]; + + buf_peers[0] = '\0'; + if (peers_len > 0) { + char *b = buf_peers; + gsize len = sizeof (buf_peers); + guint i; + + nm_utils_strbuf_append_str (&b, &len, " { "); + for (i = 0; i < peers_len; i++) { + nm_utils_strbuf_append_str (&b, &len, " { "); + nm_platform_wireguard_peer_to_string (&peers[i], b, len); + nm_utils_strbuf_seek_end (&b, &len); + nm_utils_strbuf_append_str (&b, &len, " } "); + } + nm_utils_strbuf_append_str (&b, &len, "}"); + } + + _LOG3D ("link: change wireguard ifindex %d, %s, %u peers%s%s", + ifindex, + nm_platform_lnk_wireguard_to_string (lnk_wireguard, buf_lnk, sizeof (buf_lnk)), + peers_len, + buf_peers, + replace_peers ? " (replace-peers)" : " (update-peers)"); + } + + return klass->link_wireguard_change (self, + ifindex, + lnk_wireguard, + peers, + peers_len, + replace_peers); +} + +/*****************************************************************************/ + /** * nm_platform_link_bridge_add: * @self: platform instance @@ -2006,7 +2053,7 @@ nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatf * * Create a software bridge. */ -NMPlatformError +int nm_platform_link_bridge_add (NMPlatform *self, const char *name, const void *address, @@ -2024,7 +2071,7 @@ nm_platform_link_bridge_add (NMPlatform *self, * * Create a software bonding device. */ -NMPlatformError +int nm_platform_link_bond_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link) @@ -2040,7 +2087,7 @@ nm_platform_link_bond_add (NMPlatform *self, * * Create a software teaming device. */ -NMPlatformError +int nm_platform_link_team_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link) @@ -2058,7 +2105,7 @@ nm_platform_link_team_add (NMPlatform *self, * * Create a software VLAN device. */ -NMPlatformError +int nm_platform_link_vlan_add (NMPlatform *self, const char *name, int parent, @@ -2066,24 +2113,24 @@ nm_platform_link_vlan_add (NMPlatform *self, guint32 vlanflags, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (parent >= 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (vlanid >= 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (parent >= 0, -NME_BUG); + g_return_val_if_fail (vlanid >= 0, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_VLAN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_VLAN, out_link); + if (r < 0) + return r; - _LOGD ("link: adding link '%s': vlan parent %d vlanid %d vlanflags %x", - name, parent, vlanid, vlanflags); + _LOG2D ("link: adding link vlan parent %d vlanid %d vlanflags %x", + parent, vlanid, vlanflags); if (!klass->vlan_add (self, name, parent, vlanid, vlanflags, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2095,28 +2142,27 @@ nm_platform_link_vlan_add (NMPlatform *self, * * Create a VXLAN device. */ -NMPlatformError +int nm_platform_link_vxlan_add (NMPlatform *self, const char *name, const NMPlatformLnkVxlan *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_VXLAN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_VXLAN, out_link); + if (r < 0) + return r; - _LOGD ("link: adding link '%s': %s", - name, nm_platform_lnk_vxlan_to_string (props, NULL, 0)); + _LOG2D ("link: adding link %s", nm_platform_lnk_vxlan_to_string (props, NULL, 0)); if (!klass->link_vxlan_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2138,7 +2184,7 @@ nm_platform_link_vxlan_add (NMPlatform *self, * * Create a TUN or TAP interface. */ -NMPlatformError +int nm_platform_link_tun_add (NMPlatform *self, const char *name, const NMPlatformLnkTun *props, @@ -2146,30 +2192,29 @@ nm_platform_link_tun_add (NMPlatform *self, int *out_fd) { char b[255]; - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (NM_IN_SET (props->type, IFF_TUN, IFF_TAP), NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (name, -NME_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (NM_IN_SET (props->type, IFF_TUN, IFF_TAP), -NME_BUG); /* creating a non-persistant device requires that the caller handles * the file descriptor. */ - g_return_val_if_fail (props->persist || out_fd, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props->persist || out_fd, -NME_BUG); NM_SET_OUT (out_fd, -1); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_TUN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_TUN, out_link); + if (r < 0) + return r; - _LOGD ("link: adding link '%s': %s", - name, nm_platform_lnk_tun_to_string (props, b, sizeof (b))); + _LOG2D ("link: adding link %s", nm_platform_lnk_tun_to_string (props, b, sizeof (b))); if (!klass->link_tun_add (self, name, props, out_link, out_fd)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2181,39 +2226,38 @@ nm_platform_link_tun_add (NMPlatform *self, * * Create a 6LoWPAN interface. */ -NMPlatformError +int nm_platform_link_6lowpan_add (NMPlatform *self, const char *name, int parent, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_6LOWPAN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_6LOWPAN, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': 6lowpan parent %u", name, parent); + _LOG2D ("adding link 6lowpan parent %u", parent); if (!klass->link_6lowpan_add (self, name, parent, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } gboolean nm_platform_link_6lowpan_get_properties (NMPlatform *self, int ifindex, int *out_parent) { const NMPlatformLink *plink; - _CHECK_SELF (self, klass, FALSE); plink = nm_platform_link_get (self, ifindex); - if (!plink) return FALSE; + if (plink->type != NM_LINK_TYPE_6LOWPAN) return FALSE; @@ -2252,9 +2296,10 @@ link_set_option (NMPlatform *self, int ifindex, const char *category, const char if (dirfd < 0) return FALSE; - path = nm_sprintf_bufa (strlen (category) + strlen (option) + 2, - "%s/%s", - category, option); + path = nm_sprintf_buf_unsafe_a (strlen (category) + strlen (option) + 2, + "%s/%s", + category, + option); return nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_NETDIR_unsafe (dirfd, ifname_verified, path), value); } @@ -2272,9 +2317,9 @@ link_get_option (NMPlatform *self, int ifindex, const char *category, const char if (dirfd < 0) return NULL; - path = nm_sprintf_bufa (strlen (category) + strlen (option) + 2, - "%s/%s", - category, option); + path = nm_sprintf_buf_unsafe_a (strlen (category) + strlen (option) + 2, + "%s/%s", + category, option); return nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_NETDIR_unsafe (dirfd, ifname_verified, path)); } @@ -2407,7 +2452,7 @@ nm_platform_link_vlan_change (NMPlatform *self, nm_utils_strbuf_append_str (&b, &len, " (reset-all)"); } - _LOGD ("link: change vlan %d:%s", ifindex, buf); + _LOG3D ("link: change vlan %s", buf); } return klass->link_vlan_change (self, ifindex, @@ -2452,81 +2497,78 @@ nm_platform_link_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, i * * Create a software GRE device. */ -NMPlatformError +int nm_platform_link_gre_add (NMPlatform *self, const char *name, const NMPlatformLnkGre *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_gre_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_gre_to_string (props, NULL, 0)); if (!klass->link_gre_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } -static NMPlatformError +static int _infiniband_add_add_or_delete (NMPlatform *self, - int parent, + int ifindex, int p_key, gboolean add, const NMPlatformLink **out_link) { char name[IFNAMSIZ]; const NMPlatformLink *parent_link; - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (parent >= 0, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (ifindex >= 0, -NME_BUG); + g_return_val_if_fail (p_key >= 0 && p_key <= 0xffff, -NME_BUG); /* the special keys 0x0000 and 0x8000 are not allowed. */ if (NM_IN_SET (p_key, 0, 0x8000)) - return NM_PLATFORM_ERROR_UNSPECIFIED; + return -NME_UNSPEC; - parent_link = nm_platform_link_get (self, parent); + parent_link = nm_platform_link_get (self, ifindex); if (!parent_link) - return NM_PLATFORM_ERROR_NOT_FOUND; + return -NME_PL_NOT_FOUND; if (parent_link->type != NM_LINK_TYPE_INFINIBAND) - return NM_PLATFORM_ERROR_WRONG_TYPE; + return -NME_PL_WRONG_TYPE; 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); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - - _LOGD ("link: adding infiniband partition %s for parent '%s' (%d), key %d", - name, parent_link->name, parent, p_key); - if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_INFINIBAND, out_link); + if (r < 0) + return r; + + _LOG3D ("link: adding infiniband partition %s, key %d", name, p_key); + if (!klass->infiniband_partition_add (self, ifindex, p_key, out_link)) + return -NME_UNSPEC; } else { - _LOGD ("link: deleting infiniband partition %s for parent '%s' (%d), key %d", - name, parent_link->name, parent, p_key); + _LOG3D ("link: deleting infiniband partition %s, key %d", name, p_key); - if (!klass->infiniband_partition_delete (self, parent, p_key)) - return NM_PLATFORM_ERROR_UNSPECIFIED; + if (!klass->infiniband_partition_delete (self, ifindex, p_key)) + return -NME_UNSPEC; } - return NM_PLATFORM_ERROR_SUCCESS; + return 0; } -NMPlatformError +int nm_platform_link_infiniband_add (NMPlatform *self, int parent, int p_key, @@ -2535,7 +2577,7 @@ nm_platform_link_infiniband_add (NMPlatform *self, return _infiniband_add_add_or_delete (self, parent, p_key, TRUE, out_link); } -NMPlatformError +int nm_platform_link_infiniband_delete (NMPlatform *self, int parent, int p_key) @@ -2612,30 +2654,29 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self, * * Create an IPv6 tunnel. */ -NMPlatformError +int nm_platform_link_ip6tnl_add (NMPlatform *self, const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (!props->is_gre, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); + g_return_val_if_fail (!props->is_gre, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IP6TNL, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_IP6TNL, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); if (!klass->link_ip6tnl_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2647,35 +2688,34 @@ nm_platform_link_ip6tnl_add (NMPlatform *self, * * Create an IPv6 GRE/GRETAP tunnel. */ -NMPlatformError +int nm_platform_link_ip6gre_add (NMPlatform *self, const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (props->is_gre, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); + g_return_val_if_fail (props->is_gre, -NME_BUG); - plerr = _link_add_check_existing (self, - name, - props->is_tap - ? NM_LINK_TYPE_IP6GRETAP - : NM_LINK_TYPE_IP6GRE, - out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, + name, + props->is_tap + ? NM_LINK_TYPE_IP6GRETAP + : NM_LINK_TYPE_IP6GRE, + out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); if (!klass->link_ip6gre_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2687,29 +2727,28 @@ nm_platform_link_ip6gre_add (NMPlatform *self, * * Create an IPIP tunnel. */ -NMPlatformError +int nm_platform_link_ipip_add (NMPlatform *self, const char *name, const NMPlatformLnkIpIp *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IPIP, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_IPIP, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ipip_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_ipip_to_string (props, NULL, 0)); if (!klass->link_ipip_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2722,30 +2761,29 @@ nm_platform_link_ipip_add (NMPlatform *self, * * Create a MACsec interface. */ -NMPlatformError +int nm_platform_link_macsec_add (NMPlatform *self, const char *name, int parent, const NMPlatformLnkMacsec *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_MACSEC, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_MACSEC, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macsec_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_macsec_to_string (props, NULL, 0)); if (!klass->link_macsec_add (self, name, parent, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2757,33 +2795,32 @@ nm_platform_link_macsec_add (NMPlatform *self, * * Create a MACVLAN or MACVTAP device. */ -NMPlatformError +int nm_platform_link_macvlan_add (NMPlatform *self, const char *name, int parent, const NMPlatformLnkMacvlan *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; NMLinkType type; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); type = props->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; - plerr = _link_add_check_existing (self, name, type, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, type, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macvlan_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_macvlan_to_string (props, NULL, 0)); if (!klass->link_macvlan_add (self, name, parent, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } /** @@ -2795,29 +2832,28 @@ nm_platform_link_macvlan_add (NMPlatform *self, * * Create a software SIT device. */ -NMPlatformError +int nm_platform_link_sit_add (NMPlatform *self, const char *name, const NMPlatformLnkSit *props, const NMPlatformLink **out_link) { - NMPlatformError plerr; + int r; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + _CHECK_SELF (self, klass, -NME_BUG); - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (props, -NME_BUG); + g_return_val_if_fail (name, -NME_BUG); - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_SIT, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; + r = _link_add_check_existing (self, name, NM_LINK_TYPE_SIT, out_link); + if (r < 0) + return r; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_sit_to_string (props, NULL, 0)); + _LOG2D ("adding link %s", nm_platform_lnk_sit_to_string (props, NULL, 0)); if (!klass->link_sit_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; + return -NME_UNSPEC; + return 0; } gboolean @@ -2825,12 +2861,11 @@ nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_pe { const NMPlatformLink *plink; int peer_ifindex; - _CHECK_SELF (self, klass, FALSE); plink = nm_platform_link_get (self, ifindex); - if (!plink) return FALSE; + if (plink->type != NM_LINK_TYPE_VETH) return FALSE; @@ -2888,14 +2923,11 @@ nm_platform_link_tun_get_properties (NMPlatform *self, gint64 group; gint64 flags; - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - /* we consider also invisible links (those that are not yet in udev). */ plobj = nm_platform_link_get_obj (self, ifindex, FALSE); if (!plobj) return FALSE; + if (NMP_OBJECT_CAST_LINK (plobj)->type != NM_LINK_TYPE_TUN) return FALSE; @@ -3148,6 +3180,16 @@ nm_platform_wpan_set_short_addr (NMPlatform *self, int ifindex, guint16 short_ad return klass->wpan_set_short_addr (self, ifindex, short_addr); } +gboolean +nm_platform_wpan_set_channel (NMPlatform *self, int ifindex, guint8 page, guint8 channel) +{ + _CHECK_SELF (self, klass, FALSE); + + g_return_val_if_fail (ifindex > 0, FALSE); + + return klass->wpan_set_channel (self, ifindex, page, channel); +} + #define TO_STRING_DEV_BUF_SIZE (5+15+1) static const char * _to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size) @@ -3387,7 +3429,7 @@ nm_platform_ip4_address_add (NMPlatform *self, 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)); + _LOG3D ("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, flags, label); } @@ -3421,7 +3463,7 @@ nm_platform_ip6_address_add (NMPlatform *self, addr.preferred = preferred; addr.n_ifa_flags = flags; - _LOGD ("address: adding or updating IPv6 address: %s", nm_platform_ip6_address_to_string (&addr, NULL, 0)); + _LOG3D ("address: adding or updating IPv6 address: %s", nm_platform_ip6_address_to_string (&addr, NULL, 0)); } return klass->ip6_address_add (self, ifindex, address, plen, peer_address, lifetime, preferred, flags); } @@ -3430,20 +3472,24 @@ gboolean nm_platform_ip4_address_delete (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address) { char str_dev[TO_STRING_DEV_BUF_SIZE]; - char str_peer2[NM_UTILS_INET_ADDRSTRLEN]; - char str_peer[100]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char str_peer[INET_ADDRSTRLEN + 50]; _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen <= 32, FALSE); - _LOGD ("address: deleting IPv4 address %s/%d, %sifindex %d%s", - nm_utils_inet4_ntop (address, NULL), plen, - peer_address != address - ? nm_sprintf_buf (str_peer, "peer %s, ", nm_utils_inet4_ntop (peer_address, str_peer2)) : "", - ifindex, - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); + _LOG3D ("address: deleting IPv4 address %s/%d, %s%s", + nm_utils_inet4_ntop (address, b1), + plen, + peer_address != address + ? nm_sprintf_buf (str_peer, + "peer %s, ", + nm_utils_inet4_ntop (peer_address, b2)) + : "", + _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); return klass->ip4_address_delete (self, ifindex, address, plen, peer_address); } @@ -3451,15 +3497,16 @@ gboolean nm_platform_ip6_address_delete (NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen) { char str_dev[TO_STRING_DEV_BUF_SIZE]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen <= 128, FALSE); - _LOGD ("address: deleting IPv6 address %s/%d, ifindex %d%s", - nm_utils_inet6_ntop (&address, NULL), plen, ifindex, - _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); + _LOG3D ("address: deleting IPv6 address %s/%d, %s", + nm_utils_inet6_ntop (&address, sbuf), plen, + _to_string_dev (self, ifindex, str_dev, sizeof (str_dev))); return klass->ip6_address_delete (self, ifindex, address, plen); } @@ -3711,7 +3758,7 @@ ip4_addr_subnets_is_secondary (const NMPObject *address, * That means, expired addresses and addresses that could not be added * will be dropped. * Hence, the input argument @known_addresses is also an output argument - * telling which addresses were succesfully added. + * telling which addresses were successfully added. * Addresses are removed by unrefing the instance via nmp_object_unref() * and leaving a NULL tombstone. * @@ -3885,7 +3932,7 @@ ip6_address_scope_cmp (gconstpointer a, gconstpointer b) * That means, expired addresses and addresses that could not be added * will be dropped. * Hence, the input argument @known_addresses is also an output argument - * telling which addresses were succesfully added. + * telling which addresses were successfully added. * Addresses are removed by unrefing the instance via nmp_object_unref() * and leaving a NULL tombstone. * @full_sync: Also remove link-local and temporary addresses. @@ -4193,7 +4240,6 @@ nm_platform_ip_route_sync (NMPlatform *self, gboolean success = TRUE; char sbuf1[sizeof (_nm_utils_to_string_buffer)]; char sbuf2[sizeof (_nm_utils_to_string_buffer)]; - char sbuf_err[60]; nm_assert (NM_IS_PLATFORM (self)); nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); @@ -4205,7 +4251,7 @@ nm_platform_ip_route_sync (NMPlatform *self, for (i_type = 0; routes && i_type < 2; i_type++) { for (i = 0; i < routes->len; i++) { - NMPlatformError plerr, plerr2; + int r, r2; gboolean gateway_route_added = FALSE; conf_o = routes->pdata[i]; @@ -4227,8 +4273,8 @@ nm_platform_ip_route_sync (NMPlatform *self, (GEqualFunc) nmp_object_id_equal); } if (!g_hash_table_insert (routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { - _LOGD ("route-sync: skip adding duplicate route %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); + _LOG3D ("route-sync: skip adding duplicate route %s", + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); continue; } @@ -4245,7 +4291,7 @@ nm_platform_ip_route_sync (NMPlatform *self, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0) continue; - /* we need to replace the existing route with a (slightly) differnt + /* we need to replace the existing route with a (slightly) different * one. Delete it first. */ if (!nm_platform_object_delete (self, plat_o)) { /* ignore error. */ @@ -4253,12 +4299,12 @@ nm_platform_ip_route_sync (NMPlatform *self, } sync_route_add: - plerr = nm_platform_ip_route_add (self, - NMP_NLM_FLAG_APPEND - | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, - conf_o); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) { - if (-((int) plerr) == EEXIST) { + r = nm_platform_ip_route_add (self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + conf_o); + if (r < 0) { + if (r == -EEXIST) { /* Don't fail for EEXIST. It's not clear that the existing route * is identical to the one that we were about to add. However, * above we should have deleted conflicting (non-identical) routes. */ @@ -4267,92 +4313,92 @@ sync_route_add: NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); if (!plat_entry) { - _LOGD ("route-sync: adding route %s failed with EEXIST, however we cannot find such a route", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); + _LOG3D ("route-sync: adding route %s failed with EEXIST, however we cannot find such a route", + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); } else if (vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), NMP_OBJECT_CAST_IPX_ROUTE (plat_entry->obj), NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) != 0) { - _LOGD ("route-sync: adding route %s failed due to existing (different!) route %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nmp_object_to_string (plat_entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); + _LOG3D ("route-sync: adding route %s failed due to existing (different!) route %s", + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), + nmp_object_to_string (plat_entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); } } } else if (NMP_OBJECT_CAST_IP_ROUTE (conf_o)->rt_source < NM_IP_CONFIG_SOURCE_USER) { - _LOGD ("route-sync: ignore failure to add IPv%c route: %s: %s", + _LOG3D ("route-sync: ignore failure to add IPv%c route: %s: %s", vt->is_ip4 ? '4' : '6', nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_platform_error_to_string (plerr, sbuf_err, sizeof (sbuf_err))); - } else if ( -((int) plerr) == EINVAL + nm_strerror (r)); + } else if ( r == -EINVAL && out_temporary_not_available && _err_inval_due_to_ipv6_tentative_pref_src (self, conf_o)) { - _LOGD ("route-sync: ignore failure to add IPv6 route with tentative IPv6 pref-src: %s: %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_platform_error_to_string (plerr, sbuf_err, sizeof (sbuf_err))); + _LOG3D ("route-sync: ignore failure to add IPv6 route with tentative IPv6 pref-src: %s: %s", + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), + nm_strerror (r)); if (!*out_temporary_not_available) *out_temporary_not_available = g_ptr_array_new_full (0, (GDestroyNotify) nmp_object_unref); g_ptr_array_add (*out_temporary_not_available, (gpointer) nmp_object_ref (conf_o)); } else if ( !gateway_route_added - && ( ( -((int) plerr) == ENETUNREACH + && ( ( r == -ENETUNREACH && vt->is_ip4 && !!NMP_OBJECT_CAST_IP4_ROUTE (conf_o)->gateway) - || ( -((int) plerr) == EHOSTUNREACH + || ( r == -EHOSTUNREACH && !vt->is_ip4 && !IN6_IS_ADDR_UNSPECIFIED (&NMP_OBJECT_CAST_IP6_ROUTE (conf_o)->gateway)))) { NMPObject oo; if (vt->is_ip4) { - const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (conf_o); + const NMPlatformIP4Route *rt = NMP_OBJECT_CAST_IP4_ROUTE (conf_o); nmp_object_stackinit (&oo, NMP_OBJECT_TYPE_IP4_ROUTE, &((NMPlatformIP4Route) { - .ifindex = r->ifindex, - .network = r->gateway, + .ifindex = rt->ifindex, + .network = rt->gateway, .plen = 32, - .metric = r->metric, - .rt_source = r->rt_source, - .table_coerced = r->table_coerced, + .metric = rt->metric, + .rt_source = rt->rt_source, + .table_coerced = rt->table_coerced, })); } else { - const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (conf_o); + const NMPlatformIP6Route *rt = NMP_OBJECT_CAST_IP6_ROUTE (conf_o); nmp_object_stackinit (&oo, NMP_OBJECT_TYPE_IP6_ROUTE, &((NMPlatformIP6Route) { - .ifindex = r->ifindex, - .network = r->gateway, + .ifindex = rt->ifindex, + .network = rt->gateway, .plen = 128, - .metric = r->metric, - .rt_source = r->rt_source, - .table_coerced = r->table_coerced, + .metric = rt->metric, + .rt_source = rt->rt_source, + .table_coerced = rt->table_coerced, })); } - _LOGD ("route-sync: failure to add IPv%c route: %s: %s; try adding direct route to gateway %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_platform_error_to_string (plerr, sbuf_err, sizeof (sbuf_err)), - nmp_object_to_string (&oo, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); - - plerr2 = nm_platform_ip_route_add (self, - NMP_NLM_FLAG_APPEND - | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, - &oo); - - if (plerr2 != NM_PLATFORM_ERROR_SUCCESS) { - _LOGD ("route-sync: failure to add gateway IPv%c route: %s: %s", - vt->is_ip4 ? '4' : '6', - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_platform_error_to_string (plerr, sbuf_err, sizeof (sbuf_err))); + _LOG3D ("route-sync: failure to add IPv%c route: %s: %s; try adding direct route to gateway %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), + nm_strerror (r), + nmp_object_to_string (&oo, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); + + r2 = nm_platform_ip_route_add (self, + NMP_NLM_FLAG_APPEND + | NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE, + &oo); + + if (r2 < 0) { + _LOG3D ("route-sync: failure to add gateway IPv%c route: %s: %s", + vt->is_ip4 ? '4' : '6', + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), + nm_strerror (r2)); } gateway_route_added = TRUE; goto sync_route_add; } else { - _LOGW ("route-sync: failure to add IPv%c route: %s: %s", + _LOG3W ("route-sync: failure to add IPv%c route: %s: %s", vt->is_ip4 ? '4' : '6', nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nm_platform_error_to_string (plerr, sbuf_err, sizeof (sbuf_err))); + nm_strerror (r)); success = FALSE; } } @@ -4494,30 +4540,32 @@ nm_platform_ip_route_normalize (int addr_family, } } -static NMPlatformError +static int _ip_route_add (NMPlatform *self, NMPNlmFlags flags, int addr_family, gconstpointer route) { char sbuf[sizeof (_nm_utils_to_string_buffer)]; + int ifindex; _CHECK_SELF (self, klass, FALSE); nm_assert (route); nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - _LOGD ("route: %-10s IPv%c route: %s", - _nmp_nlm_flag_to_string (flags & NMP_NLM_FLAG_FMASK), - nm_utils_addr_family_to_char (addr_family), - addr_family == AF_INET - ? nm_platform_ip4_route_to_string (route, sbuf, sizeof (sbuf)) - : nm_platform_ip6_route_to_string (route, sbuf, sizeof (sbuf))); + ifindex = ((NMPlatformObject *)route)->ifindex; + _LOG3D ("route: %-10s IPv%c route: %s", + _nmp_nlm_flag_to_string (flags & NMP_NLM_FLAG_FMASK), + nm_utils_addr_family_to_char (addr_family), + addr_family == AF_INET + ? nm_platform_ip4_route_to_string (route, sbuf, sizeof (sbuf)) + : nm_platform_ip6_route_to_string (route, sbuf, sizeof (sbuf))); return klass->ip_route_add (self, flags, addr_family, route); } -NMPlatformError +int nm_platform_ip_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPObject *route) @@ -4538,7 +4586,7 @@ nm_platform_ip_route_add (NMPlatform *self, return _ip_route_add (self, flags, addr_family, NMP_OBJECT_CAST_IP_ROUTE (route)); } -NMPlatformError +int nm_platform_ip4_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route) @@ -4546,7 +4594,7 @@ nm_platform_ip4_route_add (NMPlatform *self, return _ip_route_add (self, flags, AF_INET, route); } -NMPlatformError +int nm_platform_ip6_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route) @@ -4558,6 +4606,7 @@ gboolean nm_platform_object_delete (NMPlatform *self, const NMPObject *obj) { + int ifindex = obj->object.ifindex; _CHECK_SELF (self, klass, FALSE); if (!NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), NMP_OBJECT_TYPE_IP4_ROUTE, @@ -4566,16 +4615,16 @@ nm_platform_object_delete (NMPlatform *self, NMP_OBJECT_TYPE_TFILTER)) g_return_val_if_reached (FALSE); - _LOGD ("%s: delete %s", - NMP_OBJECT_GET_CLASS (obj)->obj_type_name, - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + _LOG3D ("%s: delete %s", + NMP_OBJECT_GET_CLASS (obj)->obj_type_name, + nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); return klass->object_delete (self, obj); } /*****************************************************************************/ -NMPlatformError +int nm_platform_ip_route_get (NMPlatform *self, int addr_family, gconstpointer address /* in_addr_t or struct in6_addr */, @@ -4583,16 +4632,15 @@ nm_platform_ip_route_get (NMPlatform *self, NMPObject **out_route) { nm_auto_nmpobj NMPObject *route = NULL; - NMPlatformError result; + int result; char buf[NM_UTILS_INET_ADDRSTRLEN]; - char buf_err[200]; char buf_oif[64]; _CHECK_SELF (self, klass, FALSE); - g_return_val_if_fail (address, NM_PLATFORM_ERROR_BUG); + g_return_val_if_fail (address, -NME_BUG); g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, - AF_INET6), NM_PLATFORM_ERROR_BUG); + AF_INET6), -NME_BUG); _LOGT ("route: get IPv%c route for: %s%s", nm_utils_addr_family_to_char (addr_family), @@ -4600,7 +4648,7 @@ nm_platform_ip_route_get (NMPlatform *self, oif_ifindex > 0 ? nm_sprintf_buf (buf_oif, " oif %d", oif_ifindex) : ""); if (!klass->ip_route_get) - result = NM_PLATFORM_ERROR_OPNOTSUPP; + result = -NME_PL_OPNOTSUPP; else { result = klass->ip_route_get (self, addr_family, @@ -4609,12 +4657,12 @@ nm_platform_ip_route_get (NMPlatform *self, &route); } - if (result != NM_PLATFORM_ERROR_SUCCESS) { + if (result < 0) { nm_assert (!route); _LOGW ("route: get IPv%c route for: %s failed with %s", nm_utils_addr_family_to_char (addr_family), inet_ntop (addr_family, address, buf, sizeof (buf)), - nm_platform_error_to_string (result, buf_err, sizeof (buf_err))); + nm_strerror (result)); } else { nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (route), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); nm_assert (!NMP_OBJECT_IS_STACKINIT (route)); @@ -4807,7 +4855,7 @@ _ip4_dev_route_blacklist_schedule (NMPlatform *self) * route, however it has a wrong metric of zero. We add our own device route (with * proper metric), but need to delete the route that kernel adds. * - * The problem is, that kernel does not immidiately add the route, when adding + * The problem is, that kernel does not immediately add the route, when adding * the address. It only shows up some time later. So, we register here a list * of blacklisted routes, and when they show up within a time out, we assume it's * the kernel generated one, and we delete it. @@ -4898,14 +4946,15 @@ nm_platform_ip4_dev_route_blacklist_set (NMPlatform *self, /*****************************************************************************/ -NMPlatformError +int nm_platform_qdisc_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc) { - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + int ifindex = qdisc->ifindex; + _CHECK_SELF (self, klass, -NME_BUG); - _LOGD ("adding or updating a qdisc: %s", nm_platform_qdisc_to_string (qdisc, NULL, 0)); + _LOG3D ("adding or updating a qdisc: %s", nm_platform_qdisc_to_string (qdisc, NULL, 0)); return klass->qdisc_add (self, flags, qdisc); } @@ -4954,7 +5003,7 @@ nm_platform_qdisc_sync (NMPlatform *self, const NMPObject *q = g_ptr_array_index (known_qdiscs, i); success &= (nm_platform_qdisc_add (self, NMP_NLM_FLAG_ADD, - NMP_OBJECT_CAST_QDISC (q)) == NM_PLATFORM_ERROR_SUCCESS); + NMP_OBJECT_CAST_QDISC (q)) >= 0); } } @@ -4963,14 +5012,15 @@ nm_platform_qdisc_sync (NMPlatform *self, /*****************************************************************************/ -NMPlatformError +int nm_platform_tfilter_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter) { - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); + int ifindex = tfilter->ifindex; + _CHECK_SELF (self, klass, -NME_BUG); - _LOGD ("adding or updating a tfilter: %s", nm_platform_tfilter_to_string (tfilter, NULL, 0)); + _LOG3D ("adding or updating a tfilter: %s", nm_platform_tfilter_to_string (tfilter, NULL, 0)); return klass->tfilter_add (self, flags, tfilter); } @@ -5019,7 +5069,7 @@ nm_platform_tfilter_sync (NMPlatform *self, const NMPObject *q = g_ptr_array_index (known_tfilters, i); success &= (nm_platform_tfilter_add (self, NMP_NLM_FLAG_ADD, - NMP_OBJECT_CAST_TFILTER (q)) == NM_PLATFORM_ERROR_SUCCESS); + NMP_OBJECT_CAST_TFILTER (q)) >= 0); } } @@ -5477,6 +5527,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize char str_dst_port[25]; char str_tos[25]; char str_ttl[25]; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) return buf; @@ -5487,7 +5538,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize g_snprintf (str_group, sizeof (str_group), " %s %s", IN_MULTICAST (ntohl (lnk->group)) ? "group" : "remote", - nm_utils_inet4_ntop (lnk->group, NULL)); + nm_utils_inet4_ntop (lnk->group, sbuf)); } if (IN6_IS_ADDR_UNSPECIFIED (&lnk->group6)) str_group6[0] = '\0'; @@ -5496,7 +5547,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize " %s%s %s", IN6_IS_ADDR_MULTICAST (&lnk->group6) ? "group" : "remote", str_group[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ - nm_utils_inet6_ntop (&lnk->group6, NULL)); + nm_utils_inet6_ntop (&lnk->group6, sbuf)); } if (lnk->local == 0) @@ -5504,7 +5555,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize else { g_snprintf (str_local, sizeof (str_local), " local %s", - nm_utils_inet4_ntop (lnk->local, NULL)); + nm_utils_inet4_ntop (lnk->local, sbuf)); } if (IN6_IS_ADDR_UNSPECIFIED (&lnk->local6)) str_local6[0] = '\0'; @@ -5512,7 +5563,7 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize g_snprintf (str_local6, sizeof (str_local6), " local%s %s", str_local[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */ - nm_utils_inet6_ntop (&lnk->local6, NULL)); + nm_utils_inet6_ntop (&lnk->local6, sbuf)); } g_snprintf (buf, len, @@ -5554,28 +5605,26 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize const char * nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, gsize len) { + char *buf0 = buf; gs_free char *public_key_b64 = NULL; - char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100]; + char s_sockaddr[NM_UTILS_INET_ADDRSTRLEN + 100]; + char s_endpoint[20 + sizeof (s_sockaddr)]; char s_addr[NM_UTILS_INET_ADDRSTRLEN]; guint i; nm_utils_to_string_buffer_init (&buf, &len); - if (peer->endpoint_family == AF_INET) { - nm_sprintf_buf (s_endpoint, - " endpoint %s:%u", - nm_utils_inet4_ntop (peer->endpoint_addr.addr4, s_addr), - (guint) peer->endpoint_port); - } else if (peer->endpoint_family == AF_INET6) { + public_key_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key)); + + if (peer->endpoint.sa.sa_family != AF_UNSPEC) { nm_sprintf_buf (s_endpoint, - " endpoint [%s]:%u", - nm_utils_inet6_ntop (&peer->endpoint_addr.addr6, s_addr), - (guint) peer->endpoint_port); + " endpoint %s", + nm_sock_addr_union_to_string (&peer->endpoint, + s_sockaddr, + sizeof (s_sockaddr))); } else s_endpoint[0] = '\0'; - public_key_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key)); - nm_utils_strbuf_append (&buf, &len, "public-key %s" "%s" /* preshared-key */ @@ -5584,7 +5633,7 @@ nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, g " tx %"G_GUINT64_FORMAT "%s", /* allowed-ips */ public_key_b64, - nm_utils_mem_all_zero (peer->preshared_key, sizeof (peer->preshared_key)) + nm_utils_memeqzero (peer->preshared_key, sizeof (peer->preshared_key)) ? "" : " preshared-key (hidden)", s_endpoint, @@ -5603,7 +5652,7 @@ nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, g allowed_ip->mask); } - return buf; + return buf0; } const char * @@ -5614,7 +5663,7 @@ nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *bu if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) return buf; - if (!nm_utils_mem_all_zero (lnk->public_key, sizeof (lnk->public_key))) + if (!nm_utils_memeqzero (lnk->public_key, sizeof (lnk->public_key))) public_b64 = g_base64_encode (lnk->public_key, sizeof (lnk->public_key)); g_snprintf (buf, len, @@ -5627,7 +5676,7 @@ nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *bu ? " public-key " : "", public_b64 ?: "", - nm_utils_mem_all_zero (lnk->private_key, sizeof (lnk->private_key)) + nm_utils_memeqzero (lnk->private_key, sizeof (lnk->private_key)) ? "" : " private-key (hidden)", lnk->listen_port, @@ -5926,13 +5975,21 @@ nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsi const char * nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len) { - char s_network[INET6_ADDRSTRLEN], s_gateway[INET6_ADDRSTRLEN], s_pref_src[INET6_ADDRSTRLEN]; - char s_src_all[INET6_ADDRSTRLEN + 40], s_src[INET6_ADDRSTRLEN]; + char s_network[INET6_ADDRSTRLEN]; + char s_gateway[INET6_ADDRSTRLEN]; + char s_pref_src[INET6_ADDRSTRLEN]; + char s_src_all[INET6_ADDRSTRLEN + 40]; + char s_src[INET6_ADDRSTRLEN]; char str_table[30]; char str_pref[40]; char str_pref2[30]; - char str_dev[TO_STRING_DEV_BUF_SIZE], s_source[50]; - char str_window[32], str_cwnd[32], str_initcwnd[32], str_initrwnd[32], str_mtu[32]; + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char s_source[50]; + char str_window[32]; + char str_cwnd[32]; + char str_initcwnd[32]; + char str_initrwnd[32]; + char str_mtu[32]; char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; if (!nm_utils_to_string_buffer_init_null (route, &buf, &len)) @@ -6982,7 +7039,7 @@ nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPlatfor /* if the lifetime is equal, compare the preferred time. */ ta = tb = 0; - if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0 /* liftime==0 means permanent! */) + if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0 /* lifetime==0 means permanent! */) ta = G_MAXINT64; else if (a->timestamp) ta = ((gint64) a->timestamp) + a->preferred; @@ -7017,44 +7074,43 @@ nm_platform_signal_change_type_to_string (NMPlatformSignalChangeType change_type static void log_link (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformLink *device, NMPlatformSignalChangeType change_type, gpointer user_data) { - - _LOGD ("signal: link %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_link_to_string (device, NULL, 0)); + _LOG3D ("signal: link %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_link_to_string (device, NULL, 0)); } static void log_ip4_address (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: address 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_address_to_string (address, NULL, 0)); + _LOG3D ("signal: address 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_address_to_string (address, NULL, 0)); } static void log_ip6_address (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP6Address *address, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: address 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_address_to_string (address, NULL, 0)); + _LOG3D ("signal: address 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_address_to_string (address, NULL, 0)); } static void log_ip4_route (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP4Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: route 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_route_to_string (route, NULL, 0)); + _LOG3D ("signal: route 4 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip4_route_to_string (route, NULL, 0)); } static void log_ip6_route (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformIP6Route *route, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: route 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_route_to_string (route, NULL, 0)); + _LOG3D ("signal: route 6 %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_ip6_route_to_string (route, NULL, 0)); } static void log_qdisc (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformQdisc *qdisc, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: qdisc %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_qdisc_to_string (qdisc, NULL, 0)); + _LOG3D ("signal: qdisc %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_qdisc_to_string (qdisc, NULL, 0)); } static void log_tfilter (NMPlatform *self, NMPObjectType obj_type, int ifindex, NMPlatformTfilter *tfilter, NMPlatformSignalChangeType change_type, gpointer user_data) { - _LOGD ("signal: tfilter %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_tfilter_to_string (tfilter, NULL, 0)); + _LOG3D ("signal: tfilter %7s: %s", nm_platform_signal_change_type_to_string (change_type), nm_platform_tfilter_to_string (tfilter, NULL, 0)); } /*****************************************************************************/ @@ -7069,6 +7125,7 @@ nm_platform_cache_update_emit_signal (NMPlatform *self, gboolean visible_old; const NMPObject *o; const NMPClass *klass; + int ifindex; nm_assert (NM_IN_SET ((NMPlatformSignalChangeType) cache_op, NM_PLATFORM_SIGNAL_NONE, NM_PLATFORM_SIGNAL_ADDED, @@ -7110,6 +7167,7 @@ nm_platform_cache_update_emit_signal (NMPlatform *self, return; } + ifindex = o->object.ifindex; klass = NMP_OBJECT_GET_CLASS (o); if ( klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE @@ -7117,10 +7175,10 @@ nm_platform_cache_update_emit_signal (NMPlatform *self, && NM_IN_SET (cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED)) _ip4_dev_route_blacklist_notify_route (self, o); - _LOGt ("emit signal %s %s: %s", - klass->signal_type, - nm_platform_signal_change_type_to_string ((NMPlatformSignalChangeType) cache_op), - nmp_object_to_string (o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); + _LOG3t ("emit signal %s %s: %s", + klass->signal_type, + nm_platform_signal_change_type_to_string ((NMPlatformSignalChangeType) cache_op), + nmp_object_to_string (o, NMP_OBJECT_TO_STRING_PUBLIC, NULL, 0)); nmp_object_ref (o); g_signal_emit (self, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 2bf5966c..412ac597 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -21,12 +21,6 @@ #ifndef __NETWORKMANAGER_PLATFORM_H__ #define __NETWORKMANAGER_PLATFORM_H__ -#include <netinet/in.h> -#include <linux/if.h> -#include <linux/if_addr.h> -#include <linux/if_link.h> -#include <linux/ip6_tunnel.h> - #include "nm-dbus-interface.h" #include "nm-core-types-internal.h" @@ -35,6 +29,7 @@ #include "nm-setting-wired.h" #include "nm-setting-wireless.h" #include "nm-setting-ip-tunnel.h" +#include "nm-utils/nm-errno.h" #define NM_TYPE_PLATFORM (nm_platform_get_type ()) #define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform)) @@ -53,6 +48,14 @@ /*****************************************************************************/ +/* IFNAMSIZ is both defined in <linux/if.h> and <net/if.h>. In the past, these + * headers conflicted, so we cannot simply include either of them in a header-file.*/ +#define NMP_IFNAMSIZ 16 + +/*****************************************************************************/ + +struct _NMPWireGuardPeer; + struct udev_device; typedef gboolean (*NMPObjectPredicateFunc) (const NMPObject *obj, @@ -149,29 +152,6 @@ typedef enum { } NMPlatformIPRouteCmpType; -typedef enum { /*< skip >*/ - - /* dummy value, to enforce that the enum type is signed and has a size - * to hold an integer. We want to encode errno from <errno.h> as negative - * values. */ - _NM_PLATFORM_ERROR_MININT = G_MININT, - - NM_PLATFORM_ERROR_SUCCESS = 0, - - NM_PLATFORM_ERROR_BUG, - - NM_PLATFORM_ERROR_UNSPECIFIED, - - NM_PLATFORM_ERROR_NOT_FOUND, - NM_PLATFORM_ERROR_EXISTS, - NM_PLATFORM_ERROR_WRONG_TYPE, - NM_PLATFORM_ERROR_NOT_SLAVE, - NM_PLATFORM_ERROR_NO_FIRMWARE, - NM_PLATFORM_ERROR_OPNOTSUPP, - NM_PLATFORM_ERROR_NETLINK, - NM_PLATFORM_ERROR_CANT_SET_MTU, -} NMPlatformError; - typedef enum { /* match-flags are strictly inclusive. That means, @@ -208,7 +188,7 @@ typedef enum { struct _NMPlatformLink { __NMPlatformObject_COMMON; - char name[IFNAMSIZ]; + char name[NMP_IFNAMSIZ]; NMLinkType type; /* rtnl_link_get_type(), IFLA_INFO_KIND. */ @@ -299,10 +279,10 @@ struct _NMPlatformObject { * are permanent. This rule is so that unset addresses (calloc) are permanent by default. * 2 @lifetime==@preferred==NM_PLATFORM_LIFETIME_PERMANENT: @timestamp is irrelevant (but mostly * set to 0). Such addresses are permanent. - * 3 Non permanent addreses should (almost) always have @timestamp > 0. 0 is not a valid timestamp + * 3 Non permanent addresses should (almost) always have @timestamp > 0. 0 is not a valid timestamp * and never returned by nm_utils_get_monotonic_timestamp_s(). In this case @valid/@preferred * is anchored at @timestamp. - * 4 Non permanent addresses with @timestamp == 0 are implicitely anchored at *now*, thus the time + * 4 Non permanent addresses with @timestamp == 0 are implicitly anchored at *now*, thus the time * moves as time goes by. This is usually not useful, except e.g. nm_platform_ip[46]_address_add(). * * Non permanent addresses from DHCP/RA might have the @timestamp set to the moment of when the @@ -355,7 +335,7 @@ struct _NMPlatformIP4Address { * */ in_addr_t peer_address; /* PTP peer address */ - char label[IFNAMSIZ]; + char label[NMP_IFNAMSIZ]; }; /** @@ -417,7 +397,7 @@ typedef union { * On the other hand, for IPv6 you cannot add two IPv6 routes that only differ * by an RTA_METRICS property. * - * When deleting a route, kernel seems to ignore the RTA_METRICS propeties. + * When deleting a route, kernel seems to ignore the RTA_METRICS properties. * That is a problem/bug for IPv4 because you cannot explicitly select which * route to delete. Kernel just picks the first. See rh#1475642. */ \ \ @@ -792,13 +772,14 @@ typedef struct { void (*refresh_all) (NMPlatform *self, NMPObjectType obj_type); - gboolean (*link_add) (NMPlatform *, - const char *name, - NMLinkType type, - const char *veth_peer, - const void *address, - size_t address_len, - const NMPlatformLink **out_link); + int (*link_add) (NMPlatform *, + const char *name, + NMLinkType type, + const char *veth_peer, + const void *address, + size_t address_len, + const NMPlatformLink **out_link); + gboolean (*link_delete) (NMPlatform *, int ifindex); gboolean (*link_refresh) (NMPlatform *, int ifindex); @@ -815,15 +796,15 @@ typedef struct { const char *(*link_get_udi) (NMPlatform *self, int ifindex); struct udev_device *(*link_get_udev_device) (NMPlatform *self, int ifindex); - NMPlatformError (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + int (*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); - NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); - NMPlatformError (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); + int (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); + int (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name); gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe); gboolean (*link_set_sriov_vfs) (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); @@ -846,6 +827,13 @@ typedef struct { gboolean (*link_can_assume) (NMPlatform *, int ifindex); + int (*link_wireguard_change) (NMPlatform *self, + int ifindex, + const NMPlatformLnkWireGuard *lnk_wireguard, + const struct _NMPWireGuardPeer *peers, + guint peers_len, + gboolean replace_peers); + gboolean (*vlan_add) (NMPlatform *, const char *name, int parent, int vlanid, guint32 vlanflags, const NMPlatformLink **out_link); gboolean (*link_vlan_change) (NMPlatform *self, int ifindex, @@ -927,6 +915,7 @@ typedef struct { gboolean (*wpan_set_pan_id) (NMPlatform *, int ifindex, guint16 pan_id); guint16 (*wpan_get_short_addr) (NMPlatform *, int ifindex); gboolean (*wpan_set_short_addr) (NMPlatform *, int ifindex, guint16 short_addr); + gboolean (*wpan_set_channel) (NMPlatform *, int ifindex, guint8 page, guint8 channel); gboolean (*object_delete) (NMPlatform *, const NMPObject *obj); @@ -950,23 +939,23 @@ typedef struct { gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, guint8 plen); - NMPlatformError (*ip_route_add) (NMPlatform *, - NMPNlmFlags flags, - int addr_family, - const NMPlatformIPRoute *route); - NMPlatformError (*ip_route_get) (NMPlatform *self, - int addr_family, - gconstpointer address, - int oif_ifindex, - NMPObject **out_route); + int (*ip_route_add) (NMPlatform *, + NMPNlmFlags flags, + int addr_family, + const NMPlatformIPRoute *route); + int (*ip_route_get) (NMPlatform *self, + int addr_family, + gconstpointer address, + int oif_ifindex, + NMPObject **out_route); - NMPlatformError (*qdisc_add) (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformQdisc *qdisc); + int (*qdisc_add) (NMPlatform *self, + NMPNlmFlags flags, + const NMPlatformQdisc *qdisc); - NMPlatformError (*tfilter_add) (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformTfilter *tfilter); + int (*tfilter_add) (NMPlatform *self, + NMPNlmFlags flags, + const NMPlatformTfilter *tfilter); NMPlatformKernelSupportFlags (*check_kernel_support) (NMPlatform * self, NMPlatformKernelSupportFlags request_flags); @@ -1095,22 +1084,23 @@ gboolean nm_platform_netns_push (NMPlatform *platform, NMPNetns **netns); const char *nm_link_type_to_string (NMLinkType link_type); -const char *nm_platform_error_to_string (NMPlatformError error, - char *buf, - gsize buf_len); -#define nm_platform_error_to_string_a(error) \ - (nm_platform_error_to_string ((error), g_alloca (30), 30)) - #define NMP_SYSCTL_PATHID_ABSOLUTE(path) \ ((const char *) NULL), -1, (path) #define NMP_SYSCTL_PATHID_NETDIR_unsafe(dirfd, ifname, path) \ - nm_sprintf_bufa (NM_STRLEN ("net:/sys/class/net//\0") + IFNAMSIZ + strlen (path), \ - "net:/sys/class/net/%s/%s", (ifname), (path)), \ + nm_sprintf_buf_unsafe_a ( NM_STRLEN ("net:/sys/class/net//\0") \ + + NMP_IFNAMSIZ \ + + ({ \ + const gsize _l = strlen (path); \ + \ + nm_assert (_l < 200); \ + _l; \ + }), \ + "net:/sys/class/net/%s/%s", (ifname), (path)), \ (dirfd), (path) #define NMP_SYSCTL_PATHID_NETDIR(dirfd, ifname, path) \ - nm_sprintf_bufa (NM_STRLEN ("net:/sys/class/net//"path"/\0") + IFNAMSIZ, \ + nm_sprintf_bufa (NM_STRLEN ("net:/sys/class/net//"path"/\0") + NMP_IFNAMSIZ, \ "net:/sys/class/net/%s/%s", (ifname), path), \ (dirfd), (""path"") @@ -1120,7 +1110,35 @@ char *nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, c gint32 nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, const char *path, gint32 fallback); gint64 nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int dirfd, const char *path, guint base, gint64 min, gint64 max, gint64 fallback); -gboolean nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, int value); +char *nm_platform_sysctl_ip_conf_get (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property); + +gint64 nm_platform_sysctl_ip_conf_get_int_checked (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + guint base, + gint64 min, + gint64 max, + gint64 fallback); + +gboolean nm_platform_sysctl_ip_conf_set (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + const char *value); + +gboolean nm_platform_sysctl_ip_conf_set_int64 (NMPlatform *platform, + int addr_family, + const char *ifname, + const char *property, + gint64 value); + +gboolean nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NMPlatform *self, + const char *iface, + int value); const char *nm_platform_if_indextoname (NMPlatform *self, int ifindex, char *out_ifname/* of size IFNAMSIZ */); int nm_platform_if_nametoindex (NMPlatform *self, const char *ifname); @@ -1135,11 +1153,11 @@ const NMPlatformLink *nm_platform_link_get_by_ifname (NMPlatform *self, const ch const NMPlatformLink *nm_platform_link_get_by_address (NMPlatform *self, NMLinkType link_type, gconstpointer address, size_t length); GPtrArray *nm_platform_link_get_all (NMPlatform *self, gboolean sort_by_name); -NMPlatformError nm_platform_link_dummy_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_bridge_add (NMPlatform *self, const char *name, const void *address, size_t address_len, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_bond_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_team_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_veth_add (NMPlatform *self, const char *name, const char *peer, const NMPlatformLink **out_link); +int nm_platform_link_dummy_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); +int nm_platform_link_bridge_add (NMPlatform *self, const char *name, const void *address, size_t address_len, const NMPlatformLink **out_link); +int nm_platform_link_bond_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); +int nm_platform_link_team_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); +int nm_platform_link_veth_add (NMPlatform *self, const char *name, const char *peer, const NMPlatformLink **out_link); gboolean nm_platform_link_delete (NMPlatform *self, int ifindex); @@ -1160,7 +1178,7 @@ GPtrArray *nm_platform_lookup_clone (NMPlatform *platform, NMPObjectPredicateFunc predicate, gpointer user_data); -/* convienience methods to lookup the link and access fields of NMPlatformLink. */ +/* convenience methods to lookup the link and access fields of NMPlatformLink. */ int nm_platform_link_get_ifindex (NMPlatform *self, const char *name); const char *nm_platform_link_get_name (NMPlatform *self, int ifindex); NMLinkType nm_platform_link_get_type (NMPlatform *self, int ifindex); @@ -1210,12 +1228,12 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex); struct udev_device *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex); -NMPlatformError nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +int 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); -NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); -NMPlatformError nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); +int nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); +int nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name); gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe); gboolean nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); @@ -1259,12 +1277,12 @@ const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int if const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkWireGuard *nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_vlan_add (NMPlatform *self, - const char *name, - int parent, - int vlanid, - guint32 vlanflags, - const NMPlatformLink **out_link); +int nm_platform_link_vlan_add (NMPlatform *self, + const char *name, + int parent, + int vlanid, + guint32 vlanflags, + const NMPlatformLink **out_link); gboolean nm_platform_link_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to); gboolean nm_platform_link_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to); gboolean nm_platform_link_vlan_change (NMPlatform *self, @@ -1278,18 +1296,18 @@ gboolean nm_platform_link_vlan_change (NMPlatform *self, const NMVlanQosMapping *egress_map, gsize n_egress_map); -NMPlatformError nm_platform_link_vxlan_add (NMPlatform *self, - const char *name, - const NMPlatformLnkVxlan *props, - const NMPlatformLink **out_link); - -NMPlatformError nm_platform_link_infiniband_add (NMPlatform *self, - int parent, - int p_key, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_infiniband_delete (NMPlatform *self, - int parent, - int p_key); +int nm_platform_link_vxlan_add (NMPlatform *self, + const char *name, + const NMPlatformLnkVxlan *props, + const NMPlatformLink **out_link); + +int nm_platform_link_infiniband_add (NMPlatform *self, + int parent, + int p_key, + const NMPlatformLink **out_link); +int nm_platform_link_infiniband_delete (NMPlatform *self, + int parent, + int p_key); gboolean nm_platform_link_infiniband_get_properties (NMPlatform *self, int ifindex, int *parent, int *p_key, const char **mode); gboolean nm_platform_link_veth_get_properties (NMPlatform *self, int ifindex, int *out_peer_ifindex); @@ -1318,55 +1336,67 @@ guint16 nm_platform_wpan_get_pan_id (NMPlatform *platform, int ifindex gboolean nm_platform_wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id); guint16 nm_platform_wpan_get_short_addr (NMPlatform *platform, int ifindex); gboolean nm_platform_wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr); +gboolean nm_platform_wpan_set_channel (NMPlatform *platform, int ifindex, guint8 page, guint8 channel); void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen); const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr); const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int ifindex, in_addr_t address, guint8 plen, in_addr_t peer_address); -NMPlatformError nm_platform_link_gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkGre *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_ip6tnl_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_ip6gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_ipip_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIpIp *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_macsec_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLnkMacsec *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_macvlan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLnkMacvlan *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_sit_add (NMPlatform *self, - const char *name, - const NMPlatformLnkSit *props, - const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_tun_add (NMPlatform *self, - const char *name, - const NMPlatformLnkTun *props, - const NMPlatformLink **out_link, - int *out_fd); -NMPlatformError nm_platform_link_6lowpan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLink **out_link); +int nm_platform_link_gre_add (NMPlatform *self, + const char *name, + const NMPlatformLnkGre *props, + const NMPlatformLink **out_link); +int nm_platform_link_ip6tnl_add (NMPlatform *self, + const char *name, + const NMPlatformLnkIp6Tnl *props, + const NMPlatformLink **out_link); +int nm_platform_link_ip6gre_add (NMPlatform *self, + const char *name, + const NMPlatformLnkIp6Tnl *props, + const NMPlatformLink **out_link); +int nm_platform_link_ipip_add (NMPlatform *self, + const char *name, + const NMPlatformLnkIpIp *props, + const NMPlatformLink **out_link); +int nm_platform_link_macsec_add (NMPlatform *self, + const char *name, + int parent, + const NMPlatformLnkMacsec *props, + const NMPlatformLink **out_link); +int nm_platform_link_macvlan_add (NMPlatform *self, + const char *name, + int parent, + const NMPlatformLnkMacvlan *props, + const NMPlatformLink **out_link); +int nm_platform_link_sit_add (NMPlatform *self, + const char *name, + const NMPlatformLnkSit *props, + const NMPlatformLink **out_link); +int nm_platform_link_tun_add (NMPlatform *self, + const char *name, + const NMPlatformLnkTun *props, + const NMPlatformLink **out_link, + int *out_fd); +int nm_platform_link_6lowpan_add (NMPlatform *self, + const char *name, + int parent, + const NMPlatformLink **out_link); gboolean nm_platform_link_6lowpan_get_properties (NMPlatform *self, int ifindex, int *out_parent); +int nm_platform_link_wireguard_add (NMPlatform *self, + const char *name, + const NMPlatformLink **out_link); + +int nm_platform_link_wireguard_change (NMPlatform *self, + int ifindex, + const NMPlatformLnkWireGuard *lnk_wireguard, + const struct _NMPWireGuardPeer *peers, + guint peers_len, + gboolean replace_peers); + const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address); gboolean nm_platform_object_delete (NMPlatform *self, const NMPObject *route); @@ -1399,11 +1429,11 @@ gboolean nm_platform_ip_address_flush (NMPlatform *self, void nm_platform_ip_route_normalize (int addr_family, NMPlatformIPRoute *route); -NMPlatformError nm_platform_ip_route_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPObject *route); -NMPlatformError nm_platform_ip4_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route); -NMPlatformError nm_platform_ip6_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route); +int nm_platform_ip_route_add (NMPlatform *self, + NMPNlmFlags flags, + const NMPObject *route); +int nm_platform_ip4_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP4Route *route); +int nm_platform_ip6_route_add (NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route); GPtrArray *nm_platform_ip_route_get_prune_list (NMPlatform *self, int addr_family, @@ -1421,22 +1451,22 @@ gboolean nm_platform_ip_route_flush (NMPlatform *self, int addr_family, int ifindex); -NMPlatformError nm_platform_ip_route_get (NMPlatform *self, - int addr_family, - gconstpointer address, - int oif_ifindex, - NMPObject **out_route); +int nm_platform_ip_route_get (NMPlatform *self, + int addr_family, + gconstpointer address, + int oif_ifindex, + NMPObject **out_route); -NMPlatformError nm_platform_qdisc_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformQdisc *qdisc); +int nm_platform_qdisc_add (NMPlatform *self, + NMPNlmFlags flags, + const NMPlatformQdisc *qdisc); gboolean nm_platform_qdisc_sync (NMPlatform *self, int ifindex, GPtrArray *known_qdiscs); -NMPlatformError nm_platform_tfilter_add (NMPlatform *self, - NMPNlmFlags flags, - const NMPlatformTfilter *tfilter); +int nm_platform_tfilter_add (NMPlatform *self, + NMPNlmFlags flags, + const NMPlatformTfilter *tfilter); gboolean nm_platform_tfilter_sync (NMPlatform *self, int ifindex, GPtrArray *known_tfilters); @@ -1467,7 +1497,6 @@ const char *nm_platform_vlan_qos_mapping_to_string (const char *name, char *buf, gsize len); -struct _NMPWireGuardPeer; const char *nm_platform_wireguard_peer_to_string (const struct _NMPWireGuardPeer *peer, char *buf, gsize len); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index fdc27440..80e65b49 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <linux/rtnetlink.h> +#include <linux/if.h> #include <libudev.h> #include "nm-utils.h" @@ -88,6 +89,192 @@ struct _NMPCache { /*****************************************************************************/ +int +nm_sock_addr_union_cmp (const NMSockAddrUnion *a, const NMSockAddrUnion *b) +{ + nm_assert (!a || NM_IN_SET (a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + nm_assert (!b || NM_IN_SET (b->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + + NM_CMP_SELF (a, b); + + NM_CMP_FIELD (a, b, sa.sa_family); + switch (a->sa.sa_family) { + case AF_INET: + NM_CMP_DIRECT (ntohl (a->in.sin_addr.s_addr), ntohl (b->in.sin_addr.s_addr)); + NM_CMP_DIRECT (htons (a->in.sin_port), htons (b->in.sin_port)); + break; + case AF_INET6: + NM_CMP_DIRECT_IN6ADDR (&a->in6.sin6_addr, &b->in6.sin6_addr); + NM_CMP_DIRECT (htons (a->in6.sin6_port), htons (b->in6.sin6_port)); + NM_CMP_FIELD (a, b, in6.sin6_scope_id); + NM_CMP_FIELD (a, b, in6.sin6_flowinfo); + break; + } + return 0; +} + +void +nm_sock_addr_union_hash_update (const NMSockAddrUnion *a, NMHashState *h) +{ + if (!a) { + nm_hash_update_val (h, 1241364739u); + return; + } + + nm_assert (NM_IN_SET (a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + + switch (a->sa.sa_family) { + case AF_INET: + nm_hash_update_vals (h, + a->in.sin_family, + a->in.sin_addr.s_addr, + a->in.sin_port); + return; + case AF_INET6: + nm_hash_update_vals (h, + a->in6.sin6_family, + a->in6.sin6_addr, + a->in6.sin6_port, + a->in6.sin6_scope_id, + a->in6.sin6_flowinfo); + return; + default: + nm_hash_update_val (h, a->sa.sa_family); + return; + } +} + +/** + * nm_sock_addr_union_cpy: + * @dst: the destination #NMSockAddrUnion. It will always be fully initialized, + * to one of the address families AF_INET, AF_INET6, or AF_UNSPEC (in case of + * error). + * @src: (allow-none): the source buffer with an sockaddr to copy. It may be unaligned in + * memory. If not %NULL, the buffer must be at least large enough to contain + * sa.sa_family, and then, depending on sa.sa_family, it must be large enough + * to hold struct sockaddr_in or struct sockaddr_in6. + * + * @dst will always be fully initialized (including setting all un-used bytes to zero). + */ +void +nm_sock_addr_union_cpy (NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */) +{ + struct sockaddr sa; + gsize src_len; + + nm_assert (dst); + + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + + if (!src) + return; + + memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family)); + + if (sa.sa_family == AF_INET) + src_len = sizeof (struct sockaddr_in); + else if (sa.sa_family == AF_INET6) + src_len = sizeof (struct sockaddr_in6); + else + return; + + memcpy (dst, src, src_len); + nm_assert (dst->sa.sa_family == sa.sa_family); +} + +/** + * nm_sock_addr_union_cpy_untrusted: + * @dst: the destination #NMSockAddrUnion. It will always be fully initialized, + * to one of the address families AF_INET, AF_INET6, or AF_UNSPEC (in case of + * error). + * @src: the source buffer with an sockaddr to copy. It may be unaligned in + * memory. + * @src_len: the length of @src in bytes. + * + * The function requires @src_len to be either sizeof(struct sockaddr_in) or sizeof (struct sockaddr_in6). + * If that's the case, then @src will be interpreted as such structure (unaligned), and + * accessed. It will check sa.sa_family to match the expected sizes, and if it does, the + * struct will be copied. + * + * On any failure, @dst will be set to sa.sa_family AF_UNSPEC. + * @dst will always be fully initialized (including setting all un-used bytes to zero). + */ +void +nm_sock_addr_union_cpy_untrusted (NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len) +{ + int f_expected; + struct sockaddr sa; + + nm_assert (dst); + + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + + if (src_len == sizeof (struct sockaddr_in)) + f_expected = AF_INET; + else if (src_len == sizeof (struct sockaddr_in6)) + f_expected = AF_INET6; + else + return; + + memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family)); + + if (sa.sa_family != f_expected) + return; + + memcpy (dst, src, src_len); + nm_assert (dst->sa.sa_family == sa.sa_family); +} + +const char * +nm_sock_addr_union_to_string (const NMSockAddrUnion *sa, + char *buf, + gsize len) +{ + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + char s_scope_id[40]; + + if (!nm_utils_to_string_buffer_init_null (sa, &buf, &len)) + return buf; + + /* maybe we should use getnameinfo(), but here implement it ourself. + * + * We want to see the actual bytes for debugging (as we understand them), + * and now what getnameinfo() makes of it. Also, it's simpler this way. */ + + switch (sa->sa.sa_family) { + case AF_INET: + g_snprintf (buf, len, + "%s:%u", + nm_utils_inet4_ntop (sa->in.sin_addr.s_addr, s_addr), + (guint) htons (sa->in.sin_port)); + break; + case AF_INET6: + g_snprintf (buf, len, + "[%s%s]:%u", + nm_utils_inet6_ntop (&sa->in6.sin6_addr, s_addr), + ( sa->in6.sin6_scope_id != 0 + ? nm_sprintf_buf (s_scope_id, "%u", sa->in6.sin6_scope_id) + : ""), + (guint) htons (sa->in6.sin6_port)); + break; + case AF_UNSPEC: + g_snprintf (buf, len, "unspec"); + break; + default: + g_snprintf (buf, len, + "{addr-family:%u}", + (unsigned) sa->sa.sa_family); + break; + } + + return buf; +} + +/*****************************************************************************/ + static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class; static void @@ -391,14 +578,9 @@ _wireguard_peer_hash_update (const NMPWireGuardPeer *peer, peer->rx_bytes, peer->tx_bytes, peer->last_handshake_time.tv_sec, - peer->last_handshake_time.tv_nsec, - peer->endpoint_port, - peer->endpoint_family); + peer->last_handshake_time.tv_nsec); - if (peer->endpoint_family == AF_INET) - nm_hash_update_val (h, peer->endpoint_addr.addr4); - else if (peer->endpoint_family == AF_INET6) - nm_hash_update_val (h, peer->endpoint_addr.addr6); + nm_sock_addr_union_hash_update (&peer->endpoint, h); for (i = 0; i < peer->allowed_ips_len; i++) _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h); @@ -418,15 +600,11 @@ _wireguard_peer_cmp (const NMPWireGuardPeer *a, NM_CMP_FIELD (a, b, tx_bytes); NM_CMP_FIELD (a, b, allowed_ips_len); NM_CMP_FIELD (a, b, persistent_keepalive_interval); - NM_CMP_FIELD (a, b, endpoint_port); - NM_CMP_FIELD (a, b, endpoint_family); + NM_CMP_FIELD (a, b, endpoint.sa.sa_family); NM_CMP_FIELD_MEMCMP (a, b, public_key); NM_CMP_FIELD_MEMCMP (a, b, preshared_key); - if (a->endpoint_family == AF_INET) - NM_CMP_FIELD (a, b, endpoint_addr.addr4); - else if (a->endpoint_family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, endpoint_addr.addr6); + NM_CMP_RETURN (nm_sock_addr_union_cmp (&a->endpoint, &b->endpoint)); for (i = 0; i < a->allowed_ips_len; i++) { NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i], @@ -629,9 +807,12 @@ _nmp_object_stackinit_from_class (NMPObject *obj, const NMPClass *klass) nm_assert (obj); nm_assert (klass); - memset (obj, 0, sizeof (NMPObject)); - obj->_class = klass; - obj->parent._ref_count = NM_OBJ_REF_COUNT_STACKINIT; + *obj = (NMPObject) { + .parent = { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; } static NMPObject * @@ -643,9 +824,12 @@ _nmp_object_stackinit_from_type (NMPObject *obj, NMPObjectType obj_type) klass = nmp_class_from_type (obj_type); nm_assert (klass); - memset (obj, 0, sizeof (NMPObject)); - obj->_class = klass; - obj->parent._ref_count = NM_OBJ_REF_COUNT_STACKINIT; + *obj = (NMPObject) { + .parent = { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; return obj; } @@ -896,11 +1080,9 @@ static const char * \ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \ { \ plat_type *const obj = (plat_type *) _obj; \ - char buf1[NM_UTILS_INET_ADDRSTRLEN]; \ - char buf2[NM_UTILS_INET_ADDRSTRLEN]; \ + _nm_unused char buf1[NM_UTILS_INET_ADDRSTRLEN]; \ + _nm_unused char buf2[NM_UTILS_INET_ADDRSTRLEN]; \ \ - (void) buf1; \ - (void) buf2; \ g_snprintf (buf, buf_len, \ __VA_ARGS__); \ return buf; \ @@ -1636,7 +1818,7 @@ nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *m * The flag obj->link.connected depends on the state of other links in the * @cache. See also nmp_cache_link_connected_needs_toggle(). Given an ifindex * of a master, check if the cache contains such a master link that needs - * toogling of the connected flag. + * toggling of the connected flag. * * Returns: NULL if there is no master link with ifindex @master_ifindex that should be toggled. * Otherwise, return the link object from inside the cache with the given ifindex. @@ -1975,6 +2157,8 @@ nmp_cache_lookup_link_full (const NMPCache *cache, } else if (!ifname && !match_fn) return NULL; else { + const NMPObject *obj_best = NULL; + if (ifname) { if (strlen (ifname) >= IFNAMSIZ) return NULL; @@ -1986,16 +2170,21 @@ nmp_cache_lookup_link_full (const NMPCache *cache, nmp_cache_iter_for_each_link (&iter, head_entry, &link) { obj = NMP_OBJECT_UP_CAST (link); - if (visible_only && !nmp_object_is_visible (obj)) - continue; if (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) continue; + if (visible_only && !nmp_object_is_visible (obj)) + continue; if (match_fn && !match_fn (obj, user_data)) continue; - return obj; + /* if there are multiple candidates, prefer the visible ones. */ + if ( visible_only + || nmp_object_is_visible (obj)) + return obj; + if (!obj_best) + obj_best = obj; } - return NULL; + return obj_best; } } @@ -2338,7 +2527,7 @@ nmp_cache_remove_netlink (NMPCache *cache, * * Returns: how the cache changed. * - * Even if there was no change in the cace (NMP_CACHE_OPS_UNCHANGED), @out_obj_old + * Even if there was no change in the cache (NMP_CACHE_OPS_UNCHANGED), @out_obj_old * and @out_obj_new will be set accordingly. **/ NMPCacheOpsType @@ -2609,7 +2798,7 @@ update_done: nm_dedup_multi_entry_reorder (entry_cur, NULL, FALSE); break; default: - /* this is an unexecpted case, probably a bug that we need to handle better. */ + /* this is an unexpected case, probably a bug that we need to handle better. */ resync_required = TRUE; break; } @@ -3096,7 +3285,7 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_wireguard_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp, + .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_wireguard_hash_update, + .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_wireguard_cmp, }, }; diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 97be8321..4649441b 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -21,6 +21,8 @@ #ifndef __NMP_OBJECT_H__ #define __NMP_OBJECT_H__ +#include <netinet/in.h> + #include "nm-utils/nm-obj.h" #include "nm-utils/nm-dedup-multi.h" #include "nm-platform.h" @@ -29,6 +31,38 @@ struct udev_device; /*****************************************************************************/ +typedef union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +} NMSockAddrUnion; + +#define NM_SOCK_ADDR_UNION_INIT_UNSPEC \ + { \ + .sa = { \ + .sa_family = AF_UNSPEC, \ + }, \ + } + +int nm_sock_addr_union_cmp (const NMSockAddrUnion *a, + const NMSockAddrUnion *b); + +void nm_sock_addr_union_hash_update (const NMSockAddrUnion *a, + NMHashState *h); + +void nm_sock_addr_union_cpy (NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */); + +void nm_sock_addr_union_cpy_untrusted (NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len); + +const char *nm_sock_addr_union_to_string (const NMSockAddrUnion *sa, + char *buf, + gsize len); + +/*****************************************************************************/ + typedef struct { NMIPAddr addr; guint8 family; @@ -36,10 +70,12 @@ typedef struct { } NMPWireGuardAllowedIP; typedef struct _NMPWireGuardPeer { - NMIPAddr endpoint_addr; + NMSockAddrUnion endpoint; + struct timespec last_handshake_time; guint64 rx_bytes; guint64 tx_bytes; + union { const NMPWireGuardAllowedIP *allowed_ips; guint _construct_idx_start; @@ -48,11 +84,11 @@ typedef struct _NMPWireGuardPeer { guint allowed_ips_len; guint _construct_idx_end; }; + guint16 persistent_keepalive_interval; - guint16 endpoint_port; + guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; - guint8 endpoint_family; } NMPWireGuardPeer; /*****************************************************************************/ @@ -100,14 +136,14 @@ typedef enum { /*< skip >*/ * * Also, note that links may be considered invisible. This index type * expose all links, even invisible ones. For addresses/routes, this - * distiction doesn't exist, as all addresses/routes that are alive + * distinction doesn't exist, as all addresses/routes that are alive * are visible as well. */ NMP_CACHE_ID_TYPE_OBJECT_TYPE, /* index for the link objects by ifname. */ NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, - /* indeces for the visible default-routes, ignoring ifindex. + /* indices for the visible default-routes, ignoring ifindex. * This index only contains two partitions: all visible default-routes, * separate for IPv4 and IPv6. */ NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, @@ -504,7 +540,7 @@ nmp_object_ref (const NMPObject *obj) } /* ref and unref accept const pointers. NMPObject is supposed to be shared - * and kept immutable. Disallowing to take/retrun a reference to a const + * and kept immutable. Disallowing to take/return a reference to a const * NMPObject is cumbersome, because callers are precisely expected to * keep a ref on the otherwise immutable object. */ g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), NULL); diff --git a/src/platform/tests/meson.build b/src/platform/tests/meson.build index bedc6916..3704e2ac 100644 --- a/src/platform/tests/meson.build +++ b/src/platform/tests/meson.build @@ -22,7 +22,7 @@ foreach test_unit: test_units 'platform/' + test_unit[0], test_script, timeout: test_unit[3], - args: test_args + [exe.full_path()] + args: test_args + [exe.full_path()], ) endforeach diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index ddef8853..d84a806d 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -189,7 +189,7 @@ test_ip4_address_general_2 (void) inet_pton (AF_INET, IP4_ADDRESS, &addr); g_assert (ifindex > 0); - /* Looks like addresses are not announced by kerenl when the interface + /* Looks like addresses are not announced by kernel when the interface * is down. Link-local IPv6 address is automatically added. */ g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, DEVICE_IFINDEX, NULL)); diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 12d91812..6c73a63e 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -52,7 +52,7 @@ test_cleanup_internal (void) inet_pton (AF_INET6, "2001:db8:e:f:1:2:3:4", &gateway6); /* Create and set up device */ - g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); accept_signal (link_added); free_signal (link_added); g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME), NULL)); @@ -128,8 +128,7 @@ _nmtstp_init_tests (int *argc, char ***argv) void _nmtstp_setup_tests (void) { - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); g_test_add_func ("/internal", test_cleanup_internal); /* FIXME: add external cleanup check */ diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 1cb2f516..8e29b5ce 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -366,9 +366,12 @@ _nmtstp_assert_ip4_route_exists (const char *file, &c); if (c != c_exists && c_exists != -1) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u tos %u shall exist %u times, but platform has it %u times", file, line, func, - nm_utils_inet4_ntop (network, NULL), plen, + nm_utils_inet4_ntop (network, sbuf), + plen, metric, tos, c_exists, @@ -821,7 +824,8 @@ _ip_address_add (NMPlatform *platform, gs_free char *s_valid = NULL; gs_free char *s_preferred = NULL; gs_free char *s_label = NULL; - char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; ifname = nm_platform_link_get_name (platform, ifindex); g_assert (ifname); @@ -834,14 +838,14 @@ _ip_address_add (NMPlatform *platform, s_label = g_strdup_printf ("%s:%s", ifname, label); if (is_v4) { - char s_peer[100]; + char s_peer[NM_UTILS_INET_ADDRSTRLEN + 50]; g_assert (flags == 0); if ( peer_address->addr4 != address->addr4 || nmtst_get_rand_int () % 2) { /* If the peer is the same as the local address, we can omit it. The result should be identical */ - g_snprintf (s_peer, sizeof (s_peer), " peer %s", nm_utils_inet4_ntop (peer_address->addr4, b2)); + nm_sprintf_buf (s_peer, " peer %s", nm_utils_inet4_ntop (peer_address->addr4, b2)); } else s_peer[0] = '\0'; @@ -1006,7 +1010,7 @@ void nmtstp_ip4_route_add (NMPlatform *platform, route.metric = metric; route.mss = mss; - g_assert_cmpint (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_REPLACE, &route), ==, NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); } void nmtstp_ip6_route_add (NMPlatform *platform, @@ -1030,7 +1034,7 @@ void nmtstp_ip6_route_add (NMPlatform *platform, route.metric = metric; route.mss = mss; - g_assert_cmpint (nm_platform_ip6_route_add (platform, NMP_NLM_FLAG_REPLACE, &route), ==, NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip6_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); } /*****************************************************************************/ @@ -1052,7 +1056,8 @@ _ip_address_del (NMPlatform *platform, if (external_command) { const char *ifname; - char b1[NM_UTILS_INET_ADDRSTRLEN], b2[NM_UTILS_INET_ADDRSTRLEN]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; int success; gboolean had_address; @@ -1198,7 +1203,7 @@ nmtstp_link_veth_add (NMPlatform *platform, nmtstp_assert_wait_for_link (platform, peer, NM_LINK_TYPE_VETH, 10); } } else - success = nm_platform_link_veth_add (platform, name, peer, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_veth_add (platform, name, peer, &pllink)); g_assert (success); _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_VETH); @@ -1225,7 +1230,7 @@ nmtstp_link_dummy_add (NMPlatform *platform, if (success) pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_DUMMY, 100); } else - success = nm_platform_link_dummy_add (platform, name, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (platform, name, &pllink)); g_assert (success); _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_DUMMY); @@ -1240,7 +1245,8 @@ nmtstp_link_gre_add (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; gboolean success; - char buffer[INET_ADDRSTRLEN]; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; NMLinkType link_type; g_assert (nm_utils_is_valid_iface_name (name, NULL)); @@ -1265,15 +1271,15 @@ nmtstp_link_gre_add (NMPlatform *platform, name, type, dev ?: "", - nm_utils_inet4_ntop (lnk->local, NULL), - nm_utils_inet4_ntop (lnk->remote, buffer), + nm_utils_inet4_ntop (lnk->local, b1), + nm_utils_inet4_ntop (lnk->remote, b2), lnk->ttl, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); } else - success = nm_platform_link_gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_gre_add (platform, name, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, link_type); @@ -1288,7 +1294,8 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; gboolean success; - char buffer[INET6_ADDRSTRLEN]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; char encap[20]; char tclass[20]; gboolean encap_ignore; @@ -1326,8 +1333,8 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, name, mode, dev, - nm_utils_inet6_ntop (&lnk->local, NULL), - nm_utils_inet6_ntop (&lnk->remote, buffer), + nm_utils_inet6_ntop (&lnk->local, b1), + nm_utils_inet6_ntop (&lnk->remote, b2), lnk->ttl, tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), encap_ignore ? "none" : nm_sprintf_buf (encap, "%u", lnk->encap_limit), @@ -1335,7 +1342,7 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, if (success) pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100); } else - success = nm_platform_link_ip6tnl_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6tnl_add (platform, name, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); @@ -1350,7 +1357,8 @@ nmtstp_link_ip6gre_add (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; gboolean success; - char buffer[INET6_ADDRSTRLEN]; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; char tclass[20]; gboolean tclass_inherit; @@ -1373,8 +1381,8 @@ nmtstp_link_ip6gre_add (NMPlatform *platform, name, lnk->is_tap ? "ip6gretap" : "ip6gre", dev, - nm_utils_inet6_ntop (&lnk->local, NULL), - nm_utils_inet6_ntop (&lnk->remote, buffer), + nm_utils_inet6_ntop (&lnk->local, b1), + nm_utils_inet6_ntop (&lnk->remote, b2), lnk->ttl, tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), lnk->flow_label); @@ -1385,7 +1393,7 @@ nmtstp_link_ip6gre_add (NMPlatform *platform, 100); } } else - success = nm_platform_link_ip6gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6gre_add (platform, name, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); @@ -1400,7 +1408,8 @@ nmtstp_link_ipip_add (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; gboolean success; - char buffer[INET_ADDRSTRLEN]; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; g_assert (nm_utils_is_valid_iface_name (name, NULL)); @@ -1417,15 +1426,15 @@ nmtstp_link_ipip_add (NMPlatform *platform, success = !nmtstp_run_command ("ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", name, dev, - nm_utils_inet4_ntop (lnk->local, NULL), - nm_utils_inet4_ntop (lnk->remote, buffer), + nm_utils_inet4_ntop (lnk->local, b1), + nm_utils_inet4_ntop (lnk->remote, b2), lnk->ttl, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IPIP, 100); } else - success = nm_platform_link_ipip_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ipip_add (platform, name, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IPIP); @@ -1473,7 +1482,7 @@ nmtstp_link_macvlan_add (NMPlatform *platform, if (success) pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); } else - success = nm_platform_link_macvlan_add (platform, name, parent, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_macvlan_add (platform, name, parent, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, link_type); @@ -1488,7 +1497,8 @@ nmtstp_link_sit_add (NMPlatform *platform, { const NMPlatformLink *pllink = NULL; gboolean success; - char buffer[INET_ADDRSTRLEN]; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; g_assert (nm_utils_is_valid_iface_name (name, NULL)); @@ -1510,15 +1520,15 @@ nmtstp_link_sit_add (NMPlatform *platform, success = !nmtstp_run_command ("ip tunnel add %s mode sit%s local %s remote %s ttl %u tos %02x %s", name, dev, - nm_utils_inet4_ntop (lnk->local, NULL), - nm_utils_inet4_ntop (lnk->remote, buffer), + nm_utils_inet4_ntop (lnk->local, b1), + nm_utils_inet4_ntop (lnk->remote, b2), lnk->ttl, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_SIT, 100); } else - success = nm_platform_link_sit_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; + success = NMTST_NM_ERR_SUCCESS (nm_platform_link_sit_add (platform, name, lnk, &pllink)); _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_SIT); @@ -1533,8 +1543,8 @@ nmtstp_link_tun_add (NMPlatform *platform, int *out_fd) { const NMPlatformLink *pllink = NULL; - NMPlatformError plerr; int err; + int r; g_assert (nm_utils_is_valid_iface_name (name, NULL)); g_assert (lnk); @@ -1579,8 +1589,8 @@ nmtstp_link_tun_add (NMPlatform *platform, g_error ("failure to add tun/tap device via ip-route"); } else { g_assert (lnk->persist || out_fd); - plerr = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd); - g_assert_cmpint (plerr, ==, NM_PLATFORM_ERROR_SUCCESS); + r = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd); + g_assert_cmpint (r, ==, 0); } g_assert (pllink); @@ -1596,8 +1606,8 @@ nmtstp_link_vxlan_add (NMPlatform *platform, const NMPlatformLnkVxlan *lnk) { const NMPlatformLink *pllink = NULL; - NMPlatformError plerr; int err; + int r; g_assert (nm_utils_is_valid_iface_name (name, NULL)); @@ -1607,27 +1617,32 @@ nmtstp_link_vxlan_add (NMPlatform *platform, if (external_command) { gs_free char *dev = NULL; - gs_free char *local = NULL, *remote = NULL; + char local[NM_UTILS_INET_ADDRSTRLEN]; + char group[NM_UTILS_INET_ADDRSTRLEN]; if (lnk->parent_ifindex) dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); if (lnk->local) - local = g_strdup_printf ("%s", nm_utils_inet4_ntop (lnk->local, NULL)); + nm_utils_inet4_ntop (lnk->local, local); else if (memcmp (&lnk->local6, &in6addr_any, sizeof (in6addr_any))) - local = g_strdup_printf ("%s", nm_utils_inet6_ntop (&lnk->local6, NULL)); + nm_utils_inet6_ntop (&lnk->local6, local); + else + local[0] = '\0'; if (lnk->group) - remote = g_strdup_printf ("%s", nm_utils_inet4_ntop (lnk->group, NULL)); + nm_utils_inet4_ntop (lnk->group, group); else if (memcmp (&lnk->group6, &in6addr_any, sizeof (in6addr_any))) - remote = g_strdup_printf ("%s", nm_utils_inet6_ntop (&lnk->group6, NULL)); + nm_utils_inet6_ntop (&lnk->group6, group); + else + group[0] = '\0'; err = nmtstp_run_command ("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos %02x dstport %u srcport %u %u ageing %u", name, lnk->id, dev ?: "", local, - remote, + group, lnk->ttl, lnk->tos, lnk->dst_port, @@ -1641,8 +1656,8 @@ nmtstp_link_vxlan_add (NMPlatform *platform, _LOGI ("Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); } if (!pllink) { - plerr = nm_platform_link_vxlan_add (platform, name, lnk, &pllink); - g_assert_cmpint (plerr, ==, NM_PLATFORM_ERROR_SUCCESS); + r = nm_platform_link_vxlan_add (platform, name, lnk, &pllink); + g_assert (NMTST_NM_ERR_SUCCESS (r)); g_assert (pllink); } @@ -1702,10 +1717,11 @@ nmtstp_link_get (NMPlatform *platform, /*****************************************************************************/ void -nmtstp_link_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - const char *name) +nmtstp_link_delete (NMPlatform *platform, + gboolean external_command, + int ifindex, + const char *name, + gboolean require_exist) { gint64 end_time; const NMPlatformLink *pllink; @@ -1718,7 +1734,10 @@ nmtstp_link_del (NMPlatform *platform, pllink = nmtstp_link_get (platform, ifindex, name); - g_assert (pllink); + if (!pllink) { + g_assert (!require_exist); + return; + } name = name_copy = g_strdup (pllink->name); ifindex = pllink->ifindex; @@ -2072,7 +2091,7 @@ main (int argc, char **argv) result = g_test_run (); - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); g_object_unref (NM_PLATFORM_GET); return result; diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 1baadfa1..048fd9dd 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -21,6 +21,9 @@ #include <syslog.h> #include <string.h> #include <arpa/inet.h> +#include <linux/if.h> +#include <linux/if_link.h> +#include <linux/ip6_tunnel.h> #include "platform/nm-platform.h" #include "platform/nmp-object.h" @@ -324,10 +327,11 @@ const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform, const char *name, const NMPlatformLnkVxlan *lnk); -void nmtstp_link_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - const char *name); +void nmtstp_link_delete (NMPlatform *platform, + gboolean external_command, + int ifindex, + const char *name, + gboolean require_exist); /*****************************************************************************/ @@ -346,9 +350,9 @@ _nmtstp_env1_wrapper_setup (const NmtstTestData *test_data) _LOGT ("TEST[%s]: setup", test_data->testpath); - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert_cmpint (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL), ==, NM_PLATFORM_ERROR_SUCCESS); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); *p_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); g_assert_cmpint (*p_ifindex, >, 0); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 057490c4..bfd33058 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -47,7 +47,7 @@ #define MTU 1357 #define _ADD_DUMMY(platform, name) \ - g_assert_cmpint (nm_platform_link_dummy_add ((platform), (name), NULL), ==, NM_PLATFORM_ERROR_SUCCESS) + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add ((platform), (name), NULL))) static void test_bogus(void) @@ -77,7 +77,7 @@ test_bogus(void) g_assert (!addrlen); g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU) != NM_PLATFORM_ERROR_SUCCESS); + g_assert (!NMTST_NM_ERR_SUCCESS (nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU))); g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX)); @@ -107,30 +107,30 @@ software_add (NMLinkType link_type, const char *name) { switch (link_type) { case NM_LINK_TYPE_DUMMY: - return nm_platform_link_dummy_add (NM_PLATFORM_GET, name, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, name, NULL)); case NM_LINK_TYPE_BRIDGE: - return nm_platform_link_bridge_add (NM_PLATFORM_GET, name, NULL, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, name, NULL, 0, NULL)); case NM_LINK_TYPE_BOND: { gboolean bond0_exists = !!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0"); - NMPlatformError plerr; + int r; - plerr = nm_platform_link_bond_add (NM_PLATFORM_GET, name, NULL); + r = nm_platform_link_bond_add (NM_PLATFORM_GET, name, NULL); /* Check that bond0 is *not* automatically created. */ if (!bond0_exists) g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0")); - return plerr == NM_PLATFORM_ERROR_SUCCESS; + return r >= 0; } case NM_LINK_TYPE_TEAM: - return nm_platform_link_team_add (NM_PLATFORM_GET, name, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return NMTST_NM_ERR_SUCCESS (nm_platform_link_team_add (NM_PLATFORM_GET, name, NULL)); case NM_LINK_TYPE_VLAN: { SignalData *parent_added; SignalData *parent_changed; /* Don't call link_callback for the bridge interface */ parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME); - if (nm_platform_link_bridge_add (NM_PLATFORM_GET, PARENT_NAME, NULL, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS) + if (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, PARENT_NAME, NULL, 0, NULL))) accept_signal (parent_added); free_signal (parent_added); @@ -147,7 +147,7 @@ software_add (NMLinkType link_type, const char *name) accept_signals (parent_changed, 1, 2); free_signal (parent_changed); - return nm_platform_link_vlan_add (NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL) == NM_PLATFORM_ERROR_SUCCESS; + return NMTST_NM_ERR_SUCCESS (nm_platform_link_vlan_add (NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL)); } } default: @@ -343,7 +343,7 @@ test_slave (int master, int type, SignalData *master_changed) ensure_no_signal (link_added); ensure_no_signal (link_changed); ensure_no_signal (link_removed); - nmtstp_link_del (NULL, -1, ifindex, NULL); + nmtstp_link_delete (NULL, -1, ifindex, NULL, TRUE); accept_signals (master_changed, 0, 1); accept_signals (link_changed, 0, 1); accept_signal (link_removed); @@ -439,18 +439,18 @@ test_software (NMLinkType link_type, const char *link_typename) free_signal (link_changed); /* Delete */ - nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); + nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); accept_signal (link_removed); /* Delete again */ - g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME))); + g_assert (nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME) <= 0); g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, ifindex)); /* VLAN: Delete parent */ if (link_type == NM_LINK_TYPE_VLAN) { SignalData *link_removed_parent = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, vlan_parent); - nmtstp_link_del (NULL, -1, vlan_parent, NULL); + nmtstp_link_delete (NULL, -1, vlan_parent, NULL, TRUE); accept_signal (link_removed_parent); free_signal (link_removed_parent); } @@ -466,12 +466,20 @@ test_bridge (void) test_software (NM_LINK_TYPE_BRIDGE, "bridge"); } +static int +_system (const char *cmd) +{ + /* some gcc version really want to warn on -Werror=unused-result. Add a bogus wrapper + * function. */ + return system (cmd); +} + static void test_bond (void) { if (nmtstp_is_root_test () && !g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) && - system("modprobe --show bonding") != 0) { + _system("modprobe --show bonding") != 0) { g_test_skip ("Skipping test for bonding: bonding module not available"); return; } @@ -502,7 +510,7 @@ test_bridge_addr (void) nm_utils_hwaddr_aton ("de:ad:be:ef:00:11", addr, sizeof (addr)); - g_assert_cmpint (nm_platform_link_bridge_add (NM_PLATFORM_GET, DEVICE_NAME, addr, sizeof (addr), &plink), ==, NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, DEVICE_NAME, addr, sizeof (addr), &plink))); g_assert (plink); link = *plink; g_assert_cmpstr (link.name, ==, DEVICE_NAME); @@ -518,13 +526,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) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE))); 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) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE))); 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); @@ -534,7 +542,7 @@ test_bridge_addr (void) g_assert_cmpint (plink->addr.len, ==, sizeof (addr)); g_assert (!memcmp (plink->addr.data, addr, sizeof (addr))); - nmtstp_link_del (NULL, -1, link.ifindex, link.name); + nmtstp_link_delete (NULL, -1, link.ifindex, link.name, TRUE); } /*****************************************************************************/ @@ -554,11 +562,11 @@ test_internal (void) g_assert (!nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); /* Add device */ - g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); accept_signal (link_added); /* Try to add again */ - g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_EXISTS); + g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == -NME_PL_EXISTS); /* Check device index, name and type */ ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); @@ -595,7 +603,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)) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac)))); address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addrlen); g_assert (addrlen == sizeof(mac)); g_assert (!memcmp (address, mac, addrlen)); @@ -604,12 +612,12 @@ test_internal (void) accept_signal (link_changed); /* Set MTU */ - g_assert (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU))); g_assert_cmpint (nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex), ==, MTU); accept_signal (link_changed); /* Delete device */ - nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); + nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); accept_signal (link_removed); /* Try to delete again */ @@ -684,6 +692,233 @@ test_external (void) /*****************************************************************************/ +static guint8 * +_copy_base64 (guint8 *dst, gsize dst_len, const char *base64_src) +{ + g_assert (dst); + g_assert (dst_len > 0); + + if (!base64_src) + memset (dst, 0, dst_len); + else { + gs_free guint8 *b = NULL; + gsize l; + + b = g_base64_decode (base64_src, &l); + g_assert (b); + g_assert (l == dst_len); + + memcpy (dst, b, dst_len); + } + return dst; +} + +typedef struct { + const char *pri; + const char *pub; + const char *pre; +} KeyPair; + +static void +_test_wireguard_change (NMPlatform *platform, + int ifindex, + int test_mode) +{ + const KeyPair self_key = + { "yOWEsaXFxX9/DOkQPzqB9RufZOpfSP4LZZCErP0N0Xo=", "s6pVT2xPwktor9O5bVOSzcPqBu9uzQOUzPQHXLU2jmk=" }; + const KeyPair keys[100] = { + { "+BDHMh11bkheGfvlQpqt8P/H7N1sPXtVi05XraZS0E8=", "QItu7PJadBVXFXGv55CMtVnbRHdrI6E2CGlu2N5oGx4=", "2IvZnKTzbF1UlChznWSsEYtGbPjhYSTT41GXO6zLxvk=" }, + { "qGZyV2BO1nyY/FGYd6elBPirwJC9QyZwqbm2OJAgLkY=", "v8L1FEitO0xo+wW/CVVUnALlw0zGveApSFdlITi/5lI=", "/R2c0JmBNGJzT594NQ0mBJ2XJjxt2QUSo+ZiqeY0EQA=" }, + { "YDgsIb0oe+9NcxIx2r0HEEPQpRMxmRN0ALoLm9Sh40Q=", "nFPs1HaU7uFBvE9xZCMF8oOAjzLpZ49AzDHOluY1O2E=", "zsYED2Ef7zIHJoRBPcen+w4ktrRsLPEfYwZhWIuXfds=" }, + { "kHkosM503LWu43tdYXbNwVOpRrtPgd9XFqcN7k4t6G4=", "b8e092WT+eNmnxCr5WE2QC/MXAjDagfG1g03cs2mBC0=", "VXz0ShGWT7H0CBCg2awfatmOJF15ZtaSMPhMsp+hc3A=" }, + { "4C2w5CEnxH59Y2aa6CJXgLdDtWoNMS2UJounRCM1Jkk=", "gC/R9umlnEQL+Qsz/Y64AlsdMge4ECe5/u/JHZCMWSs=", "2bmL5ISr+V5a7l7xFJ695BLIJyBgx8xnxzybkxiRHOg=" }, + { "KHJSzFGkXcZf/wbH2rr99SYtGKWbL680wA2AcDE94lo=", "BsN23h4aOi458Q3EgMQsodsWQxd9h/RxqskAUpsXfgg=", "nK4Zv34YKEhjuexhq1SgK4oTd4MZJT5gcpYvEuPjc7Q=" }, + { "QGMulXJ9e3AVxtpi8+UUVqPOr/YBWvCNFVsWS9IUnUA=", "kjVclP5Ifi6og2BBCEHKS/aa/WktArB4+ig06lYaVlg=", "0+mmceDPcSRK3vFnYqHd9iAfY+Nyjzf/1KgDeYGlRkQ=" }, + { "AOJiDD4y6GA7P7gugjjQG9Cctvc5Y27fajHz6aU3gU4=", "gEnHn6euHtcMEwZBlX6HANPeN9Of+voBDtltS38xDUw=", "wIH1OxgX6GLxx/bnR+t3fbmjGZDTU3WMxp7t1XGezqM=" }, + { "COsls2BlCltaIrrq1+FU51cWddlmoPPppSeIDunOxGA=", "+n6WuV8Tb1/iZArTrHsyNqkRHABbavBQt9Me72K2KEc=", "t4baiprSO9ZbKD2/RutOY9cr+yCajQWZGCTnQdrFQj0=" }, + { "uHawQq2BRyJlsTPoCa+MfBVnv4MwtRoS+S9FEpFOEVg=", "8lcmr27afeb6iI3BQCaDtvalF2Cl7gxRZgs+nyJ/fEg=", "Eh9o/6W60iujBLIHuRfNrPhOWAn7PambT2JRln9iwA0=" }, + { "yL7hmoE/JfRGAotRzx9xOpjfrDA3BFlPEemFiQw40Wk=", "BHK0PHi5kp7rOfQ46oc9xlVpB+pZeZYXTtH7EXr5TwU=", "BS2h2ZZyW0BlYMmLR29xyHEcZ4jtO7rgj1jkz/EEaxU=" }, + { "ON8YrTHQgoC5e0mAR9FakZ8hZ/9I7ysuE21sG546J1Y=", "Bm3l5I6iH1tDrv6EgdZU9PzHqp0H26Z6ggmmIypwxy8=", "qKVfbCnK1EI3eC28SsL+jyBnEnIF/nRJQJzDevBFdNQ=" }, + { "KGLO0RI0VlQFCG+ETUqk25HdaKUnUPXKOKkTh/w8BXU=", "sBDBwQFC7k8UMdMzuavKBkBjYYKigzvYmGF5rm6muQc=", "BNfZF9d7540pUGGOQCh3iDxAZcPBqX4qqM00GSLPBek=" }, + { "KGdWyEodIn7KKI2e4EFK9tT6Bt3bNMFBRFVTKjjJm2E=", "lrbjU/Xn9wDCZQiU8E5fY6igTSozghvo47QeVIIWaUk=", "LczqW48MW8qDQIZYRELsz/VCzVDc5niROvk7OqrTxR0=" }, + { "wO3xinUGABgEmX+RJZbBbOtAmBuPPFG6oVdimvoo90w=", "dCIvTzR6EerOOsRKnWly1a9WGzbJ4qc+6t3SSzLgWFk=", "wFj0zpr5PadBoBy0couLuZ1qudZbXLbV/j3UT+AyKeo=" }, + { "+JNOBlO4tp9vvQk6UO4r3sILyEgjl+BBoWketZufyn0=", "Q6LSv9y7YQkJEzQ/1mpjJEgOrO8GYPUTgcizjh7Cm34=", "kg7AG9MuN04xPJ5Z0IcNZ4a8d1b/n4GsGIeyA4FaaSE=" }, + { "+EJcThLRwjZ+h1CNNFu15HWzznf4u/lPVw8hifTm2Ec=", "Kkn2jFqwBzyIFQfD0OpmePFSmBYmhKagv4pGgkqsWgE=", "jYpxojj8WKYe/XIXMP+uv1Fv0+TKrs83tqfzP0AGdcI=" }, + { "+DKFqSMNFmxriEFj3qatuzYeTJ9+xWYspZ4ydL3eC0Q=", "3o37bsg6HhRg/M9+fTlLcFYc2w/Bz9rLQySvvYCKbRE=", "Jb9qoDIBat1EexlgfpRbXa7OflptME8/zt93bldkiVE=" }, + { "EH3MjFOMqRoDFQz+hSlJpntWBeH3lTk6WPjTIQjr42o=", "PbPewED/nxSBLdM7AXMj7uS3bCgAAg8M6F4iPLd0b1U=", "pj4+UgOGkpJwlRvX5BRXZzmzAUnDtUtJsS7LzbcJWzw=" }, + { "kL6M2KvO+vPBLEc/a0DpEHTibQ1bwaMRT9b9SkzeP0Y=", "pS3G2bHHlkOE6UHP0qVitDuxXgjEaZTviTjNc55RbVs=", "ZVZpWOtYqhX3CpF1kATg/38J6pvUJo8AS1sVYjs3rUE=" }, + { "sFlcRLDn36fnew2Ld92IHJwnKifdS3aF1MWRPs6K3Wg=", "OpjUOTiWExaDYULTINB4yQFqc3mnU3RjQzGRV+KtdFY=", "of0V/uoFRNljv/XTt/tXgoquLRH93Ty0KNiaPUpEi2w=" }, + { "UJ8hjDsg3jfsnnfPH8Gw9FnCb6taTuviurAfZu+kEFg=", "3byjHksUOv8CNjGGKvHvvrJDURBhCIL5UtfZbgyVWCE=", "9f7dbWif51gGrE7R9LeuewQSrvGFGTOB3ceJC67jSkI=" }, + { "iFFPKGIfqeUKY/w72KAZSjd/PGTqCakHYBV10xMDfnI=", "ehneHATNSXtsJTOiPjVSc0QARkihgcfcvoXKFWKfQnI=", "yKdqDBcRwA7RCg4GiY/b5IsWcExPleOBde/hjxc36a4=" }, + { "GDGocdPJTPUAllxQo7SpXZKqMPn7lpxQELQUX9ETHmE=", "n0ScNEou4ekfrXRRXvcADLu2Afj8g5D3TuDP/I4KrnY=", "8QhswqAhi/ehhcmCwQF5aSh80TvIGC/gRL5jBn5wOH8=" }, + { "UCcrlN8fX2ZdNdhaEBNwktwL+H0ZO7fhaj7rgdUutmw=", "LF8J728ilXs4TphnrgR6r0p7W3912DYnsXkGMEPQnRE=", "cYfMjxl2REYir7frGeB0u+NHAaFYF02ysgpBhOL5ygc=" }, + { "SH0657XuIiHidVmViXZF30RUWtkuWXcWWHmKZHTiOG8=", "7k6j49W1u5qgLE5MQUc1osPVW1oPPhzjrGvJ7o9YamY=", "dV2+7rNk/3LR2IcwYg/c+Wvzep1yjY7/u1I+nnlTQ00=" }, + { "qFQWs6jzrscV42pGISQyA7JDvFFAvEQCWJi584VHD2g=", "AT63nHKLC17yUvkR4lOVPxCr4DD3QhXmcmecOTn+Amc=", "2Qe2fwJbFcu1CmKpktElOFkSQMqlyvlV3ZUIAd/Dcts=" }, + { "6J+yLxgPwWtUbk9I3zbeD8RuK6XkQjJ0wTJ1zSVhflQ=", "NJzMBYyPZjk3eLmgdKaOeWyNER5YZF1mR8Umeiu9f28=", "pp+4+XHw5ZmHGJ7WbZ1xLYRsnTI17QIbb0bzHzYZrBs=" }, + { "KJGoWYNVDUWcEMg+E4tljv1LiWAbdRw2QVapYqdFa1Y=", "M2SGk9WVnzYNGnT777G/JE8uUsY2f7mszTwlue73UDE=", "Jg8N7GbhbYB400foFP+OH0v+hCaL1jW61bajSA6EZqc=" }, + { "uAgrgppPyIvk8S1CHUmaCaORsgFFfBreB8pxXmbSdXw=", "dJ22bER4fD3qF2/yIGWQ7SgmZ990sy/SbANjmUMkzws=", "mKkd0OoAR9sClmD+k3fL9weBsoCy5GQGz9BP0kAQIjc=" }, + { "EI3Q8gePNPrtFyoMcv7hOihQgroF/dfjzPn8yvpGPWQ=", "Y9QhJFeiyuuIZNPU56B6U//ZK+XTTe4EP7h/p3Q+dE8=", "qBVUYw9rTWaxn55nUd55NpCWtxOUSWLt4WJGusiDS8Q=" }, + { "oEQvdRm/yHkx+JvlhHGT5RUFrFEUleKb9DCT55EqZ30=", "8hsh/UHwWADTHntOJq4dy0o7ahcNAAlo2rDpjzzrVXk=", "/GF2inW2mPtA26IgFdgOEBbBEerT740wWuP/8NyANdc=" }, + { "6OWrGKZKNsgfRezSUw29EnHymcgKyEKvX5/pZQlLmWs=", "oaJeO6YSS2dodNEf97DvgWrYnFFelG5daEdN84jVVGw=", "T5wvTdyVxK0LY96kouLjs06oUfhGChfty8OUL1Mddro=" }, + { "mPmzQbh2R+r1DC5hSquzKM1SDrxUdfnBPRPJrpqrgkE=", "BtUHAnYWjDjBI42qBf9dJqezTUikYsF96o6PKEWPrVo=", "MxU8EMmq+vVHpuK/AkFZrZDF2b+VbSqukZLPbNsCcgo=" }, + { "8GVxuoo1Veyr+nqxr5Q4vmsMf5qfiXwSlQ4q3+BU60g=", "uSOLe/E9/OjIgUOk0NMBHB45E0+q4Rd+IUO2UOxmKlM=", "+30F+56OE0Sr3wY2clKw4kgE+2XiucMg7xjK6EemXuk=" }, + { "qORPKb+qFuU/9TpFbRUupHsqm9iyk9pa6cpik+EVDkg=", "bMZxxd+Z9I0XA1h9U8JEY+/mRxWGnvbXDZ5Dxz7YzS0=", "SmkkqOz4OhHuSL6cxuRm9+Mlt50Sfd0sMDFTC78gqOE=" }, + { "2Ko3IYhXKcdOMIJGNpASk9saNSZsI64lyJPOoxpQ2kI=", "xVOc9PxY1VFaZfemmKi+Ei2liHhmeTu+JMa+rS00gnA=", "+398DlW8kWeI2aRaC4QfcrEjwqPKCohyDeWdaI1wvv0=" }, + { "CPioGCVpxnym62nH/QoCt1RiiaaxUcuFjvh5kRhjqHA=", "W0XxlBLrZgFKhggMvvv6oFf/RJbfs92qv8JK9e+5i2o=", "bsK2U6CRAUv1uVgYQ7NpqjWWswFIDiDPDEtU1XQygSA=" }, + { "AF17siKaeiO85hikYN0IWCMGWqPm1UOoCkXMltJGUVk=", "B+PFos9aN2S5bLxzGZHljRZj41j3rIx8RWu0vDUzq1w=", "Qb8d6iDYv3m1h7PE8j0Exl2cSwpHkim/fJ1S4P7MYvY=" }, + { "wMFDBTJzx5tDCBhMkrptYJ8w9EeURjc4xeDQpevxAWo=", "4ec439EXE5WQzvtV9reSX+aMmdq5k7o9Ayt8oQp+RhQ=", "jwQlvdNH5WtSSU10H+fh/JisOlaBaohDPEp/BYnTt1Q=" }, + { "4GaJpIFigNDwd31O84pLIMM/o2qhp0ydlI/ydD/2a2Q=", "r/LdkCoK5/BPGdq2+XJO8sCRhI+8ULFmg0887V43PAI=", "Da+3ZZvEJdx4TYFMIDUlbkmytILnSTNxTKX+sQdjMd4=" }, + { "gMnojGqCLmMfGp2m31xlKZ/rIV2b8ockw9DPahRyu0c=", "H6tKCTosnM4BXKqflXrkTdJyNlCIZhQ3ZRxfrvSdrDk=", "4Z6K3LKIMV89plcjMb9CzSzJl03SWRe/++geBMZcOtY=" }, + { "wKCg22aNNoHnDJ0oAKE46FcSSsREW4AaGn5WxCSeXUs=", "9NDTFC0iPt4HbbWepLHhN5poNTN2fdxJKNadsNT7qzY=", "GSVTOCnfLpJ1VCOLHaKSjCMv7/OlcnQiP5+5woqkud8=" }, + { "oCoykq7pcJcg2X2V5TBRzGwn8hzzHC05WUreuotdznY=", "DxfwnbMqr5Wn5SAyFolfEmNQT6l84Oq69ngpg6H6Iio=", "p1RHBuqhuDa1MAQ2lbqmUQFu0CTwYlf73fWZSj9tQhA=" }, + { "UO7YVyRUVkcKr7c63VWWV2zj36XD3HyDfLZCqvrZmFc=", "360lzYtIyHq5lv/QXSCe4bL4G2J1jBXFJ8yS+Ycr7Bc=", "RRPQ1XWF1HN8Us4dtfn2eemdjgtWm7U8r7mM3y00NOk=" }, + { "eCGFYV/NuGP4H552E8Of1xU+3IvZxGyX+p5UFGW8iHI=", "LqhZ4AS9dQ/MhsQnE5Oy7Q8INXY+P+mrfGY5dtg9SlE=", "SICfqs8T5wP6IzATDCT4ovamBKPdkZ7JP4Cfsb3izec=" }, + { "oI3HBZknoIMMZw1BuYMkTBylt25reX7AbCqtWQv8cno=", "B7dUgLgvQhi0RGmvaMrmf26WdjEVrhaiBclVkCKd4AA=", "5O9K9pLXwxFAt5lfMWh4qGbwX1BM7sz0QGYxAnR77dk=" }, + { "sBfYn14EFVIS2M/E1aahP7mOmRNbNtyDChDMS1s6aGs=", "FLYv0ZvzxMkc9A7OzhC4P1ZRu1aKIQd7u6gqfdekC3c=", "kaYLcNCXnCLgiB8fleMQuboUJsj5u3YAmXL9x3ywV0M=" }, + { "qFwZESU/XYZXUtxwrGsFU9qPAFTzjm7EhTS1Q6ajGlM=", "hraQQaqJCkS2yQXv+ccMOVh9V9a/qgSZJgdMAhrt8ms=", "72oDfnWOn39gdk/ncw8Lv267I0I+m73SwxrpYojpWYk=" }, + { "YHhp6Zf/miuc2QXeI2lTezy0lL0pTv2b+nWNkmjYQWI=", "UhNO5arLzF0WlZSgNOx7+IjWN+GSxDdQxZRp8uIwsyI=", "1Q39Nzv2NGI9zWKWMpYLURAMZUg+FP+OboHHzFU8Anc=" }, + { "mLBBXKaCJ+7qeBZpS3wxGi/SQ4kLzun+K+QwwdwfJVQ=", "gIq/nh7NwCJ36MvRnyrWHaRWu8lTmwfN2NvsjVl6SXQ=", "AahcNR91GDyJBIP+vC8ZuIV8ukqjSGtd8s+cmjVC2Ao=" }, + { "OJG4LZlNNngFtAEQdbVVWVm6QAjOOauGcMZGbQrb40M=", "pFHAC6HaWAOtvTRRVfSHvzG05mp4SJZXKsN/tkSF0kM=", "IoXT3wIqWNxQhYuHWl12ODq/P7RM9LwaqglhmjKg+0g=" }, + { "OOwBFOQNhepiqDf04DehQLh1gpBNOluDF1ia752Yfng=", "u715uJ/XhdjXjThCTJ9w6zzXnIhp3VCxhtso1wk+oBQ=", "5x1Ip3Ym0KzDjGhiYjmpeWWr+dgrZlYwfr02GngPOTM=" }, + { "eNPFnwkQy1qw+IjFAlrDA6+sIsxbWDlzbNSsBW8R1UA=", "OaOXaAfPb1MRpWadawFje8YZ0oxJgdCIDIP8c5X+r1U=", "NtfaRRD0GqujnaQQoNoBbtovgO4dfVwEmEQx/YgnDpw=" }, + { "OLdaZItbtxH3mGqItkibIJp7KV27FrQavjhd5zq6s3Q=", "SLSmAYxkMCGj0DO35cMLkC3NVAqK2VmVFndbOZEdA24=", "SnBO68XQTDjxYbmYaAeEHgLwD2u4D+BPT86raRuUQZM=" }, + { "UBQOEz08izwr4eEK/SnQUpkt+TxCjo6Sya/XOGMLOE0=", "wQwrwezI9LzKevGsJJCBHDG8noR0yIEtOK5Rig97SSo=", "DpyS+0d7lrlFWkztsniG2v/j44vcuvWz3sPeghRyb5A=" }, + { "mN98iuqUKh67ggUdq9ZIQNZCZM90fgycTVqYKEo+DkY=", "GYdXVW1jpS0dN1q9zMehubP7LfYqs34kszN0bXQqxxA=", "AJPIHffB4uvvJJki4xCG0VORVBbF6bc2mZQqUx+idPc=" }, + { "OEd/1it8C3o+NOWxDI3DfLMXVBHJQg15N3E8F8d99l8=", "QL1NcuUkoXxDy7M9VjGslCejcUlnUDHRghFVnr+8fmA=", "nven9Dicl8U6QXuDO8rRNtjd4NYaa90SU+Gmv435XKY=" }, + { "AFMCGDu2oAP68miucsi4fmYX2KeRZnsEGv8tQm8JEng=", "1sNxvk8uZhFsBUgxOXmuCMjDAgBbjVeWe9oaFk5Osy0=", "t5iI5XXd56S5q0Y9HC91gzgF9uGjL9FIy6NUaKqkydo=" }, + { "CIAwfJghQHHr4YlztN9at6/iWkrEVCGFAxNVuQCuT3I=", "zpUOF1h17g7RpBzrVlN7oTRz6e+dxcDL8OsAtHwgLC8=", "kOSwC1p6Uoti9E9Eg7ViPZwCytuvp5Fr5Buw677aogU=" }, + { "sC8vrAVBU0zvhWDRfzfySjvopXm2/cTMkTLmioyO3Es=", "p6H7GWm8NfgyO5OCX/COjvVT4MAnTs9ZUj4uZMK8XHA=", "9Tzqo57V/h7+6nSNAHSBKdmU7ultlvZbAnNKSRlrLi4=" }, + { "eI63gjxCZGnzqZxPEi/ifYphXhxIRI2ZxK8jzqo3mmU=", "XyNzEuU9x37fxFCnrZH89Krs5/UqGVx5wNkGfQCAYz0=", "vZ2fTlRPnJQ+q33YdS5p1aweqPGj/kTMc4Uq80FtFjI=" }, + { "aNJlGtm79/RS4SQ/PC4YM6LFo9zAqDr2/RjLqk/z/1A=", "lgZ9akPrABmfHQMlfNFnnpAJzGtcsaU9mUjEYKfzZHc=", "d0Xt1Bcgphd1HMI0RneA4VdBbMZL1qNGJAvFhb080eA=" }, + { "oONSnHirNh3cuH93Ty0C9AXKebGY+cdF3R0DtPzIQlo=", "TuREKfA8EVQiYWsPx8veUzjN2cz/b72limSLWlrCWxw=", "vEqqKbpZf0EM6EApMUaUH65r3Zr81Y/DSODhE4H7U3Y=" }, + { "+D6RyLEaHJ9YF9WDyOlwh87KaNJcc6lqX8Arp6yqHF0=", "EpecjfIo1/EEbmsgUtzEDqLu2ut+SMmzqaBL9Z/MlCA=", "oYfO6/7XQgEYT9zmr4sqFrk0muK/fEv3FfD8MzZzjkE=" }, + { "OCmW5KQql2PRMJnsMYQjXlr6TSYUbxJBknqZtXJPSHM=", "ZZR2ghHlCwAJu/XlsEZuNS6XiGPwuXzyMPPywYFapVM=", "fqSCXq+pKJJ6yNvlOi+tyQ9E4Y6kc4kblGrVqN2WuXA=" }, + { "APWXDAe8d2ia1CUbf/IzSPXOUjR8TVuJgmISiWw0/EY=", "jrT5P5YCkG+U7cfNTvCKy0GSEgsjwmJtHg+8HBP6ZCA=", "t75aUjZXMPir8Ao0yhVClh9/BdWxSL+11CjK3iELNWk=" }, + { "8Nw4sRis7M/6Om+3w5YHXthyMzLGuP48teqdzbHNPlA=", "lj3q3ZYij3ZJ/QunK8n9I00cv/Z+O1TU1kFFl8x3DTE=", "adqB79P7gbXEYYnSd1/UPCwFffTAPXa9kHWynRBYcGo=" }, + { "yOupps5XbjV0fIZKnGhrpcxB7yDQzbBILC0UMJyVS1c=", "+MDV/t9UCIdgm3IkH3BZlxaRPJ3lejRmrm4UPApq4mk=", "AOJPmQxsU6hjOd+9mHnF0VL7Afih3P1Fr625xFT4FtY=" }, + { "cD2DEl4MBwONuTV0db5XreoVjQAUZFNXqIeFEU3KFkE=", "2CeHrjN7tBX48k4Sgv5fIHG06e57q/ucCL+8DIRmfXw=", "3EUo6MRzs6rSoY/7AFs8wiBiTXPcHzerLh6Xp3aMGKo=" }, + { "EA+S3a9ZeOLiRbhTxaT2wkpyDheAmai+UJa6SFGzSm8=", "GGByUKZx/FPa2OkJoqVTHXx+6jrIpIw5rf0rp43MHko=", "BXoDA3yn0JcMV7hHVzEqhlwAORvhToFO1qG00nas92A=" }, + { "eBeJi/imBiV52WEqrwAprUQggqdQmvTTmWtLq8pDDkM=", "zCX26ZTOZHLpq5x5aIUL1XhIVoXJLp/zcXwnmFA3jBo=", "Dm/DCxXWYXEsmQgxAD3KREK2PF0bUSnV5WRAaya8s1I=" }, + { "8C7p+EQO+CnWUSjHVu3PpeWpUIbLy48zpftZu021plM=", "DxpnF/IbKAh6kmWC5Jpj8iw387EDkrvjsjOb9fbTSng=", "bGrk0OshJB+0oQOK0QGKU8+lotnIDz3oeUnMZGienyM=" }, + { "COIez7YcBJiOJCLxxWV5UGLW5/o009YI0aszlD/PiUc=", "eD9USWV37LFIOxlDSHyOmfFqNJFpORRlzEI+HoF/czI=", "n+/ra86gUSF2pNZS51nt2JgrzXnQJl+dWswOq/Ahs94=" }, + { "iBBSTG9VLC+T9+ahNaQ4umZoig8o7w1DaeOw+cD2BGc=", "XnAxqDlvGnQ6aakv8ABGHVj07qVQfk4NChZbstTMBxg=", "7KKSwu/4yWr1UzFmNMGtiaSwdYMhP/HKbrQLlABL4UE=" }, + { "eNmwattflehr9+KsVqTuwt1YaAc5ONkaIaTQt9Gkhn8=", "1NNVvm++YTTGMKyAXfGOCZ4aDDdFFH5Um3vAg4XimDo=", "bXNrnDTP0pBay9ytZe7xpiKoSi12F7WUXqoIeI++Xvo=" }, + { "QJotpmZINx9eptKpkh9j3JlEDcHdWnjEbicdBS7gPXM=", "3gLYKeoruVZ/AYjym0gciDvRHj45UIWyHhNjWj2Wj28=", "NwuUkkE5yOWT7wed7bltgAk71miz3cSooiIDAdv6kKw=" }, + { "OAYGuxH70OPQvhVIX4BhSCWUyzAI5H2IkYxKgC/AO0M=", "Rj9iNF/FagkXfdLPqc9LHfaoGR8GlvY3gun2FilE508=", "hkNXLVMlBRsMEaQKkSzevcEK2sMu0AShGKQJMNqdzWM=" }, + { "uBrgZ7wLHrOV/0dNiEqo7FjY9VnJqL5eUDHJWAc9QXg=", "3Hnln8ZHfSaK4OzESJe5U6NcLaW56wzfZICzvzefnSo=", "DhXsehe5FAmbUidXT5ZpZIAuu1eF9rkU6cF3FBoKwOE=" }, + { "sJknn3CHvx/812EWU3ddLdLLZFBKsc+wx35GXyiRsHY=", "qqa2dNSt0jWozGyqpokP392H5/DOAUUZmUpyZDaUEEE=", "1Dyz8CvmF17oKT/wG2fu3vRzPzgQv8/OY9GJYew4FG8=" }, + { "yOumS9HN68ZwIm+5hZol3jFQ0DB4SKuW/ld3y8wioGk=", "6PowsbKj/fKSzXZMAfaSkP3fE+4AThL9xm6ysQzMDxg=", "vF8cKu9X9FxgCjyVZ5RG7nuue8RelF5Qsb8Efme4M4A=" }, + { "mISm5vQfPdK72SsaHh6O1/ARvaWCtm+KZNcpTsyt500=", "YCORDQDpb1U8vADdstBgXkg0N7QaAc5VoXJ4QFuA/UY=", "JlrBmfaCgbfEVD9YQq3c03WwwsHWc1nBwp1JkFORC3A=" }, + { "cPyu3Qry6qbsiOJKFGRziZ9LJWJ47k3ZSXiGkQXuQm0=", "/cmBZTbqEp8sababPAxGb3OvDAEE7MlwPOwEFHE+7yM=", "lp0Hhc/rVtpT5FtLLccChqDl3El48XtP6Wm6JwjI7jo=" }, + { "YKsMYU0SINbPwWw4RDCJV6GnzDlSp1ZNwUw2euGWi0A=", "/KmBReATQbFnLg8YKV0jwhqKeishRoWvlVtMX3550Vk=", "7fXpPSMo1Fw2sOXtjTtvFU+DbZvS/FWB9wAsywWx6R4=" }, + { "WD0YI3y71eIp/GXw9i+7scEiQKSBkGihZWE+s6fGmWo=", "RdthAL/qPnAZFb3xBgRMiAtGHNjgokzoKX9iO2K5qhc=", "4dk4HGkT9dBmomGNorDE/hLr/HEFhljtl4zz3M4sG58=" }, + { "oD8KWhJYZVhutJRb0kZlZnB22QUXzi2FfPRD0ll65UM=", "MYTBGHh4Ukj97pKj6qcfWmxGNQzmU3/aBOX2f1tfhG0=", "VT1gC+a9nRJzYMi/TPvRVnn3IQlaop/jKmmxZePEME0=" }, + { "0Ns/1SOiqR2CpHRG03QNzJJd5gxTm1XJmSkFlugjQ3k=", "KvQAI+ekNOa2xfEvfyc9JGcS+CTUrnnhsKrlyJGJixg=", "J8LmSX6zElX3S9q4PNvh2NKUtAiQ3oHiYjSJ7yErPlY=" }, + { "mD6TeF4ezSPXN/csN1OhoAREFSXllI+zl4DUOInVq2Q=", "WmLJ9ep2EqFcSftnYFJsmWyUxqL0zzuSzVEv94PcISM=", "U2+ILy2NDmmfgSW78C8dl8GyHESUc1lXPHPpg5F+gr8=" }, + { "SMJoXOYgHz8HSzY+ByeWLcSP5qFwv7YjRe0bcKesRnM=", "DEsNSOY3TEs9J2YgqroQ4xKq8T8xNJQjvvE4UrTItQw=", "Bws1Hk2+lO+JQ7ME16EbwAdsBkWsGvti0Gb6LY2Lrms=" }, + { "iGhXF0Hg0tqZmpwAMiolxvbvTPClQ7LlBAspSSyFEHE=", "7Xxzpwl7yRWehHNWTYVtFkdChJdXhtY4Mtw1fA9QcCg=", "Swjfv0PjuaE8Oq3a17BVno5I+q49dZlPwKK1bPUoKNI=" }, + { "MIazjx3qTi6Qz3WzhtCPw3i4Q2uZBHcuMoh++ZGFYUk=", "oni8pbFqk9Ya+Fx+911Nl1SN0FD/hR1jwb2RH3t/pRk=", "ZYAFcj67LkbNURYbSnCCWGxAG8QLDGWwbl968mA6ZA4=" }, + { "MAadYdiFM2cPuJF19q20Yoo5KJabuR9TUQ9jG5nvA1w=", "5OcE8XV+UPoBVbgqBQdVF62GZCW9DOQEdxrQsktPPBA=", "FCZsEFXouy+xtxv8X7VroXtvPG1Z1HFHL724tz1jcUI=" }, + { "+GwxMmD2dee5+QmvXNI0NdP+rNWoSXTN42otbp0aZ24=", "Y0N44baz9ihclCUnv6rRbDqCYu4BxQlBfNnTz3NNe2A=", "/LqSgkVQNkQ/oBiZSgpM9Rw7BJv0RvRpEQpvlizvHy0=" }, + { "8FREpCtncOcT7+W2nW4aYSjmSbADtVSH9rIliQZZUH4=", "fTNSd0JeREhXmPfjrmrAu6Lu/yHkB9GyxR3SyO4kZ28=", "262KN/iG/iJEaZeerFm1yVtvhFVGgQFwSvtxTcjZzeg=" }, + { "EDhaRQGtscjoSE9wJOnSXoQVtVruIqyzknty+x/vDWo=", "eMmMgws6ZxDIxZ6QSwGjZO1Mx/r5T+fJjSTKGMBk/BU=", "0CyaJV6AG9bZ0C4yeZ/RDsOs9BdNqZpUxAsD30WmJO4=" }, + { "CJV0UB2YdvVDG1cs4oiJgHAS+f1FocGr/vGCfiovsWQ=", "9/O9GWZEOXVm7On8lftL27PffRORju8OKl6gZd/74CA=", "A+kXRVNOwIrA5DUa+3v7dpRC+Gbxm23LTiYmOUAXUyY=" }, + { "gCjDsJUwZGA7BjYVoCQsvdIgN9Q4lBHlSyKwUrl751A=", "HRwS8T9y2qPYk7JVU/8Y+6cS+Bk8XCLCXxwN/ttbQiI=", "iFotjA6rhUfkDv4S/wspJgEWunEmrlGSGsXcJ0+8laQ=" }, + { "6N5pL4gsuK+shHpDxirTnAGdyKXIlYHyfIhtB0njJGA=", "CVZvW7NaN2XMEEKHodghBA9hLCwee/jrmttiWh/CmEg=", "OpPEd3Sp8r6KdjNDTN4bVHETlGJ92BCK74FCdEaDe9g=" }, + { "UIPPTUdvhlg8qEDv6JRxM4/8F5ORjJz4ud82QZrgeEY=", "7Nd13z5EpB3ChytvQC1CxvDY7n0H8r2Y7lzLEY8hdEk=", "b22PvgU0M2QfNC7ZGN+RXNe5fjOzMsY32IcHTwLNIqw=" }, + { "oBn53Q5fmxKX02PgI6F47Rb+XoLeFQO07ok2tYhk0lE=", "e0gtPDKXCZSoNW1uHqBPQXLfiYgyeqPMU2zZJgPXACI=", "wmjW2wDT2EzFkyaGui7YWNLTRu8Q4eD/GVKM2utZkEs=" }, + }; + gs_unref_ptrarray GPtrArray *allowed_ips_keep_alive = NULL; + gs_unref_array GArray *peers = NULL; + NMPlatformLnkWireGuard lnk_wireguard; + int r; + guint i; + + allowed_ips_keep_alive = g_ptr_array_new_with_free_func (g_free); + + peers = g_array_new (FALSE, TRUE, sizeof (NMPWireGuardPeer)); + + lnk_wireguard = (NMPlatformLnkWireGuard) { + .listen_port = 50754, + .fwmark = 0x1102, + }; + _copy_base64 (lnk_wireguard.private_key, sizeof (lnk_wireguard.private_key), self_key.pri); + _copy_base64 (lnk_wireguard.public_key, sizeof (lnk_wireguard.public_key), self_key.pub); + + if (test_mode == 0) { + /* no peers. */ + } else if (NM_IN_SET (test_mode, 1, 2)) { + guint num_peers = (test_mode == 1) ? 1 : G_N_ELEMENTS (keys); + + for (i = 0; i < num_peers; i++) { + NMPWireGuardPeer peer; + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + NMSockAddrUnion endpoint; + guint i_allowed_ips, n_allowed_ips; + NMPWireGuardAllowedIP *allowed_ips; + + if ((i % 2) == 1) { + endpoint = (NMSockAddrUnion) { + .in = { + .sin_family = AF_INET, + .sin_addr = nmtst_inet4_from_string (nm_sprintf_buf (s_addr, "192.168.7.%d", i)), + .sin_port = htons (14000 + i), + }, + }; + } else { + endpoint = (NMSockAddrUnion) { + .in6 = { + .sin6_family = AF_INET6, + .sin6_addr = *nmtst_inet6_from_string (nm_sprintf_buf (s_addr, "a:b:c:e::1:%d", i)), + .sin6_port = htons (16000 + i), + }, + }; + } + + if (test_mode == 1) + n_allowed_ips = 1; + else + n_allowed_ips = i % 10; + allowed_ips = g_new0 (NMPWireGuardAllowedIP, n_allowed_ips); + g_ptr_array_add (allowed_ips_keep_alive, allowed_ips); + for (i_allowed_ips = 0; i_allowed_ips < n_allowed_ips; i_allowed_ips++) { + NMPWireGuardAllowedIP *aip = &allowed_ips[i_allowed_ips]; + + aip->family = (i_allowed_ips % 2) ? AF_INET : AF_INET6; + if (aip->family == AF_INET) { + aip->addr.addr4 = nmtst_inet4_from_string (nm_sprintf_buf (s_addr, "10.%u.%u.0", i, i_allowed_ips)); + aip->mask = 32 - (i_allowed_ips % 8); + } else { + aip->addr.addr6 = *nmtst_inet6_from_string (nm_sprintf_buf (s_addr, "a:d:f:%02x:%02x::", i, i_allowed_ips)); + aip->mask = 128 - (i_allowed_ips % 10); + } + } + + peer = (NMPWireGuardPeer) { + .persistent_keepalive_interval = 60+i, + .endpoint = endpoint, + .allowed_ips = n_allowed_ips > 0 ? allowed_ips : NULL, + .allowed_ips_len = n_allowed_ips, + }; + _copy_base64 (peer.public_key, sizeof (peer.public_key), keys[i].pub); + _copy_base64 (peer.preshared_key, sizeof (peer.preshared_key), (i % 3) ? NULL : keys[i].pre); + + g_array_append_val (peers, peer); + } + } else + g_assert_not_reached (); + + r = nm_platform_link_wireguard_change (platform, + ifindex, + &lnk_wireguard, + (const NMPWireGuardPeer *) peers->data, + peers->len, + TRUE); + g_assert (NMTST_NM_ERR_SUCCESS (r)); +} + +/*****************************************************************************/ + typedef struct { NMLinkType link_type; int test_mode; @@ -697,6 +932,7 @@ test_software_detect (gconstpointer user_data) int ifindex, ifindex_parent; const NMPlatformLink *plink; const NMPObject *lnk; + int r; guint i_step; const gboolean ext = test_data->external_command; NMPlatformLnkTun lnk_tun; @@ -897,7 +1133,7 @@ test_software_detect (gconstpointer user_data) 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); + nmtstp_link_delete (NM_PLATFORM_GET, FALSE, dummy->ifindex, NULL, TRUE); } if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) @@ -1005,6 +1241,19 @@ test_software_detect (gconstpointer user_data) : NULL)); break; } + case NM_LINK_TYPE_WIREGUARD: { + const NMPlatformLink *link; + + r = nm_platform_link_wireguard_add (NM_PLATFORM_GET, DEVICE_NAME, &link); + if (r == -EOPNOTSUPP) { + g_test_skip ("wireguard not supported (modprobe wireguard?)"); + goto out_delete_parent; + } + + g_assert (NMTST_NM_ERR_SUCCESS (r)); + g_assert (NMP_OBJECT_GET_TYPE (NMP_OBJECT_UP_CAST (link)) == NMP_OBJECT_TYPE_LINK); + break; + } default: g_assert_not_reached (); } @@ -1217,7 +1466,7 @@ test_software_detect (gconstpointer user_data) g_assert_cmpint (plnk->dst_port, ==, 4789); if ( plnk->src_port_min != 0 || plnk->src_port_max != 0) { - /* on some kernels, omiting the port range results in setting + /* on some kernels, omitting the port range results in setting * following default port range. */ g_assert_cmpint (plnk->src_port_min, ==, 32768); g_assert_cmpint (plnk->src_port_max, ==, 61000); @@ -1238,14 +1487,26 @@ test_software_detect (gconstpointer user_data) } break; } + case NM_LINK_TYPE_WIREGUARD: { + const NMPlatformLnkWireGuard *plnk = &lnk->lnk_wireguard; + + g_assert (plnk == nm_platform_link_get_lnk_wireguard (NM_PLATFORM_GET, ifindex, NULL)); + + if (plink->n_ifi_flags & IFF_UP) { + _test_wireguard_change (NM_PLATFORM_GET, plink->ifindex, test_data->test_mode); + if (_LOGD_ENABLED ()) + _system ("WG_HIDE_KEYS=never wg show all"); + } + break; + } default: g_assert_not_reached (); } } - nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); + nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); out_delete_parent: - nmtstp_link_del (NULL, -1, ifindex_parent, PARENT_NAME); + nmtstp_link_delete (NULL, -1, ifindex_parent, PARENT_NAME, TRUE); } static void @@ -1822,8 +2083,8 @@ test_vlan_set_xgress (void) _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP); } - nmtstp_link_del (NULL, -1, ifindex, DEVICE_NAME); - nmtstp_link_del (NULL, -1, ifindex_parent, PARENT_NAME); + nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); + nmtstp_link_delete (NULL, -1, ifindex_parent, PARENT_NAME, TRUE); } /*****************************************************************************/ @@ -1879,7 +2140,7 @@ test_create_many_links_do (guint n_devices) if (EX == 2) nmtstp_run_command_check ("ip link delete %s", name); else - nmtstp_link_del (NULL, EX, g_array_index (ifindexes, int, i), name); + nmtstp_link_delete (NULL, EX, g_array_index (ifindexes, int, i), name, TRUE); } _LOGI (">>> process events after deleting devices..."); @@ -1965,7 +2226,7 @@ test_nl_bugs_veth (void) }); out: - nmtstp_link_del (NULL, -1, ifindex_veth0, IFACE_VETH0); + nmtstp_link_delete (NULL, -1, ifindex_veth0, IFACE_VETH0, TRUE); g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth0, IFACE_VETH0)); g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth1, IFACE_VETH1)); nmtstp_namespace_handle_release (ns_handle); @@ -2018,7 +2279,7 @@ again: } g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_bond0, IFACE_BOND0)); - nmtstp_link_del (NULL, -1, ifindex_dummy0, IFACE_DUMMY0); + nmtstp_link_delete (NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); } /*****************************************************************************/ @@ -2072,8 +2333,8 @@ again: goto again; } - nmtstp_link_del (NULL, -1, ifindex_bridge0, IFACE_BRIDGE0); - nmtstp_link_del (NULL, -1, ifindex_dummy0, IFACE_DUMMY0); + nmtstp_link_delete (NULL, -1, ifindex_bridge0, IFACE_BRIDGE0, TRUE); + nmtstp_link_delete (NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); } /*****************************************************************************/ @@ -2637,8 +2898,8 @@ test_sysctl_rename (void) } nm_platform_process_events (PL); - nmtstp_link_del (PL, -1, ifindex[0], NULL); - nmtstp_link_del (PL, -1, ifindex[1], NULL); + nmtstp_link_delete (PL, -1, ifindex[0], NULL, TRUE); + nmtstp_link_delete (PL, -1, ifindex[1], NULL, TRUE); } /*****************************************************************************/ @@ -2717,7 +2978,7 @@ test_sysctl_netns_switch (void) else g_assert_cmpint (ifindex_tmp, ==, -1); - nmtstp_link_del (PL, FALSE, ifindex, NULL); + nmtstp_link_delete (PL, FALSE, ifindex, NULL, TRUE); } /*****************************************************************************/ @@ -2800,12 +3061,8 @@ test_ethtool_features_get (void) ethtool_features_dump (features); - if (_LOGT_ENABLED ()) { - int ignore; - - ignore = system ("ethtool -k lo"); - (void) ignore; - } + if (_LOGT_ENABLED ()) + _system ("ethtool -k lo"); if (!do_set) { requested = gfree_keeper->pdata[i_run * 2 - 2]; @@ -2829,9 +3086,9 @@ _nmtstp_init_tests (int *argc, char ***argv) void _nmtstp_setup_tests (void) { - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME)); - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME)); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, SLAVE_NAME, FALSE); + nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, PARENT_NAME, FALSE); g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, SLAVE_NAME)); g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, PARENT_NAME)); @@ -2862,6 +3119,9 @@ _nmtstp_setup_tests (void) test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0); test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0); test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1); + test_software_detect_add ("/link/software/detect/wireguard/0", NM_LINK_TYPE_WIREGUARD, 0); + test_software_detect_add ("/link/software/detect/wireguard/1", NM_LINK_TYPE_WIREGUARD, 1); + test_software_detect_add ("/link/software/detect/wireguard/2", NM_LINK_TYPE_WIREGUARD, 2); g_test_add_func ("/link/software/vlan/set-xgress", test_vlan_set_xgress); diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 85b14b57..4c0f686f 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -427,7 +427,7 @@ test_ip4_route_get (void) { int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); in_addr_t a; - NMPlatformError result; + int result; nm_auto_nmpobj NMPObject *route = NULL; const NMPlatformIP4Route *r; @@ -446,7 +446,7 @@ test_ip4_route_get (void) nmtst_get_rand_int () % 2 ? 0 : ifindex, &route); - g_assert (result == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (result)); g_assert (NMP_OBJECT_GET_TYPE (route) == NMP_OBJECT_TYPE_IP4_ROUTE); g_assert (!NMP_OBJECT_IS_STACKINIT (route)); g_assert (route->parent._ref_count == 1); @@ -565,7 +565,7 @@ test_ip4_route_options (gconstpointer test_data) } for (i = 0; i < rts_n; i++) - g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); for (i = 0; i < rts_n; i++) { rts_cmp[i] = rts_add[i]; @@ -589,7 +589,7 @@ test_ip6_route_get (void) { int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); const struct in6_addr *a; - NMPlatformError result; + int result; nm_auto_nmpobj NMPObject *route = NULL; const NMPlatformIP6Route *r; @@ -608,7 +608,7 @@ test_ip6_route_get (void) nmtst_get_rand_int () % 2 ? 0 : ifindex, &route); - g_assert (result == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (result)); g_assert (NMP_OBJECT_GET_TYPE (route) == NMP_OBJECT_TYPE_IP6_ROUTE); g_assert (!NMP_OBJECT_IS_STACKINIT (route)); g_assert (route->parent._ref_count == 1); @@ -724,7 +724,7 @@ test_ip6_route_options (gconstpointer test_data) _wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 400, IFINDEX, addr_n, addr_in6); for (i = 0; i < rts_n; i++) - g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); for (i = 0; i < rts_n; i++) { rts_cmp[i] = rts_add[i]; @@ -823,7 +823,7 @@ again_find_idx: order_idx[order_len++] = idx; r->ifindex = iface_data[idx].ifindex; - g_assert (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_APPEND, r) == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_APPEND, r))); } else { i = nmtst_get_rand_int () % order_len; idx = order_idx[i]; diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/nm-wifi-utils-nl80211.c index b3bb2bb6..0df3d2d8 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/nm-wifi-utils-nl80211.c @@ -30,7 +30,9 @@ #include <net/ethernet.h> #include <unistd.h> #include <linux/nl80211.h> +#include <linux/if.h> +#include "nm-utils/nm-errno.h" #include "platform/nm-netlink.h" #include "nm-wifi-utils-private.h" #include "platform/nm-platform.h" @@ -38,11 +40,16 @@ #include "nm-utils.h" #define _NMLOG_PREFIX_NAME "wifi-nl80211" -#define _NMLOG(level, domain, ...) \ +#define _NMLOG_DOMAIN LOGD_PLATFORM | LOGD_WIFI +#define _NMLOG(level, ...) \ G_STMT_START { \ - nm_log ((level), (domain), NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME \ + char _ifname_buf[IFNAMSIZ]; \ + const char *_ifname = self ? nmp_utils_if_indextoname (self->parent.ifindex, _ifname_buf) : NULL; \ + \ + nm_log ((level), _NMLOG_DOMAIN, _ifname ?: NULL, NULL, \ + "%s%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + NM_PRINT_FMT_QUOTED (_ifname, " (", _ifname, ")", "") \ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } G_STMT_END @@ -103,16 +110,16 @@ nla_put_failure: } static struct nl_msg * -nl80211_alloc_msg (NMWifiUtilsNl80211 *nl80211, guint32 cmd, guint32 flags) +nl80211_alloc_msg (NMWifiUtilsNl80211 *self, guint32 cmd, guint32 flags) { - return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, nl80211->phy, cmd, flags); + return _nl80211_alloc_msg (self->id, self->parent.ifindex, self->phy, cmd, flags); } static int -_nl80211_send_and_recv (struct nl_sock *nl_sock, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) +nl80211_send_and_recv (NMWifiUtilsNl80211 *self, + struct nl_msg *msg, + int (*valid_handler) (struct nl_msg *, void *), + void *valid_data) { int err; int done = 0; @@ -129,7 +136,7 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, g_return_val_if_fail (msg != NULL, -ENOMEM); - err = nl_send_auto (nl_sock, msg); + err = nl_send_auto (self->nl_sock, msg); if (err < 0) return err; @@ -137,19 +144,18 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, * done will be 1, on error it will be < 0. */ while (!done) { - err = nl_recvmsgs (nl_sock, &cb); + err = nl_recvmsgs (self->nl_sock, &cb); if (err < 0 && err != -EAGAIN) { /* Kernel scan list can change while we are dumping it, as new scan * results from H/W can arrive. BSS info is assured to be consistent * and we don't need consistent view of whole scan list. Hence do * not warn on DUMP_INTR error for get scan command. */ - if (err == -NLE_DUMP_INTR && + if (err == -NME_NL_DUMP_INTR && genlmsg_hdr (nlmsg_hdr (msg))->cmd == NL80211_CMD_GET_SCAN) break; - _LOGW (LOGD_WIFI, "nl_recvmsgs() error: (%d) %s", - err, nl_geterror (err)); + _LOGW ("nl_recvmsgs() error: (%d) %s", err, nm_strerror (err)); break; } } @@ -159,22 +165,12 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, return err; } -static int -nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - return _nl80211_send_and_recv (nl80211->nl_sock, msg, - valid_handler, valid_data); -} - static void dispose (GObject *object) { - NMWifiUtilsNl80211 *nl80211 = NM_WIFI_UTILS_NL80211 (object); + NMWifiUtilsNl80211 *self = NM_WIFI_UTILS_NL80211 (object); - g_clear_pointer (&nl80211->freqs, g_free); + g_clear_pointer (&self->freqs, g_free); } struct nl80211_iface_info { @@ -213,15 +209,15 @@ nl80211_iface_info_handler (struct nl_msg *msg, void *arg) static NM80211Mode wifi_nl80211_get_mode (NMWifiUtils *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_iface_info iface_info = { .mode = NM_802_11_MODE_UNKNOWN, }; nm_auto_nlmsg struct nl_msg *msg = NULL; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_INTERFACE, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_INTERFACE, 0); - if (nl80211_send_and_recv (nl80211, msg, nl80211_iface_info_handler, + if (nl80211_send_and_recv (self, msg, nl80211_iface_info_handler, &iface_info) < 0) return NM_802_11_MODE_UNKNOWN; @@ -231,11 +227,11 @@ wifi_nl80211_get_mode (NMWifiUtils *data) static gboolean wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_INTERFACE, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_SET_INTERFACE, 0); switch (mode) { case NM_802_11_MODE_INFRA: @@ -251,7 +247,7 @@ wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode) g_assert_not_reached (); } - err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); + err = nl80211_send_and_recv (self, msg, NULL, NULL); return err >= 0; nla_put_failure: @@ -261,14 +257,14 @@ nla_put_failure: static gboolean wifi_nl80211_set_powersave (NMWifiUtils *data, guint32 powersave) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_POWER_SAVE, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_SET_POWER_SAVE, 0); NLA_PUT_U32 (msg, NL80211_ATTR_PS_STATE, powersave == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED); - err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); + err = nl80211_send_and_recv (self, msg, NULL, NULL); return err >= 0; nla_put_failure: @@ -318,13 +314,13 @@ nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg) static NMSettingWirelessWakeOnWLan wifi_nl80211_get_wake_on_wlan (NMWifiUtils *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; nm_auto_nlmsg struct nl_msg *msg = NULL; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_WOWLAN, 0); - nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl); + nl80211_send_and_recv (self, msg, nl80211_get_wake_on_wlan_handler, &wowl); return wowl; } @@ -332,7 +328,7 @@ wifi_nl80211_get_wake_on_wlan (NMWifiUtils *data) static gboolean wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *triggers; int err; @@ -340,7 +336,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_SET_WOWLAN, 0); if (!msg) return FALSE; @@ -363,7 +359,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo nla_nest_end(msg, triggers); - err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); + err = nl80211_send_and_recv (self, msg, NULL, NULL); return err >= 0; @@ -491,25 +487,25 @@ nl80211_bss_dump_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_bss_info (NMWifiUtilsNl80211 *self, struct nl80211_bss_info *bss_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; memset (bss_info, 0, sizeof (*bss_info)); - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_SCAN, NLM_F_DUMP); + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_SCAN, NLM_F_DUMP); - nl80211_send_and_recv (nl80211, msg, nl80211_bss_dump_handler, bss_info); + nl80211_send_and_recv (self, msg, nl80211_bss_dump_handler, bss_info); } static guint32 wifi_nl80211_get_freq (NMWifiUtils *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_bss_info bss_info; - nl80211_get_bss_info (nl80211, &bss_info); + nl80211_get_bss_info (self, &bss_info); return bss_info.freq; } @@ -517,12 +513,12 @@ wifi_nl80211_get_freq (NMWifiUtils *data) static guint32 wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; int i; - for (i = 0; i < nl80211->num_freqs; i++) { + for (i = 0; i < self->num_freqs; i++) { while (*freqs) { - if (nl80211->freqs[i] == *freqs) + if (self->freqs[i] == *freqs) return *freqs; freqs++; } @@ -533,10 +529,10 @@ wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) static gboolean wifi_nl80211_get_bssid (NMWifiUtils *data, guint8 *out_bssid) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_bss_info bss_info; - nl80211_get_bss_info (nl80211, &bss_info); + nl80211_get_bss_info (self, &bss_info); if (bss_info.valid) memcpy (out_bssid, bss_info.bssid, ETH_ALEN); @@ -615,7 +611,7 @@ nl80211_station_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_ap_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_ap_info (NMWifiUtilsNl80211 *self, struct nl80211_station_info *sta_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -623,15 +619,15 @@ nl80211_get_ap_info (NMWifiUtilsNl80211 *nl80211, memset (sta_info, 0, sizeof (*sta_info)); - nl80211_get_bss_info (nl80211, &bss_info); + nl80211_get_bss_info (self, &bss_info); if (!bss_info.valid) return; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_STATION, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_STATION, 0); if (msg) { NLA_PUT (msg, NL80211_ATTR_MAC, ETH_ALEN, bss_info.bssid); - nl80211_send_and_recv (nl80211, msg, nl80211_station_handler, sta_info); + nl80211_send_and_recv (self, msg, nl80211_station_handler, sta_info); if (!sta_info->signal_valid) { /* Fall back to bss_info signal quality (both are in percent) */ sta_info->signal = bss_info.beacon_signal; @@ -647,10 +643,10 @@ nla_put_failure: static guint32 wifi_nl80211_get_rate (NMWifiUtils *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_station_info sta_info; - nl80211_get_ap_info (nl80211, &sta_info); + nl80211_get_ap_info (self, &sta_info); return sta_info.txrate; } @@ -658,21 +654,21 @@ wifi_nl80211_get_rate (NMWifiUtils *data) static int wifi_nl80211_get_qual (NMWifiUtils *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; struct nl80211_station_info sta_info; - nl80211_get_ap_info (nl80211, &sta_info); + nl80211_get_ap_info (self, &sta_info); return sta_info.signal; } static gboolean wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + NMWifiUtilsNl80211 *self = (NMWifiUtilsNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; - msg = nl80211_alloc_msg (nl80211, + msg = nl80211_alloc_msg (self, running ? 98 /* NL80211_CMD_CRIT_PROTOCOL_START */ : 99 /* NL80211_CMD_CRIT_PROTOCOL_STOP */, @@ -690,7 +686,7 @@ wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running) 5000); } - err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); + err = nl80211_send_and_recv (self, msg, NULL, NULL); return err >= 0; nla_put_failure: @@ -698,6 +694,7 @@ nla_put_failure: } struct nl80211_device_info { + NMWifiUtilsNl80211 *self; int phy; guint32 *freqs; int num_freqs; @@ -723,6 +720,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); struct nl80211_device_info *info = arg; + NMWifiUtilsNl80211 *self = info->self; struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; struct nlattr *nl_band; @@ -872,8 +870,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) case WLAN_CIPHER_SUITE_SMS4: break; default: - _LOGD (LOGD_PLATFORM | LOGD_WIFI, - "don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", + _LOGD ("don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", ciphers[i]); break; } @@ -929,86 +926,66 @@ nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass) NMWifiUtils * nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) { - gs_unref_object NMWifiUtilsNl80211 *nl80211 = NULL; + gs_unref_object NMWifiUtilsNl80211 *self = NULL; nm_auto_nlmsg struct nl_msg *msg = NULL; - struct nl80211_device_info device_info = {}; - char ifname[IFNAMSIZ]; + struct nl80211_device_info device_info = { }; if (!genl) return NULL; - if (!nmp_utils_if_indextoname (ifindex, ifname)) { - _LOGW (LOGD_PLATFORM | LOGD_WIFI, - "can't determine interface name for ifindex %d", ifindex); - nm_sprintf_buf (ifname, "if %d", ifindex); - } - - nl80211 = g_object_new (NM_TYPE_WIFI_UTILS_NL80211, NULL); + self = g_object_new (NM_TYPE_WIFI_UTILS_NL80211, NULL); - nl80211->parent.ifindex = ifindex; - nl80211->nl_sock = genl; + self->parent.ifindex = ifindex; + self->nl_sock = genl; - nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); - if (nl80211->id < 0) { - _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); + self->id = genl_ctrl_resolve (self->nl_sock, "nl80211"); + if (self->id < 0) { + _LOGD ("genl_ctrl_resolve: failed to resolve \"nl80211\""); return NULL; } - nl80211->phy = -1; + self->phy = -1; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WIPHY, 0); + msg = nl80211_alloc_msg (self, NL80211_CMD_GET_WIPHY, 0); - if (nl80211_send_and_recv (nl80211, msg, nl80211_wiphy_info_handler, + device_info.self = self; + if (nl80211_send_and_recv (self, msg, nl80211_wiphy_info_handler, &device_info) < 0) { - _LOGD (LOGD_PLATFORM | LOGD_WIFI, - "(%s): NL80211_CMD_GET_WIPHY request failed", - ifname); + _LOGD ("NL80211_CMD_GET_WIPHY request failed"); return NULL; } if (!device_info.success) { - _LOGD (LOGD_PLATFORM | LOGD_WIFI, - "(%s): NL80211_CMD_GET_WIPHY request indicated failure", - ifname); + _LOGD ("NL80211_CMD_GET_WIPHY request indicated failure"); return NULL; } if (!device_info.supported) { - _LOGD (LOGD_PLATFORM | LOGD_WIFI, - "(%s): driver does not fully support nl80211, falling back to WEXT", - ifname); + _LOGD ("driver does not fully support nl80211, falling back to WEXT"); return NULL; } if (!device_info.can_scan_ssid) { - _LOGE (LOGD_PLATFORM | LOGD_WIFI, - "(%s): driver does not support SSID scans", - ifname); + _LOGE ("driver does not support SSID scans"); return NULL; } if (device_info.num_freqs == 0 || device_info.freqs == NULL) { - nm_log_err (LOGD_PLATFORM | LOGD_WIFI, - "(%s): driver reports no supported frequencies", - ifname); + _LOGE ("driver reports no supported frequencies"); return NULL; } if (device_info.caps == 0) { - _LOGE (LOGD_PLATFORM | LOGD_WIFI, - "(%s): driver doesn't report support of any encryption", - ifname); + _LOGE ("driver doesn't report support of any encryption"); return NULL; } - nl80211->phy = device_info.phy; - nl80211->freqs = device_info.freqs; - nl80211->num_freqs = device_info.num_freqs; - nl80211->parent.caps = device_info.caps; - nl80211->can_wowlan = device_info.can_wowlan; + self->phy = device_info.phy; + self->freqs = device_info.freqs; + self->num_freqs = device_info.num_freqs; + self->parent.caps = device_info.caps; + self->can_wowlan = device_info.can_wowlan; - _LOGI (LOGD_PLATFORM | LOGD_WIFI, - "(%s): using nl80211 for WiFi device control", - ifname); - return (NMWifiUtils *) g_steal_pointer (&nl80211); + _LOGD ("using nl80211 for Wi-Fi device control"); + return (NMWifiUtils *) g_steal_pointer (&self); } diff --git a/src/platform/wifi/nm-wifi-utils-wext.c b/src/platform/wifi/nm-wifi-utils-wext.c index e52ae5a3..597f3152 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.c +++ b/src/platform/wifi/nm-wifi-utils-wext.c @@ -511,7 +511,7 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) errsv = errno; _LOGE (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, - "(%s): error setting SSID to '%s': %s", + "(%s): error setting SSID to %s: %s", ifname, (ssid_str = _nm_utils_ssid_to_string_arr (ssid, len)), strerror (errsv)); @@ -751,7 +751,7 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ; _LOGI (LOGD_PLATFORM | LOGD_WIFI, - "(%s): using WEXT for WiFi device control", + "(%s): using WEXT for Wi-Fi device control", ifname); return (NMWifiUtils *) wext; @@ -771,7 +771,7 @@ nm_wifi_utils_wext_is_wifi (const char *iface) /* performing an ioctl on a non-existing name may cause the automatic * loading of kernel modules, which should be avoided. * - * Usually, we should thus make sure that an inteface with this name + * Usually, we should thus make sure that an interface with this name * exists. * * Note that wifi_wext_is_wifi() has only one caller which just verified diff --git a/src/platform/wifi/nm-wifi-utils.h b/src/platform/wifi/nm-wifi-utils.h index 6cd178bd..36148b5a 100644 --- a/src/platform/wifi/nm-wifi-utils.h +++ b/src/platform/wifi/nm-wifi-utils.h @@ -62,7 +62,7 @@ gboolean nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid); /* Returns current bitrate in Kbps */ guint32 nm_wifi_utils_get_rate (NMWifiUtils *data); -/* Returns quality 0 - 100% on succes, or -1 on error */ +/* Returns quality 0 - 100% on success, or -1 on error */ int nm_wifi_utils_get_qual (NMWifiUtils *data); /* Tells the driver DHCP or SLAAC is running */ diff --git a/src/platform/wpan/nm-wpan-utils.c b/src/platform/wpan/nm-wpan-utils.c index 0544539a..f8708bc6 100644 --- a/src/platform/wpan/nm-wpan-utils.c +++ b/src/platform/wpan/nm-wpan-utils.c @@ -21,15 +21,23 @@ #include "nm-wpan-utils.h" +#include <linux/if.h> + +#include "nm-utils/nm-errno.h" #include "platform/linux/nl802154.h" #include "platform/nm-netlink.h" +#include "platform/nm-platform-utils.h" #define _NMLOG_PREFIX_NAME "wpan-nl802154" #define _NMLOG(level, domain, ...) \ G_STMT_START { \ - nm_log ((level), (domain), NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME \ + char _ifname_buf[IFNAMSIZ]; \ + const char *_ifname = self ? nmp_utils_if_indextoname (self->ifindex, _ifname_buf) : NULL; \ + \ + nm_log ((level), (domain), _ifname ?: NULL, NULL, \ + "%s%s%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + NM_PRINT_FMT_QUOTED (_ifname, " (", _ifname, ")", "") \ _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ } G_STMT_END @@ -95,10 +103,10 @@ nl802154_alloc_msg (NMWpanUtils *self, guint32 cmd, guint32 flags) } static int -_nl802154_send_and_recv (struct nl_sock *nl_sock, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) +nl802154_send_and_recv (NMWpanUtils *self, + struct nl_msg *msg, + int (*valid_handler) (struct nl_msg *, void *), + void *valid_data) { int err; int done = 0; @@ -115,7 +123,7 @@ _nl802154_send_and_recv (struct nl_sock *nl_sock, g_return_val_if_fail (msg != NULL, -ENOMEM); - err = nl_send_auto (nl_sock, msg); + err = nl_send_auto (self->nl_sock, msg); if (err < 0) return err; @@ -123,10 +131,10 @@ _nl802154_send_and_recv (struct nl_sock *nl_sock, * done will be 1, on error it will be < 0. */ while (!done) { - err = nl_recvmsgs (nl_sock, &cb); + err = nl_recvmsgs (self->nl_sock, &cb); if (err < 0 && err != -EAGAIN) { _LOGW (LOGD_PLATFORM, "nl_recvmsgs() error: (%d) %s", - err, nl_geterror (err)); + err, nm_strerror (err)); break; } } @@ -136,16 +144,6 @@ _nl802154_send_and_recv (struct nl_sock *nl_sock, return err; } -static int -nl802154_send_and_recv (NMWpanUtils *self, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - return _nl802154_send_and_recv (self->nl_sock, msg, - valid_handler, valid_data); -} - struct nl802154_interface { guint16 pan_id; guint16 short_addr; @@ -248,6 +246,24 @@ nla_put_failure: return FALSE; } +gboolean +nm_wpan_utils_set_channel (NMWpanUtils *self, guint8 page, guint8 channel) +{ + nm_auto_nlmsg struct nl_msg *msg = NULL; + int err; + + g_return_val_if_fail (self != NULL, FALSE); + + msg = nl802154_alloc_msg (self, NL802154_CMD_SET_CHANNEL, 0); + NLA_PUT_U8 (msg, NL802154_ATTR_PAGE, page); + NLA_PUT_U8 (msg, NL802154_ATTR_CHANNEL, channel); + err = nl802154_send_and_recv (self, msg, NULL, NULL); + return err >= 0; + +nla_put_failure: + return FALSE; +} + /*****************************************************************************/ static void @@ -264,23 +280,22 @@ NMWpanUtils * nm_wpan_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) { NMWpanUtils *self; - int id; g_return_val_if_fail (ifindex > 0, NULL); if (!genl) return NULL; - id = genl_ctrl_resolve (genl, "nl802154"); - if (id < 0) { - _LOGD (LOGD_PLATFORM, "genl_ctrl_resolve: failed to resolve \"nl802154\""); - return NULL; - } - self = g_object_new (NM_TYPE_WPAN_UTILS, NULL); self->ifindex = ifindex; self->nl_sock = genl; - self->id = id; + self->id = genl_ctrl_resolve (genl, "nl802154"); + + if (self->id < 0) { + _LOGD (LOGD_PLATFORM, "genl_ctrl_resolve: failed to resolve \"nl802154\""); + g_object_unref (self); + return NULL; + } return self; } diff --git a/src/platform/wpan/nm-wpan-utils.h b/src/platform/wpan/nm-wpan-utils.h index f7d0c03e..1b54ec49 100644 --- a/src/platform/wpan/nm-wpan-utils.h +++ b/src/platform/wpan/nm-wpan-utils.h @@ -44,4 +44,6 @@ gboolean nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id); guint16 nm_wpan_utils_get_short_addr (NMWpanUtils *self); gboolean nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr); +gboolean nm_wpan_utils_set_channel (NMWpanUtils *self, guint8 page, guint8 channel); + #endif /* __WPAN_UTILS_H__ */ |