Skip to content

[noup] l2_packet: Implement a direct function call option #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions src/drivers/driver_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,7 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d
#ifdef CONFIG_WIFI_NM_HOSTAPD_AP
struct zep_drv_if_ctx *if_ctx = priv;
struct hostapd_data *hapd = NULL;
const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
int ret = -1;

/* TODO: Unused for now, but might need for rekeying */
Expand All @@ -2532,14 +2533,27 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d

wpa_printf(MSG_DEBUG, "hostapd: Send EAPOL frame (encrypt=%d)", encrypt);

/* Try to use driver operation for high-priority transmission */
dev_ops = get_dev_ops(if_ctx->dev_ctx);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you add CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT related change inside l2_packet_send, then all the changes before l2_packet_send are not needed, right?

if (dev_ops && dev_ops->send_l2_packet) {
ret = dev_ops->send_l2_packet(if_ctx->dev_priv, addr, ETH_P_EAPOL, data, data_len);
if (ret >= 0) {
return ret;
}
wpa_printf(MSG_DEBUG, "Driver L2 transmission failed, falling back to socket");
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */

/* Fallback to socket-based transmission */
ret = l2_packet_send(hapd->l2, addr, ETH_P_EAPOL, data, data_len);
if (ret < 0) {
wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret);
goto out;
}
#else
struct zep_drv_if_ctx *if_ctx = priv;
const struct zep_wpa_supp_dev_ops *dev_ops;
const struct zep_wpa_supp_dev_ops *dev_ops = NULL;
int ret = -1;
struct wpa_supplicant *wpa_s = NULL;

Expand All @@ -2549,10 +2563,22 @@ int wpa_drv_hapd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t d
(void)encrypt;

wpa_s = if_ctx->supp_if_ctx;
dev_ops = if_ctx->dev_ctx->config;
dev_ops = get_dev_ops(if_ctx->dev_ctx);

wpa_printf(MSG_DEBUG, "wpa_supp: Send EAPOL frame (encrypt=%d)", encrypt);

/* Try to use driver operation for high-priority transmission */
if (dev_ops && dev_ops->send_l2_packet) {
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT
ret = dev_ops->send_l2_packet(if_ctx->dev_priv, addr, ETH_P_EAPOL, data, data_len);
if (ret >= 0) {
return ret;
}
wpa_printf(MSG_DEBUG, "Driver L2 transmission failed, falling back to socket");
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */
}

