platform: merge branch 'th/platform-genl-3'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1294
This commit is contained in:
Thomas Haller 2022-07-19 12:38:19 +02:00
commit 0af516907e
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
14 changed files with 1111 additions and 620 deletions

View file

@ -788,6 +788,64 @@ test_route_type_is_nodev(void)
/*****************************************************************************/
static void
test_nmp_genl_family_type_from_name(void)
{
int n_run;
int i;
for (i = 0; i < (int) _NMP_GENL_FAMILY_TYPE_NUM; i++) {
const char *name = nmp_genl_family_infos[i].name;
g_assert(name);
if (i > 0)
g_assert_cmpint(strcmp(nmp_genl_family_infos[i - 1].name, name), <, 0);
}
g_assert_cmpint(nmp_genl_family_type_from_name("ethtool"), ==, NMP_GENL_FAMILY_TYPE_ETHTOOL);
g_assert_cmpint(nmp_genl_family_type_from_name("mptcp_pm"), ==, NMP_GENL_FAMILY_TYPE_MPTCP_PM);
g_assert_cmpint(nmp_genl_family_type_from_name("nl80211"), ==, NMP_GENL_FAMILY_TYPE_NL80211);
g_assert_cmpint(nmp_genl_family_type_from_name("nl802154"), ==, NMP_GENL_FAMILY_TYPE_NL802154);
g_assert_cmpint(nmp_genl_family_type_from_name("wireguard"),
==,
NMP_GENL_FAMILY_TYPE_WIREGUARD);
g_assert_cmpint(nmp_genl_family_type_from_name(NULL), ==, _NMP_GENL_FAMILY_TYPE_NONE);
g_assert_cmpint(nmp_genl_family_type_from_name("a"), ==, _NMP_GENL_FAMILY_TYPE_NONE);
g_assert_cmpint(nmp_genl_family_type_from_name("wireguara"), ==, _NMP_GENL_FAMILY_TYPE_NONE);
g_assert_cmpint(nmp_genl_family_type_from_name("wireguarb"), ==, _NMP_GENL_FAMILY_TYPE_NONE);
g_assert_cmpint(nmp_genl_family_type_from_name(""), ==, _NMP_GENL_FAMILY_TYPE_NONE);
g_assert_cmpint(nmp_genl_family_type_from_name("z"), ==, _NMP_GENL_FAMILY_TYPE_NONE);
for (n_run = 0; n_run < 20; n_run++) {
for (i = 0; i < (int) _NMP_GENL_FAMILY_TYPE_NUM; i++) {
const char *cname = nmp_genl_family_infos[i].name;
const int ch_idx = nmtst_get_rand_uint() % strlen(cname);
char name[200];
char ch;
gsize l;
l = g_strlcpy(name, cname, sizeof(name));
g_assert_cmpint(l, <, sizeof(name));
if (n_run == 0) {
g_assert_cmpint(nmp_genl_family_type_from_name(cname), ==, i);
g_assert_cmpint(nmp_genl_family_type_from_name(name), ==, i);
}
/* randomly change one character in the name. Such a name becomes invalid.
* There are no two valid names which only differ by one characters. */
do {
ch = nmtst_get_rand_uint() % 256;
} while (cname[ch_idx] == ch);
name[ch_idx] = ch;
g_assert_cmpint(nmp_genl_family_type_from_name(name), ==, _NMP_GENL_FAMILY_TYPE_NONE);
}
}
}
/*****************************************************************************/
NMTST_DEFINE();
int
@ -808,6 +866,8 @@ main(int argc, char **argv)
GINT_TO_POINTER(2),
test_platform_ip_address_pretty_sort_cmp);
g_test_add_func("/general/test_route_type_is_nodev", test_route_type_is_nodev);
g_test_add_func("/nm-platform/test_nmp_genl_family_type_from_name",
test_nmp_genl_family_type_from_name);
return g_test_run();
}

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ struct nl_msg {
struct sockaddr_nl nm_dst;
struct ucred nm_creds;
struct nlmsghdr *nm_nlh;
size_t nm_size;
uint32_t nm_size;
bool nm_creds_has : 1;
};
@ -261,23 +261,26 @@ nlmsg_hdr(struct nl_msg *n)
}
void *
nlmsg_reserve(struct nl_msg *n, size_t len, int pad)
nlmsg_reserve(struct nl_msg *n, uint32_t len, uint32_t pad)
{
char *buf = (char *) n->nm_nlh;
size_t nlmsg_len = n->nm_nlh->nlmsg_len;
size_t tlen;
char *buf = (char *) n->nm_nlh;
uint32_t tlen;
nm_assert(pad >= 0);
nm_assert(n);
nm_assert(pad == 0 || nm_utils_is_power_of_two(pad));
nm_assert(n->nm_nlh->nlmsg_len <= n->nm_size);
if (len > n->nm_size)
if (pad != 0) {
tlen = (len + (pad - 1u)) & ~(pad - 1u);
if (tlen < len)
return NULL;
} else
tlen = len;
if (tlen > n->nm_size - n->nm_nlh->nlmsg_len)
return NULL;
tlen = pad ? ((len + (pad - 1)) & ~(pad - 1)) : len;
if ((tlen + nlmsg_len) > n->nm_size)
return NULL;
buf += nlmsg_len;
buf += n->nm_nlh->nlmsg_len;
n->nm_nlh->nlmsg_len += tlen;
if (tlen > len)
@ -322,6 +325,8 @@ nlmsg_alloc_size(size_t len)
if (len < sizeof(struct nlmsghdr))
len = sizeof(struct nlmsghdr);
else if (len > UINT32_MAX)
g_return_val_if_reached(NULL);
nm = g_slice_new(struct nl_msg);
*nm = (struct nl_msg){
@ -359,7 +364,7 @@ nlmsg_alloc_convert(struct nlmsghdr *hdr)
}
struct nl_msg *
nlmsg_alloc_simple(int nlmsgtype, int flags)
nlmsg_alloc_simple(uint16_t nlmsgtype, uint16_t flags)
{
struct nl_msg *nm;
struct nlmsghdr *new;
@ -384,20 +389,20 @@ nlmsg_free(struct nl_msg *msg)
/*****************************************************************************/
int
nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad)
nlmsg_append(struct nl_msg *n, const void *data, uint32_t len, uint32_t pad)
{
void *tmp;
nm_assert(n);
nm_assert(data);
nm_assert(len > 0);
nm_assert(pad >= 0);
nm_assert(len == 0 || data);
tmp = nlmsg_reserve(n, len, pad);
if (tmp == NULL)
if (!tmp)
return -ENOMEM;
memcpy(tmp, data, len);
if (len > 0)
memcpy(tmp, data, len);
return 0;
}
@ -417,14 +422,17 @@ nlmsg_parse(const struct nlmsghdr *nlh,
}
struct nlmsghdr *
nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags)
nlmsg_put(struct nl_msg *n,
uint32_t pid,
uint32_t seq,
uint16_t type,
uint32_t payload,
uint16_t flags)
{
struct nlmsghdr *nlh;
struct nlmsghdr *nlh = (struct nlmsghdr *) n->nm_nlh;
if (n->nm_nlh->nlmsg_len < NLMSG_HDRLEN)
g_return_val_if_reached(NULL);
nm_assert(nlh->nlmsg_len >= NLMSG_HDRLEN);
nlh = (struct nlmsghdr *) n->nm_nlh;
nlh->nlmsg_type = type;
nlh->nlmsg_flags = flags;
nlh->nlmsg_pid = pid;
@ -565,7 +573,8 @@ nla_nest_start(struct nl_msg *msg, int attrtype)
static int
_nest_end(struct nl_msg *msg, struct nlattr *start, int keep_empty)
{
size_t pad, len;
size_t len;
uint32_t pad;
len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start;
@ -584,14 +593,18 @@ _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) {
void *p;
/*
* Data inside attribute does not end at a alignment boundary.
* Pad accordingly and account 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))
p = nlmsg_reserve(msg, pad, 0);
if (!p)
g_return_val_if_reached(-NME_BUG);
memset(p, 0, pad);
}
return 0;
@ -730,9 +743,9 @@ void *
genlmsg_put(struct nl_msg *msg,
uint32_t port,
uint32_t seq,
int family,
int hdrlen,
int flags,
uint16_t family,
uint32_t hdrlen,
uint16_t flags,
uint8_t cmd,
uint8_t version)
{

View file

@ -60,7 +60,7 @@ struct nl_msg_lite {
const struct sockaddr_nl *nm_dst;
const struct ucred *nm_creds;
const struct nlmsghdr *nm_nlh;
size_t nm_size;
uint32_t nm_size;
};
/*****************************************************************************/
@ -389,13 +389,13 @@ struct nl_msg *nlmsg_alloc_size(size_t max);
struct nl_msg *nlmsg_alloc_convert(struct nlmsghdr *hdr);
struct nl_msg *nlmsg_alloc_simple(int nlmsgtype, int flags);
struct nl_msg *nlmsg_alloc_simple(uint16_t nlmsgtype, uint16_t flags);
void *nlmsg_reserve(struct nl_msg *n, size_t len, int pad);
void *nlmsg_reserve(struct nl_msg *n, uint32_t len, uint32_t pad);
int nlmsg_append(struct nl_msg *n, const void *data, size_t len, int pad);
int nlmsg_append(struct nl_msg *n, const void *data, uint32_t len, uint32_t pad);
#define nlmsg_append_struct(n, data) nlmsg_append(n, (data), sizeof(*(data)), NLMSG_ALIGNTO)
#define nlmsg_append_struct(n, data) (nlmsg_append((n), (data), sizeof(*(data)), NLMSG_ALIGNTO))
void nlmsg_free(struct nl_msg *msg);
@ -502,8 +502,12 @@ int nlmsg_parse(const struct nlmsghdr *nlh,
nlmsg_parse((nlh), (hdrlen), (tb), G_N_ELEMENTS(tb) - 1, (policy)); \
})
struct nlmsghdr *
nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags);
struct nlmsghdr *nlmsg_put(struct nl_msg *n,
uint32_t pid,
uint32_t seq,
uint16_t type,
uint32_t payload,
uint16_t flags);
/*****************************************************************************/
@ -614,9 +618,9 @@ extern const struct nla_policy genl_ctrl_policy[8];
void *genlmsg_put(struct nl_msg *msg,
uint32_t port,
uint32_t seq,
int family,
int hdrlen,
int flags,
uint16_t family,
uint32_t hdrlen,
uint16_t flags,
uint8_t cmd,
uint8_t version);
void *genlmsg_data(const struct genlmsghdr *gnlh);

