platform: cleanup error paths
- drop "goto error_label" in favor of returning right away. At most places, there was no need to do any cleanup or the cleanup is handled via nm_auto(). - adjust the return types of wireguard functions to return a boolean success/failure, instead of some error code which we didn't use. - the change to _wireguard_get_link_properties() is intentional. This was wrong previously, because in _wireguard_get_link_properties() obj is always a newly created instance, and never has a genl family ID set. This will be improved later.
This commit is contained in:
@@ -557,18 +557,6 @@ _support_rta_pref_get (void)
|
|||||||
return _support_rta_pref >= 0;
|
return _support_rta_pref >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Support Generic Netlink family
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
static int
|
|
||||||
_support_genl_family (struct nl_sock *genl, const char *name)
|
|
||||||
{
|
|
||||||
int family_id = genl_ctrl_resolve (genl, name);
|
|
||||||
_LOG2D ("kernel-support: genetlink: %s: %s", name, family_id ? "detected" : "not detected");
|
|
||||||
return family_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* Various utilities
|
* Various utilities
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@@ -1058,18 +1046,21 @@ _nl_addattr_l (struct nlmsghdr *n,
|
|||||||
* NMPObject/netlink functions
|
* NMPObject/netlink functions
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
#define _check_addr_or_errout(tb, attr, addr_len) \
|
#define _check_addr_or_return_val(tb, attr, addr_len, ret_val) \
|
||||||
({ \
|
({ \
|
||||||
const struct nlattr *__t = (tb)[(attr)]; \
|
const struct nlattr *__t = (tb)[(attr)]; \
|
||||||
\
|
\
|
||||||
if (__t) { \
|
if (__t) { \
|
||||||
if (nla_len (__t) != (addr_len)) { \
|
if (nla_len (__t) != (addr_len)) { \
|
||||||
goto errout; \
|
return ret_val; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
!!__t; \
|
!!__t; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define _check_addr_or_return_null(tb, attr, addr_len) \
|
||||||
|
_check_addr_or_return_val (tb, attr, addr_len, NULL)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */
|
/* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */
|
||||||
@@ -1096,20 +1087,19 @@ _parse_af_inet6 (NMPlatform *platform,
|
|||||||
gboolean token_valid = FALSE;
|
gboolean token_valid = FALSE;
|
||||||
gboolean addr_gen_mode_valid = FALSE;
|
gboolean addr_gen_mode_valid = FALSE;
|
||||||
guint8 i6_addr_gen_mode_inv = 0;
|
guint8 i6_addr_gen_mode_inv = 0;
|
||||||
gboolean success = FALSE;
|
|
||||||
|
|
||||||
err = nla_parse_nested (tb, IFLA_INET6_MAX, attr, policy);
|
err = nla_parse_nested (tb, IFLA_INET6_MAX, attr, policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return FALSE;
|
||||||
|
|
||||||
if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4)
|
if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4)
|
||||||
goto errout;
|
return FALSE;
|
||||||
if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8)
|
if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8)
|
||||||
goto errout;
|
return FALSE;
|
||||||
if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8)
|
if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8)
|
||||||
goto errout;
|
return FALSE;
|
||||||
|
|
||||||
if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) {
|
if (_check_addr_or_return_val (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr), FALSE)) {
|
||||||
nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr));
|
nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr));
|
||||||
token_valid = TRUE;
|
token_valid = TRUE;
|
||||||
}
|
}
|
||||||
@@ -1125,12 +1115,11 @@ _parse_af_inet6 (NMPlatform *platform,
|
|||||||
if (i6_addr_gen_mode_inv == 0) {
|
if (i6_addr_gen_mode_inv == 0) {
|
||||||
/* an inverse addrgenmode of zero is unexpected. We need to reserve zero
|
/* an inverse addrgenmode of zero is unexpected. We need to reserve zero
|
||||||
* to signal "unset". */
|
* to signal "unset". */
|
||||||
goto errout;
|
return FALSE;
|
||||||
}
|
}
|
||||||
addr_gen_mode_valid = TRUE;
|
addr_gen_mode_valid = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = TRUE;
|
|
||||||
if (token_valid) {
|
if (token_valid) {
|
||||||
*out_token_valid = token_valid;
|
*out_token_valid = token_valid;
|
||||||
nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token);
|
nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token);
|
||||||
@@ -1139,8 +1128,7 @@ _parse_af_inet6 (NMPlatform *platform,
|
|||||||
*out_addr_gen_mode_valid = addr_gen_mode_valid;
|
*out_addr_gen_mode_valid = addr_gen_mode_valid;
|
||||||
*out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
|
*out_addr_gen_mode_inv = i6_addr_gen_mode_inv;
|
||||||
}
|
}
|
||||||
errout:
|
return TRUE;
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -1858,7 +1846,7 @@ struct _wireguard_device_buf {
|
|||||||
GArray *allowedips;
|
GArray *allowedips;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static gboolean
|
||||||
_wireguard_update_from_allowedips_nla (struct _wireguard_device_buf *buf,
|
_wireguard_update_from_allowedips_nla (struct _wireguard_device_buf *buf,
|
||||||
struct nlattr *allowedip_attr)
|
struct nlattr *allowedip_attr)
|
||||||
{
|
{
|
||||||
@@ -1872,11 +1860,11 @@ _wireguard_update_from_allowedips_nla (struct _wireguard_device_buf *buf,
|
|||||||
NMWireGuardAllowedIP *allowedip;
|
NMWireGuardAllowedIP *allowedip;
|
||||||
NMWireGuardAllowedIP new_allowedip = {0};
|
NMWireGuardAllowedIP new_allowedip = {0};
|
||||||
int addr_len;
|
int addr_len;
|
||||||
int ret;
|
int nlerr;
|
||||||
|
|
||||||
ret = nla_parse_nested (tba, WGALLOWEDIP_A_MAX, allowedip_attr, allowedip_policy);
|
nlerr = nla_parse_nested (tba, WGALLOWEDIP_A_MAX, allowedip_attr, allowedip_policy);
|
||||||
if (ret)
|
if (nlerr < 0)
|
||||||
goto errout;
|
return FALSE;
|
||||||
|
|
||||||
g_array_append_val (buf->allowedips, new_allowedip);
|
g_array_append_val (buf->allowedips, new_allowedip);
|
||||||
allowedip = &g_array_index (buf->allowedips, NMWireGuardAllowedIP, buf->allowedips->len - 1);
|
allowedip = &g_array_index (buf->allowedips, NMWireGuardAllowedIP, buf->allowedips->len - 1);
|
||||||
@@ -1889,25 +1877,19 @@ _wireguard_update_from_allowedips_nla (struct _wireguard_device_buf *buf,
|
|||||||
addr_len = sizeof (in_addr_t);
|
addr_len = sizeof (in_addr_t);
|
||||||
else if (allowedip->family == AF_INET6)
|
else if (allowedip->family == AF_INET6)
|
||||||
addr_len = sizeof (struct in6_addr);
|
addr_len = sizeof (struct in6_addr);
|
||||||
else {
|
else
|
||||||
ret = -EAFNOSUPPORT;
|
return FALSE;
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -EMSGSIZE;
|
_check_addr_or_return_val (tba, WGALLOWEDIP_A_IPADDR, addr_len, FALSE);
|
||||||
_check_addr_or_errout (tba, WGALLOWEDIP_A_IPADDR, addr_len);
|
|
||||||
if (tba[WGALLOWEDIP_A_IPADDR])
|
if (tba[WGALLOWEDIP_A_IPADDR])
|
||||||
nla_memcpy (&allowedip->ip, tba[WGALLOWEDIP_A_IPADDR], addr_len);
|
nla_memcpy (&allowedip->ip, tba[WGALLOWEDIP_A_IPADDR], addr_len);
|
||||||
|
|
||||||
if (tba[WGALLOWEDIP_A_CIDR_MASK])
|
if (tba[WGALLOWEDIP_A_CIDR_MASK])
|
||||||
allowedip->mask = nla_get_u8 (tba[WGALLOWEDIP_A_CIDR_MASK]);
|
allowedip->mask = nla_get_u8 (tba[WGALLOWEDIP_A_CIDR_MASK]);
|
||||||
|
|
||||||
ret = 0;
|
return TRUE;
|
||||||
errout:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static gboolean
|
||||||
_wireguard_update_from_peers_nla (struct _wireguard_device_buf *buf,
|
_wireguard_update_from_peers_nla (struct _wireguard_device_buf *buf,
|
||||||
struct nlattr *peer_attr)
|
struct nlattr *peer_attr)
|
||||||
{
|
{
|
||||||
@@ -1926,24 +1908,18 @@ _wireguard_update_from_peers_nla (struct _wireguard_device_buf *buf,
|
|||||||
NMWireGuardPeer *const last = buf->peers->len ? &g_array_index (buf->peers, NMWireGuardPeer, buf->peers->len - 1) : NULL;
|
NMWireGuardPeer *const last = buf->peers->len ? &g_array_index (buf->peers, NMWireGuardPeer, buf->peers->len - 1) : NULL;
|
||||||
NMWireGuardPeer *peer;
|
NMWireGuardPeer *peer;
|
||||||
NMWireGuardPeer new_peer = { 0 };
|
NMWireGuardPeer new_peer = { 0 };
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (nla_parse_nested (tbp, WGPEER_A_MAX, peer_attr, peer_policy)) {
|
if (nla_parse_nested (tbp, WGPEER_A_MAX, peer_attr, peer_policy) < 0)
|
||||||
ret = -EBADMSG;
|
return FALSE;
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tbp[WGPEER_A_PUBLIC_KEY]) {
|
if (!tbp[WGPEER_A_PUBLIC_KEY])
|
||||||
ret = -EBADMSG;
|
return FALSE;
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* a peer with the same public key as last peer is just a continuation for extra AllowedIPs */
|
/* a peer with the same public key as last peer is just a continuation for extra AllowedIPs */
|
||||||
if (last && !memcmp (nla_data (tbp[WGPEER_A_PUBLIC_KEY]), last->public_key, sizeof (last->public_key))) {
|
if ( last
|
||||||
|
&& !memcmp (nla_data (tbp[WGPEER_A_PUBLIC_KEY]), last->public_key, sizeof (last->public_key)))
|
||||||
peer = last;
|
peer = last;
|
||||||
goto add_allowedips;
|
else {
|
||||||
}
|
|
||||||
|
|
||||||
/* otherwise, start a new peer */
|
/* otherwise, start a new peer */
|
||||||
g_array_append_val (buf->peers, new_peer);
|
g_array_append_val (buf->peers, new_peer);
|
||||||
peer = &g_array_index (buf->peers, NMWireGuardPeer, buf->peers->len - 1);
|
peer = &g_array_index (buf->peers, NMWireGuardPeer, buf->peers->len - 1);
|
||||||
@@ -1970,22 +1946,19 @@ _wireguard_update_from_peers_nla (struct _wireguard_device_buf *buf,
|
|||||||
|
|
||||||
peer->allowedips = NULL;
|
peer->allowedips = NULL;
|
||||||
peer->allowedips_len = 0;
|
peer->allowedips_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
add_allowedips:
|
|
||||||
if (tbp[WGPEER_A_ALLOWEDIPS]) {
|
if (tbp[WGPEER_A_ALLOWEDIPS]) {
|
||||||
struct nlattr *attr;
|
struct nlattr *attr;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
nla_for_each_nested (attr, tbp[WGPEER_A_ALLOWEDIPS], rem) {
|
nla_for_each_nested (attr, tbp[WGPEER_A_ALLOWEDIPS], rem) {
|
||||||
ret = _wireguard_update_from_allowedips_nla (buf, attr);
|
if (!_wireguard_update_from_allowedips_nla (buf, attr))
|
||||||
if (ret)
|
return FALSE;
|
||||||
goto errout;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
return TRUE;
|
||||||
errout:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2005,11 +1978,11 @@ _wireguard_get_device_cb (struct nl_msg *msg, void *arg)
|
|||||||
struct nlattr *tbd[WGDEVICE_A_MAX + 1];
|
struct nlattr *tbd[WGDEVICE_A_MAX + 1];
|
||||||
NMPlatformLnkWireGuard *props = &buf->obj->lnk_wireguard;
|
NMPlatformLnkWireGuard *props = &buf->obj->lnk_wireguard;
|
||||||
struct nlmsghdr *nlh = nlmsg_hdr (msg);
|
struct nlmsghdr *nlh = nlmsg_hdr (msg);
|
||||||
int ret;
|
int nlerr;
|
||||||
|
|
||||||
ret = genlmsg_parse (nlh, 0, tbd, WGDEVICE_A_MAX, device_policy);
|
nlerr = genlmsg_parse (nlh, 0, tbd, WGDEVICE_A_MAX, device_policy);
|
||||||
if (ret)
|
if (nlerr < 0)
|
||||||
goto errout;
|
return NL_SKIP;
|
||||||
|
|
||||||
if (tbd[WGDEVICE_A_PRIVATE_KEY])
|
if (tbd[WGDEVICE_A_PRIVATE_KEY])
|
||||||
nla_memcpy (props->private_key, tbd[WGDEVICE_A_PRIVATE_KEY], sizeof (props->private_key));
|
nla_memcpy (props->private_key, tbd[WGDEVICE_A_PRIVATE_KEY], sizeof (props->private_key));
|
||||||
@@ -2025,15 +1998,12 @@ _wireguard_get_device_cb (struct nl_msg *msg, void *arg)
|
|||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
nla_for_each_nested (attr, tbd[WGDEVICE_A_PEERS], rem) {
|
nla_for_each_nested (attr, tbd[WGDEVICE_A_PEERS], rem) {
|
||||||
ret = _wireguard_update_from_peers_nla (buf, attr);
|
if (!_wireguard_update_from_peers_nla (buf, attr))
|
||||||
if (ret)
|
return NL_SKIP;
|
||||||
goto errout;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NL_OK;
|
return NL_OK;
|
||||||
errout:
|
|
||||||
return NL_SKIP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean _wireguard_get_link_properties (NMPlatform *platform, const NMPlatformLink *link, NMPObject *obj);
|
static gboolean _wireguard_get_link_properties (NMPlatform *platform, const NMPlatformLink *link, NMPObject *obj);
|
||||||
@@ -2084,7 +2054,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||||||
const char *nl_info_kind = NULL;
|
const char *nl_info_kind = NULL;
|
||||||
int err;
|
int err;
|
||||||
nm_auto_nmpobj NMPObject *obj = NULL;
|
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||||
NMPObject *obj_result = NULL;
|
|
||||||
gboolean completed_from_cache_val = FALSE;
|
gboolean completed_from_cache_val = FALSE;
|
||||||
gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL;
|
gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL;
|
||||||
const NMPObject *link_cached = NULL;
|
const NMPObject *link_cached = NULL;
|
||||||
@@ -2105,17 +2074,17 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||||||
obj = nmp_object_new_link (ifi->ifi_index);
|
obj = nmp_object_new_link (ifi->ifi_index);
|
||||||
|
|
||||||
if (id_only)
|
if (id_only)
|
||||||
goto id_only_handled;
|
return g_steal_pointer (&obj);
|
||||||
|
|
||||||
err = nlmsg_parse (nlh, sizeof (*ifi), tb, IFLA_MAX, policy);
|
err = nlmsg_parse (nlh, sizeof (*ifi), tb, IFLA_MAX, policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (!tb[IFLA_IFNAME])
|
if (!tb[IFLA_IFNAME])
|
||||||
goto errout;
|
return NULL;
|
||||||
nla_strlcpy(obj->link.name, tb[IFLA_IFNAME], IFNAMSIZ);
|
nla_strlcpy(obj->link.name, tb[IFLA_IFNAME], IFNAMSIZ);
|
||||||
if (!obj->link.name[0])
|
if (!obj->link.name[0])
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (!tb[IFLA_MTU]) {
|
if (!tb[IFLA_MTU]) {
|
||||||
/* Kernel has two places that send RTM_GETLINK messages:
|
/* Kernel has two places that send RTM_GETLINK messages:
|
||||||
@@ -2130,14 +2099,14 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||||||
* To some extent this is a hack and correct approach is to
|
* To some extent this is a hack and correct approach is to
|
||||||
* merge objects per-field.
|
* merge objects per-field.
|
||||||
*/
|
*/
|
||||||
goto errout;
|
return NULL;
|
||||||
}
|
}
|
||||||
obj->link.mtu = nla_get_u32 (tb[IFLA_MTU]);
|
obj->link.mtu = nla_get_u32 (tb[IFLA_MTU]);
|
||||||
|
|
||||||
if (tb[IFLA_LINKINFO]) {
|
if (tb[IFLA_LINKINFO]) {
|
||||||
err = nla_parse_nested (li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], policy_link_info);
|
err = nla_parse_nested (li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], policy_link_info);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (li[IFLA_INFO_KIND])
|
if (li[IFLA_INFO_KIND])
|
||||||
nl_info_kind = nla_get_string (li[IFLA_INFO_KIND]);
|
nl_info_kind = nla_get_string (li[IFLA_INFO_KIND]);
|
||||||
@@ -2357,13 +2326,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
obj->_link.netlink.is_in_netlink = TRUE;
|
obj->_link.netlink.is_in_netlink = TRUE;
|
||||||
id_only_handled:
|
return g_steal_pointer (&obj);
|
||||||
obj_result = obj;
|
|
||||||
obj = NULL;
|
|
||||||
errout:
|
|
||||||
return obj_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copied and heavily modified from libnl3's addr_msg_parser(). */
|
/* Copied and heavily modified from libnl3's addr_msg_parser(). */
|
||||||
@@ -2380,7 +2344,6 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
int err;
|
int err;
|
||||||
gboolean is_v4;
|
gboolean is_v4;
|
||||||
nm_auto_nmpobj NMPObject *obj = NULL;
|
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||||
NMPObject *obj_result = NULL;
|
|
||||||
int addr_len;
|
int addr_len;
|
||||||
guint32 lifetime, preferred, timestamp;
|
guint32 lifetime, preferred, timestamp;
|
||||||
|
|
||||||
@@ -2389,19 +2352,19 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
ifa = nlmsg_data(nlh);
|
ifa = nlmsg_data(nlh);
|
||||||
|
|
||||||
if (!NM_IN_SET (ifa->ifa_family, AF_INET, AF_INET6))
|
if (!NM_IN_SET (ifa->ifa_family, AF_INET, AF_INET6))
|
||||||
goto errout;
|
return NULL;
|
||||||
is_v4 = ifa->ifa_family == AF_INET;
|
is_v4 = ifa->ifa_family == AF_INET;
|
||||||
|
|
||||||
err = nlmsg_parse (nlh, sizeof(*ifa), tb, IFA_MAX, policy);
|
err = nlmsg_parse (nlh, sizeof(*ifa), tb, IFA_MAX, policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
addr_len = is_v4
|
addr_len = is_v4
|
||||||
? sizeof (in_addr_t)
|
? sizeof (in_addr_t)
|
||||||
: sizeof (struct in6_addr);
|
: sizeof (struct in6_addr);
|
||||||
|
|
||||||
if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128))
|
if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128))
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
@@ -2410,8 +2373,8 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
obj->ip_address.ifindex = ifa->ifa_index;
|
obj->ip_address.ifindex = ifa->ifa_index;
|
||||||
obj->ip_address.plen = ifa->ifa_prefixlen;
|
obj->ip_address.plen = ifa->ifa_prefixlen;
|
||||||
|
|
||||||
_check_addr_or_errout (tb, IFA_ADDRESS, addr_len);
|
_check_addr_or_return_null (tb, IFA_ADDRESS, addr_len);
|
||||||
_check_addr_or_errout (tb, IFA_LOCAL, addr_len);
|
_check_addr_or_return_null (tb, IFA_LOCAL, addr_len);
|
||||||
if (is_v4) {
|
if (is_v4) {
|
||||||
/* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they
|
/* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they
|
||||||
* are effectively 0.0.0.0 (all-zero). */
|
* are effectively 0.0.0.0 (all-zero). */
|
||||||
@@ -2475,10 +2438,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
&obj->ip_address.lifetime,
|
&obj->ip_address.lifetime,
|
||||||
&obj->ip_address.preferred);
|
&obj->ip_address.preferred);
|
||||||
|
|
||||||
obj_result = obj;
|
return g_steal_pointer (&obj);
|
||||||
obj = NULL;
|
|
||||||
errout:
|
|
||||||
return obj_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */
|
/* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */
|
||||||
@@ -2501,7 +2461,6 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
int err;
|
int err;
|
||||||
gboolean is_v4;
|
gboolean is_v4;
|
||||||
nm_auto_nmpobj NMPObject *obj = NULL;
|
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||||
NMPObject *obj_result = NULL;
|
|
||||||
int addr_len;
|
int addr_len;
|
||||||
struct {
|
struct {
|
||||||
gboolean is_present;
|
gboolean is_present;
|
||||||
@@ -2520,14 +2479,14 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
|
||||||
if (!NM_IN_SET (rtm->rtm_family, AF_INET, AF_INET6))
|
if (!NM_IN_SET (rtm->rtm_family, AF_INET, AF_INET6))
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (rtm->rtm_type != RTN_UNICAST)
|
if (rtm->rtm_type != RTN_UNICAST)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
err = nlmsg_parse (nlh, sizeof (struct rtmsg), tb, RTA_MAX, policy);
|
err = nlmsg_parse (nlh, sizeof (struct rtmsg), tb, RTA_MAX, policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
@@ -2537,7 +2496,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
: sizeof (struct in6_addr);
|
: sizeof (struct in6_addr);
|
||||||
|
|
||||||
if (rtm->rtm_dst_len > (is_v4 ? 32 : 128))
|
if (rtm->rtm_dst_len > (is_v4 ? 32 : 128))
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
* parse nexthops. Only handle routes with one nh.
|
* parse nexthops. Only handle routes with one nh.
|
||||||
@@ -2553,7 +2512,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
|
|
||||||
if (nh.is_present) {
|
if (nh.is_present) {
|
||||||
/* we don't support multipath routes. */
|
/* we don't support multipath routes. */
|
||||||
goto errout;
|
return NULL;
|
||||||
}
|
}
|
||||||
nh.is_present = TRUE;
|
nh.is_present = TRUE;
|
||||||
|
|
||||||
@@ -2567,9 +2526,9 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
rtnh->rtnh_len - sizeof (*rtnh),
|
rtnh->rtnh_len - sizeof (*rtnh),
|
||||||
policy);
|
policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (_check_addr_or_errout (ntb, RTA_GATEWAY, addr_len))
|
if (_check_addr_or_return_null (ntb, RTA_GATEWAY, addr_len))
|
||||||
memcpy (&nh.gateway, nla_data (ntb[RTA_GATEWAY]), addr_len);
|
memcpy (&nh.gateway, nla_data (ntb[RTA_GATEWAY]), addr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2586,7 +2545,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
|
|
||||||
if (tb[RTA_OIF])
|
if (tb[RTA_OIF])
|
||||||
ifindex = nla_get_u32 (tb[RTA_OIF]);
|
ifindex = nla_get_u32 (tb[RTA_OIF]);
|
||||||
if (_check_addr_or_errout (tb, RTA_GATEWAY, addr_len))
|
if (_check_addr_or_return_null (tb, RTA_GATEWAY, addr_len))
|
||||||
memcpy (&gateway, nla_data (tb[RTA_GATEWAY]), addr_len);
|
memcpy (&gateway, nla_data (tb[RTA_GATEWAY]), addr_len);
|
||||||
|
|
||||||
if (!nh.is_present) {
|
if (!nh.is_present) {
|
||||||
@@ -2600,10 +2559,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
* verify that it is a duplicate and ignore old-style nexthop. */
|
* verify that it is a duplicate and ignore old-style nexthop. */
|
||||||
if ( nh.ifindex != ifindex
|
if ( nh.ifindex != ifindex
|
||||||
|| memcmp (&nh.gateway, &gateway, addr_len) != 0)
|
|| memcmp (&nh.gateway, &gateway, addr_len) != 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (!nh.is_present)
|
} else if (!nh.is_present)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
@@ -2622,7 +2581,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
|
|
||||||
err = nla_parse_nested (mtb, RTAX_MAX, tb[RTA_METRICS], rtax_policy);
|
err = nla_parse_nested (mtb, RTAX_MAX, tb[RTA_METRICS], rtax_policy);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto errout;
|
return NULL;
|
||||||
|
|
||||||
if (mtb[RTAX_LOCK])
|
if (mtb[RTAX_LOCK])
|
||||||
lock = nla_get_u32 (mtb[RTAX_LOCK]);
|
lock = nla_get_u32 (mtb[RTAX_LOCK]);
|
||||||
@@ -2650,7 +2609,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
|
|
||||||
obj->ip_route.ifindex = nh.ifindex;
|
obj->ip_route.ifindex = nh.ifindex;
|
||||||
|
|
||||||
if (_check_addr_or_errout (tb, RTA_DST, addr_len))
|
if (_check_addr_or_return_null (tb, RTA_DST, addr_len))
|
||||||
memcpy (obj->ip_route.network_ptr, nla_data (tb[RTA_DST]), addr_len);
|
memcpy (obj->ip_route.network_ptr, nla_data (tb[RTA_DST]), addr_len);
|
||||||
|
|
||||||
obj->ip_route.plen = rtm->rtm_dst_len;
|
obj->ip_route.plen = rtm->rtm_dst_len;
|
||||||
@@ -2666,7 +2625,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
if (is_v4)
|
if (is_v4)
|
||||||
obj->ip4_route.scope_inv = nm_platform_route_scope_inv (rtm->rtm_scope);
|
obj->ip4_route.scope_inv = nm_platform_route_scope_inv (rtm->rtm_scope);
|
||||||
|
|
||||||
if (_check_addr_or_errout (tb, RTA_PREFSRC, addr_len)) {
|
if (_check_addr_or_return_null (tb, RTA_PREFSRC, addr_len)) {
|
||||||
if (is_v4)
|
if (is_v4)
|
||||||
memcpy (&obj->ip4_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len);
|
memcpy (&obj->ip4_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len);
|
||||||
else
|
else
|
||||||
@@ -2677,7 +2636,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
obj->ip4_route.tos = rtm->rtm_tos;
|
obj->ip4_route.tos = rtm->rtm_tos;
|
||||||
else {
|
else {
|
||||||
if (tb[RTA_SRC]) {
|
if (tb[RTA_SRC]) {
|
||||||
_check_addr_or_errout (tb, RTA_SRC, addr_len);
|
_check_addr_or_return_null (tb, RTA_SRC, addr_len);
|
||||||
memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
|
memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len);
|
||||||
}
|
}
|
||||||
obj->ip6_route.src_plen = rtm->rtm_src_len;
|
obj->ip6_route.src_plen = rtm->rtm_src_len;
|
||||||
@@ -2707,10 +2666,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
|
|||||||
obj->ip_route.r_rtm_flags = rtm->rtm_flags;
|
obj->ip_route.r_rtm_flags = rtm->rtm_flags;
|
||||||
obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol);
|
obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol);
|
||||||
|
|
||||||
obj_result = obj;
|
return g_steal_pointer (&obj);
|
||||||
obj = NULL;
|
|
||||||
errout:
|
|
||||||
return obj_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NMPObject *
|
static NMPObject *
|
||||||
@@ -6531,20 +6487,17 @@ _wireguard_get_link_properties (NMPlatform *platform, const NMPlatformLink *link
|
|||||||
.valid_arg = &buf,
|
.valid_arg = &buf,
|
||||||
};
|
};
|
||||||
guint i, j;
|
guint i, j;
|
||||||
|
int wireguard_family_id;
|
||||||
|
|
||||||
if (!obj->_link.wireguard_family_id)
|
wireguard_family_id = genl_ctrl_resolve (priv->genl, "wireguard");
|
||||||
obj->_link.wireguard_family_id = _support_genl_family (priv->genl, "wireguard");
|
if (wireguard_family_id < 0) {
|
||||||
|
|
||||||
if (!obj->_link.wireguard_family_id) {
|
|
||||||
_LOGD ("wireguard: kernel support not available for wireguard link %s", link->name);
|
_LOGD ("wireguard: kernel support not available for wireguard link %s", link->name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = nlmsg_alloc ();
|
msg = nlmsg_alloc ();
|
||||||
if (!msg)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, obj->_link.wireguard_family_id,
|
if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, wireguard_family_id,
|
||||||
0, NLM_F_DUMP, WG_CMD_GET_DEVICE, 1))
|
0, NLM_F_DUMP, WG_CMD_GET_DEVICE, 1))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -6559,6 +6512,7 @@ _wireguard_get_link_properties (NMPlatform *platform, const NMPlatformLink *link
|
|||||||
/* have each peer point to its own chunk of the allowedips buffer */
|
/* have each peer point to its own chunk of the allowedips buffer */
|
||||||
for (i = 0, j = 0; i < buf.peers->len; i++) {
|
for (i = 0, j = 0; i < buf.peers->len; i++) {
|
||||||
NMWireGuardPeer *p = &g_array_index (buf.peers, NMWireGuardPeer, i);
|
NMWireGuardPeer *p = &g_array_index (buf.peers, NMWireGuardPeer, i);
|
||||||
|
|
||||||
p->allowedips = &g_array_index (buf.allowedips, NMWireGuardAllowedIP, j);
|
p->allowedips = &g_array_index (buf.allowedips, NMWireGuardAllowedIP, j);
|
||||||
j += p->allowedips_len;
|
j += p->allowedips_len;
|
||||||
}
|
}
|
||||||
|
@@ -791,7 +791,7 @@ int
|
|||||||
genl_ctrl_resolve (struct nl_sock *sk, const char *name)
|
genl_ctrl_resolve (struct nl_sock *sk, const char *name)
|
||||||
{
|
{
|
||||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||||
int result = -ENOMEM;
|
int nlerr;
|
||||||
gint32 response_data = -1;
|
gint32 response_data = -1;
|
||||||
const struct nl_cb cb = {
|
const struct nl_cb cb = {
|
||||||
.valid_cb = _genl_parse_getfamily,
|
.valid_cb = _genl_parse_getfamily,
|
||||||
@@ -802,31 +802,29 @@ genl_ctrl_resolve (struct nl_sock *sk, const char *name)
|
|||||||
|
|
||||||
if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL,
|
if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL,
|
||||||
0, 0, CTRL_CMD_GETFAMILY, 1))
|
0, 0, CTRL_CMD_GETFAMILY, 1))
|
||||||
goto out;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0)
|
nlerr = nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name);
|
||||||
goto out;
|
if (nlerr < 0)
|
||||||
|
return nlerr;
|
||||||
|
|
||||||
result = nl_send_auto (sk, msg);
|
nlerr = nl_send_auto (sk, msg);
|
||||||
if (result < 0)
|
if (nlerr < 0)
|
||||||
goto out;
|
return nlerr;
|
||||||
|
|
||||||
result = nl_recvmsgs (sk, &cb);
|
nlerr = nl_recvmsgs (sk, &cb);
|
||||||
if (result < 0)
|
if (nlerr < 0)
|
||||||
goto out;
|
return nlerr;
|
||||||
|
|
||||||
/* If search was successful, request may be ACKed after data */
|
/* If search was successful, request may be ACKed after data */
|
||||||
result = nl_wait_for_ack (sk, NULL);
|
nlerr = nl_wait_for_ack (sk, NULL);
|
||||||
if (result < 0)
|
if (nlerr < 0)
|
||||||
goto out;
|
return nlerr;
|
||||||
|
|
||||||
if (response_data > 0)
|
if (response_data < 0)
|
||||||
result = response_data;
|
return -NLE_UNSPEC;
|
||||||
else
|
|
||||||
result = -ENOENT;
|
|
||||||
|
|
||||||
out:
|
return response_data;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@@ -929,7 +929,7 @@ nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass)
|
|||||||
NMWifiUtils *
|
NMWifiUtils *
|
||||||
nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl)
|
nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl)
|
||||||
{
|
{
|
||||||
NMWifiUtilsNl80211 *nl80211;
|
gs_unref_object NMWifiUtilsNl80211 *nl80211 = NULL;
|
||||||
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
nm_auto_nlmsg struct nl_msg *msg = NULL;
|
||||||
struct nl80211_device_info device_info = {};
|
struct nl80211_device_info device_info = {};
|
||||||
char ifname[IFNAMSIZ];
|
char ifname[IFNAMSIZ];
|
||||||
@@ -951,7 +951,7 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl)
|
|||||||
nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211");
|
nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211");
|
||||||
if (nl80211->id < 0) {
|
if (nl80211->id < 0) {
|
||||||
_LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\"");
|
_LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\"");
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nl80211->phy = -1;
|
nl80211->phy = -1;
|
||||||
@@ -963,42 +963,42 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl)
|
|||||||
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): NL80211_CMD_GET_WIPHY request failed",
|
"(%s): NL80211_CMD_GET_WIPHY request failed",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device_info.success) {
|
if (!device_info.success) {
|
||||||
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): NL80211_CMD_GET_WIPHY request indicated failure",
|
"(%s): NL80211_CMD_GET_WIPHY request indicated failure",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device_info.supported) {
|
if (!device_info.supported) {
|
||||||
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGD (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): driver does not fully support nl80211, falling back to WEXT",
|
"(%s): driver does not fully support nl80211, falling back to WEXT",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device_info.can_scan_ssid) {
|
if (!device_info.can_scan_ssid) {
|
||||||
_LOGE (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGE (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): driver does not support SSID scans",
|
"(%s): driver does not support SSID scans",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_info.num_freqs == 0 || device_info.freqs == NULL) {
|
if (device_info.num_freqs == 0 || device_info.freqs == NULL) {
|
||||||
nm_log_err (LOGD_PLATFORM | LOGD_WIFI,
|
nm_log_err (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): driver reports no supported frequencies",
|
"(%s): driver reports no supported frequencies",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_info.caps == 0) {
|
if (device_info.caps == 0) {
|
||||||
_LOGE (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGE (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): driver doesn't report support of any encryption",
|
"(%s): driver doesn't report support of any encryption",
|
||||||
ifname);
|
ifname);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nl80211->phy = device_info.phy;
|
nl80211->phy = device_info.phy;
|
||||||
@@ -1010,9 +1010,5 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl)
|
|||||||
_LOGI (LOGD_PLATFORM | LOGD_WIFI,
|
_LOGI (LOGD_PLATFORM | LOGD_WIFI,
|
||||||
"(%s): using nl80211 for WiFi device control",
|
"(%s): using nl80211 for WiFi device control",
|
||||||
ifname);
|
ifname);
|
||||||
return (NMWifiUtils *) nl80211;
|
return (NMWifiUtils *) g_steal_pointer (&nl80211);
|
||||||
|
|
||||||
error:
|
|
||||||
g_object_unref (nl80211);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user