/* Fallback to socket-based transmission */
ret = l2_packet_send(wpa_s->l2, addr, ETH_P_EAPOL, data, data_len);
if (ret < 0) {
wpa_printf(MSG_ERROR, "%s: l2_packet_send failed: %d", __func__, ret);
Expand Down
9 changes: 9 additions & 0 deletions src/drivers/driver_zephyr.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,15 @@ struct zep_wpa_supp_dev_ops {
int (*cancel_remain_on_channel)(void *priv);
int (*get_inact_sec)(void *if_priv, const u8 *addr);
void (*send_action_cancel_wait)(void *priv);

#ifdef CONFIG_NRF70_L2_PACKET
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#ifdef CONFIG_NRF70_L2_PACKET
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT

/* L2 packet transmission with high priority (VO) */
int (*send_l2_packet)(void *if_priv, const u8 *dst_addr, u16 proto,
const u8 *data, size_t data_len);
#endif
};

/* Function to get driver operations from device */
const struct zep_wpa_supp_dev_ops *get_dev_ops(const struct device *dev);

#endif /* DRIVER_ZEPHYR_H */
66 changes: 57 additions & 9 deletions src/l2_packet/l2_packet_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/device.h>

#include "includes.h"
#include "common.h"
#include "eloop.h"
#include "l2_packet.h"
#include "common/eapol_common.h"
#include "drivers/driver_zephyr.h"

struct l2_packet_data {
char ifname[17];
Expand All @@ -30,6 +32,7 @@ struct l2_packet_data {
* buffers */
int fd;
unsigned short protocol;
void *dev_priv; /* Device private data for driver operations */
};

int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
Expand All @@ -41,35 +44,63 @@ int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr)
int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
const u8 *buf, size_t len)
{
int ret;
int ret = -1;
const struct device *device = NULL;
const struct zep_wpa_supp_dev_ops *dev_ops = NULL;

if (l2 == NULL) {
return -1;
}

/* Get the device from the interface */
device = net_if_get_device(l2->iface);
if (!device) {
wpa_printf(MSG_ERROR, "l2_packet_send: Failed to get device");
return -1;
}

/* Get driver operations */
dev_ops = get_dev_ops(device);
if (!dev_ops) {
wpa_printf(MSG_ERROR, "l2_packet_send: Failed to get driver ops");
return -1;
}

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe protect the entire set of changes (i.e. starting from line 55) with CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT ?

(Same comment for changes in other functions too).

/* Try to use driver operation for high-priority transmission */
if (dev_ops && dev_ops->send_l2_packet) {
ret = dev_ops->send_l2_packet(l2->dev_priv, dst_addr, proto, buf, len);
if (ret >= 0) {
wpa_printf(MSG_DEBUG, "l2_packet_send: Used high-priority driver transmission");
return ret;
}
wpa_printf(MSG_DEBUG, "l2_packet_send: Driver L2 transmission failed, falling back to socket");
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */

/* Fallback to socket-based transmission */
if (l2->l2_hdr) {
ret = send(l2->fd, buf, len, 0);
if (ret < 0) {
wpa_printf(MSG_ERROR, "l2_packet_send - send: %s",
strerror(errno));
wpa_printf(MSG_ERROR, "l2_packet_send: send failed: %d", ret);
}
} else {
struct sockaddr_ll ll;

os_memset(&ll, 0, sizeof(ll));
memset(&ll, 0, sizeof(ll));
ll.sll_family = AF_PACKET;
ll.sll_ifindex = l2->ifindex;
ll.sll_protocol = htons(proto);
ll.sll_ifindex = l2->ifindex;
ll.sll_halen = ETH_ALEN;
os_memcpy(ll.sll_addr, dst_addr, ETH_ALEN);
// TODO: This takes up too much stack, call wifi driver TX directly?
memcpy(ll.sll_addr, dst_addr, ETH_ALEN);

ret = sendto(l2->fd, buf, len, 0, (struct sockaddr *) &ll,
sizeof(ll));
if (ret < 0) {
wpa_printf(MSG_ERROR, "l2_packet_send - sendto: %s",
strerror(errno));
wpa_printf(MSG_ERROR, "l2_packet_send: sendto failed: %d", ret);
}
}

return ret;
}

Expand Down Expand Up @@ -114,6 +145,8 @@ l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol,
int ret = 0;
struct net_linkaddr *link_addr = NULL;
struct net_if *iface;
const struct device *device = NULL;
const struct zep_wpa_supp_dev_ops *dev_ops = NULL;

iface = net_if_get_by_index(net_if_get_by_name(ifname));
if (!iface) {
Expand Down Expand Up @@ -143,6 +176,21 @@ l2_packet_init(const char *ifname, const u8 *own_addr, unsigned short protocol,
link_addr = &iface->if_dev->link_addr;
os_memcpy(l2->own_addr, link_addr->addr, link_addr->len);

/* Get device and driver operations for high-priority transmission */
device = net_if_get_device(l2->iface);
if (device) {
dev_ops = get_dev_ops(device);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT
if (dev_ops && dev_ops->send_l2_packet) {
/* Get device private data from the interface context */
struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = device->data;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use nrf_wifi_vif_ctx_zep struct here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, local change, will fix it. Thanks.

if (vif_ctx_zep) {
l2->dev_priv = vif_ctx_zep;
}
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_L2_PKT_DIRECT */
}

l2->fd = socket(AF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM,
htons(protocol));
if (l2->fd < 0) {
Expand Down