View file

@ -395,6 +395,76 @@ _nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value)
/*****************************************************************************/
const NMPGenlFamilyInfo nmp_genl_family_infos[_NMP_GENL_FAMILY_TYPE_NUM] = {
[NMP_GENL_FAMILY_TYPE_ETHTOOL] =
{
.name = "ethtool",
},
[NMP_GENL_FAMILY_TYPE_MPTCP_PM] =
{
.name = "mptcp_pm",
},
[NMP_GENL_FAMILY_TYPE_NL80211] =
{
.name = "nl80211",
},
[NMP_GENL_FAMILY_TYPE_NL802154] =
{
.name = "nl802154",
},
[NMP_GENL_FAMILY_TYPE_WIREGUARD] =
{
.name = "wireguard",
},
};
NMPGenlFamilyType
nmp_genl_family_type_from_name(const char *name)
{
int imin, imax, imid;
if (NM_MORE_ASSERT_ONCE(50)) {
int i;
for (i = 0; i < (int) G_N_ELEMENTS(nmp_genl_family_infos); i++) {
nm_assert(nmp_genl_family_infos[i].name);
if (i > 0)
nm_assert(strcmp(nmp_genl_family_infos[i - 1].name, nmp_genl_family_infos[i].name)
< 0);
}
}
if (!name)
goto out;
imin = 0;
imax = G_N_ELEMENTS(nmp_genl_family_infos) - 1;
imid = imax / 2;
while (TRUE) {
int c;
c = strcmp(nmp_genl_family_infos[imid].name, name);
if (c == 0)
return (NMPGenlFamilyType) imid;
if (c < 0)
imin = imid + 1;
else
imax = imid - 1;
if (imin > imax)
break;
imid = (imax + imin) / 2;
}
out:
return _NMP_GENL_FAMILY_TYPE_NONE;
}
/*****************************************************************************/
/**
* nm_platform_process_events:
* @self: platform instance
@ -8975,6 +9045,19 @@ nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatform
/*****************************************************************************/
guint16
nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type)
{
_CHECK_SELF(self, klass, 0);
if (!_NM_INT_NOT_NEGATIVE(family_type) || family_type >= _NMP_GENL_FAMILY_TYPE_NUM)
g_return_val_if_reached(0);
return klass->genl_get_family_id(self, family_type);
}
/*****************************************************************************/
GHashTable *
nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex)
{

View file

@ -1103,6 +1103,25 @@ nm_platform_kernel_support_get(NMPlatformKernelSupportType type)
return nm_platform_kernel_support_get_full(type, TRUE) != NM_OPTION_BOOL_FALSE;
}
typedef enum {
NMP_GENL_FAMILY_TYPE_ETHTOOL,
NMP_GENL_FAMILY_TYPE_MPTCP_PM,
NMP_GENL_FAMILY_TYPE_NL80211,
NMP_GENL_FAMILY_TYPE_NL802154,
NMP_GENL_FAMILY_TYPE_WIREGUARD,
_NMP_GENL_FAMILY_TYPE_NUM,
_NMP_GENL_FAMILY_TYPE_NONE = _NMP_GENL_FAMILY_TYPE_NUM,
} NMPGenlFamilyType;
typedef struct {
const char *name;
} NMPGenlFamilyInfo;
extern const NMPGenlFamilyInfo nmp_genl_family_infos[_NMP_GENL_FAMILY_TYPE_NUM];
NMPGenlFamilyType nmp_genl_family_type_from_name(const char *name);
/*****************************************************************************/
struct _NMPlatformPrivate;
@ -1309,6 +1328,9 @@ typedef struct {
int (*tfilter_add)(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter);
int (*tfilter_delete)(NMPlatform *self, int ifindex, guint32 parent, gboolean log_error);
guint16 (*genl_get_family_id)(NMPlatform *platform, NMPGenlFamilyType family_type);
} NMPlatformClass;
/* NMPlatform signals
@ -2512,4 +2534,8 @@ gboolean nm_platform_ip_address_match(int addr_family,
const NMPlatformIPAddress *addr,
NMPlatformMatchFlags match_flag);
/*****************************************************************************/
guint16 nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type);
#endif /* __NETWORKMANAGER_PLATFORM_H__ */

