netdev: add helper to set/unset 4ADDR property

This commit is contained in:
Antonio Quartulli 2018-06-14 10:11:23 +08:00 committed by Denis Kenzior
parent 91456b8d98
commit 9476f78e2d
2 changed files with 90 additions and 0 deletions

View File

@ -106,6 +106,7 @@ struct netdev {
bool rekey_offload_support : 1;
bool in_ft : 1;
bool cur_rssi_low : 1;
bool use_4addr : 1;
};
struct netdev_preauth_state {
@ -3496,6 +3497,83 @@ static void netdev_bridge_port_event(const struct ifinfomsg *ifi, int bytes,
(added ? "added to" : "removed from"), master);
}
struct set_4addr_cb_data {
struct netdev *netdev;
bool value;
netdev_set_4addr_cb_t callback;
void *user_data;
netdev_destroy_func_t destroy;
};
static void netdev_set_4addr_cb(struct l_genl_msg *msg, void *user_data)
{
struct set_4addr_cb_data *cb_data = user_data;
int error = l_genl_msg_get_error(msg);
if (!cb_data)
return;
/* cache the value that has just been set */
if (!error)
cb_data->netdev->use_4addr = cb_data->value;
cb_data->callback(cb_data->netdev, -error, cb_data->user_data);
}
static void netdev_set_4addr_destroy(void *user_data)
{
struct set_4addr_cb_data *cb_data = user_data;
if (!cb_data)
return;
if (cb_data->destroy)
cb_data->destroy(cb_data->user_data);
l_free(cb_data);
}
int netdev_set_4addr(struct netdev *netdev, bool use_4addr,
netdev_set_4addr_cb_t cb, void *user_data,
netdev_destroy_func_t destroy)
{
struct set_4addr_cb_data *cb_data = NULL;
uint8_t attr_4addr = (use_4addr ? 1 : 0);
struct l_genl_msg *msg;
l_debug("netdev: %d use_4addr: %d", netdev->index, use_4addr);
msg = l_genl_msg_new_sized(NL80211_CMD_SET_INTERFACE, 32);
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
l_genl_msg_append_attr(msg, NL80211_ATTR_4ADDR, 1, &attr_4addr);
if (cb) {
cb_data = l_new(struct set_4addr_cb_data, 1);
cb_data->netdev = netdev;
cb_data->value = use_4addr;
cb_data->callback = cb;
cb_data->user_data = user_data;
cb_data->destroy = destroy;
}
if (!l_genl_family_send(nl80211, msg, netdev_set_4addr_cb, cb_data,
netdev_set_4addr_destroy)) {
l_error("CMD_SET_INTERFACE (4addr) failed");
l_genl_msg_unref(msg);
l_free(cb_data);
return -EIO;
}
return 0;
}
bool netdev_get_4addr(struct netdev *netdev)
{
return netdev->use_4addr;
}
static void netdev_newlink_notify(const struct ifinfomsg *ifi, int bytes)
{
struct netdev *netdev;
@ -3583,6 +3661,12 @@ static void netdev_initial_up_cb(struct netdev *netdev, int result,
netdev_linkmode_dormant_cb,
netdev);
/*
* we don't know the initial status of the 4addr property on this
* netdev, therefore we set it to zero by default.
*/
netdev_set_4addr(netdev, netdev->use_4addr, NULL, NULL, NULL);
l_debug("Interface %i initialized", netdev->index);
netdev->device = device_create(netdev->wiphy, netdev);

View File

@ -76,6 +76,8 @@ typedef void (*netdev_watch_func_t)(struct netdev *netdev,
void *user_data);
typedef void (*netdev_set_powered_cb_t)(struct netdev *netdev, int result,
void *user_data);
typedef void (*netdev_set_4addr_cb_t)(struct netdev *netdev, int result,
void *user_data);
typedef void (*netdev_destroy_func_t)(void *user_data);
typedef void (*netdev_eapol_event_func_t)(unsigned int event,
const void *event_data,
@ -96,6 +98,10 @@ const uint8_t *netdev_get_address(struct netdev *netdev);
uint32_t netdev_get_ifindex(struct netdev *netdev);
enum netdev_iftype netdev_get_iftype(struct netdev *netdev);
int netdev_set_iftype(struct netdev *netdev, enum netdev_iftype type);
int netdev_set_4addr(struct netdev *netdev, bool use_4addr,
netdev_set_4addr_cb_t cb, void *user_data,
netdev_destroy_func_t destroy);
bool netdev_get_4addr(struct netdev *netdev);
const char *netdev_get_name(struct netdev *netdev);
bool netdev_get_is_up(struct netdev *netdev);
struct handshake_state *netdev_get_handshake(struct netdev *netdev);