View file

@ -1149,10 +1149,7 @@ _vt_cmd_obj_hash_update_link(const NMPObject *obj, NMHashState *h)
nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LINK);
nm_platform_link_hash_update(&obj->link, h);
nm_hash_update_vals(h,
obj->_link.netlink.is_in_netlink,
obj->_link.wireguard_family_id,
obj->_link.udev.device);
nm_hash_update_vals(h, obj->_link.netlink.is_in_netlink, obj->_link.udev.device);
if (obj->_link.netlink.lnk)
nmp_object_hash_update(obj->_link.netlink.lnk, h);
}
@ -1232,7 +1229,6 @@ _vt_cmd_obj_cmp_link(const NMPObject *obj1, const NMPObject *obj2)
NM_CMP_RETURN(nm_platform_link_cmp(&obj1->link, &obj2->link));
NM_CMP_DIRECT(obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink);
NM_CMP_RETURN(nmp_object_cmp(obj1->_link.netlink.lnk, obj2->_link.netlink.lnk));
NM_CMP_DIRECT(obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id);
if (obj1->_link.udev.device != obj2->_link.udev.device) {
if (!obj1->_link.udev.device)

View file

@ -238,11 +238,6 @@ typedef struct {
/* Auxiliary data object for Wi-Fi and WPAN */
GObject *ext_data;
/* FIXME: not every NMPObjectLink should pay the price for tracking
* the wireguard family id. This should be tracked via ext_data, which
* would be exactly the right place. */
int wireguard_family_id;
} NMPObjectLink;
typedef struct {

View file

@ -46,9 +46,9 @@ typedef struct {
NMWifiUtils parent;
struct nl_sock *nl_sock;
guint32 *freqs;
int id;
int num_freqs;
int phy;
guint16 genl_family_id;
bool can_wowlan : 1;
} NMWifiUtilsNl80211;
@ -83,12 +83,12 @@ error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
}
static struct nl_msg *
_nl80211_alloc_msg(int id, int ifindex, int phy, guint32 cmd, guint32 flags)
_nl80211_alloc_msg(guint16 genl_family_id, int ifindex, int phy, uint8_t cmd, uint16_t flags)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
msg = nlmsg_alloc();
genlmsg_put(msg, 0, 0, id, 0, flags, cmd, 0);
genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
if (phy != -1)
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, phy);
@ -99,9 +99,9 @@ nla_put_failure:
}
static struct nl_msg *
nl80211_alloc_msg(NMWifiUtilsNl80211 *self, guint32 cmd, guint32 flags)
nl80211_alloc_msg(NMWifiUtilsNl80211 *self, uint8_t cmd, uint16_t flags)
{
return _nl80211_alloc_msg(self->id, self->parent.ifindex, self->phy, cmd, flags);
return _nl80211_alloc_msg(self->genl_family_id, self->parent.ifindex, self->phy, cmd, flags);
}
static int
@ -945,7 +945,7 @@ nm_wifi_utils_nl80211_class_init(NMWifiUtilsNl80211Class *klass)
}
NMWifiUtils *
nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl)
nm_wifi_utils_nl80211_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex)
{
gs_unref_object NMWifiUtilsNl80211 *self = NULL;
nm_auto_nlmsg struct nl_msg *msg = NULL;
@ -954,16 +954,14 @@ nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl)
if (!genl)
return NULL;
if (genl_family_id == 0)
return NULL;
self = g_object_new(NM_TYPE_WIFI_UTILS_NL80211, NULL);
self->parent.ifindex = ifindex;
self->nl_sock = genl;
self->id = genl_ctrl_resolve(self->nl_sock, "nl80211");
if (self->id < 0) {
_LOGD("genl_ctrl_resolve: failed to resolve \"nl80211\"");
return NULL;
}
self->genl_family_id = genl_family_id;
self->phy = -1;

View file

@ -24,6 +24,6 @@
GType nm_wifi_utils_nl80211_get_type(void);
NMWifiUtils *nm_wifi_utils_nl80211_new(int ifindex, struct nl_sock *genl);
NMWifiUtils *nm_wifi_utils_nl80211_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex);
#endif /* __WIFI_UTILS_NL80211_H__ */

View file

@ -32,16 +32,16 @@ nm_wifi_utils_class_init(NMWifiUtilsClass *klass)
{}
NMWifiUtils *
nm_wifi_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan)
nm_wifi_utils_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex, gboolean check_scan)
{
NMWifiUtils *ret;
g_return_val_if_fail(ifindex > 0, NULL);
ret = nm_wifi_utils_nl80211_new(ifindex, genl);
ret = nm_wifi_utils_nl80211_new(genl, genl_family_id, ifindex);
#if HAVE_WEXT
if (ret == NULL)
if (!ret)
ret = nm_wifi_utils_wext_new(ifindex, check_scan);
#endif

View file

@ -27,7 +27,8 @@ GType nm_wifi_utils_get_type(void);
gboolean nm_wifi_utils_is_wifi(int dirfd, const char *ifname);
NMWifiUtils *nm_wifi_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan);
NMWifiUtils *
nm_wifi_utils_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex, gboolean check_scan);
_NMDeviceWifiCapabilities nm_wifi_utils_get_caps(NMWifiUtils *data);

View file

@ -37,9 +37,9 @@
struct NMWpanUtils {
GObject parent;
int ifindex;
struct nl_sock *nl_sock;
int id;
int ifindex;
guint16 genl_family_id;
};
typedef struct {
@ -75,12 +75,12 @@ error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
}
static struct nl_msg *
_nl802154_alloc_msg(int id, int ifindex, guint32 cmd, guint32 flags)
_nl802154_alloc_msg(guint16 genl_family_id, int ifindex, uint8_t cmd, uint16_t flags)
{
nm_auto_nlmsg struct nl_msg *msg = NULL;
msg = nlmsg_alloc();
genlmsg_put(msg, 0, 0, id, 0, flags, cmd, 0);
genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0);
NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, ifindex);
return g_steal_pointer(&msg);
@ -89,9 +89,9 @@ nla_put_failure:
}
static struct nl_msg *
nl802154_alloc_msg(NMWpanUtils *self, guint32 cmd, guint32 flags)
nl802154_alloc_msg(NMWpanUtils *self, uint8_t cmd, uint16_t flags)
{
return _nl802154_alloc_msg(self->id, self->ifindex, cmd, flags);
return _nl802154_alloc_msg(self->genl_family_id, self->ifindex, cmd, flags);
}
static int
@ -264,7 +264,7 @@ nm_wpan_utils_class_init(NMWpanUtilsClass *klass)
{}
NMWpanUtils *
nm_wpan_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan)
nm_wpan_utils_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex, gboolean check_scan)
{
NMWpanUtils *self;
@ -273,16 +273,13 @@ nm_wpan_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan)
if (!genl)
return NULL;
self = g_object_new(NM_TYPE_WPAN_UTILS, NULL);
self->ifindex = ifindex;
self->nl_sock = genl;
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);
if (!genl_family_id)
return NULL;
}
self = g_object_new(NM_TYPE_WPAN_UTILS, NULL);
self->ifindex = ifindex;
self->nl_sock = genl;
self->genl_family_id = genl_family_id;
return self;
}

View file

@ -23,7 +23,8 @@ typedef struct NMWpanUtils NMWpanUtils;
GType nm_wpan_utils_get_type(void);
NMWpanUtils *nm_wpan_utils_new(int ifindex, struct nl_sock *genl, gboolean check_scan);
NMWpanUtils *
nm_wpan_utils_new(struct nl_sock *genl, guint16 genl_family_id, int ifindex, gboolean check_scan);
guint16 nm_wpan_utils_get_pan_id(NMWpanUtils *self);
gboolean nm_wpan_utils_set_pan_id(NMWpanUtils *self, guint16 pan_id);