Skip to content

Commit

Permalink
nrf_wifi: Fix filter setting for promiscuous mode
Browse files Browse the repository at this point in the history
The filter setting for promiscuous mode needs to be handled in
the driver. If the packet filtering is handled in the lower layers,
it might affect station connectivity. This commit introduces code to
add minimal filtering mechanism in driver

Addresses [SHEL-2852]

Signed-off-by: Vivekananda Uppunda <[email protected]>
  • Loading branch information
VivekUppunda committed Aug 6, 2024
1 parent 37e2ac2 commit e8f1078
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 12 deletions.
8 changes: 4 additions & 4 deletions nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ struct nrf_wifi_fmac_callbk_fns {
signed short signal);
#endif /* CONFIG_NRF700X_STA_MODE */
#if defined(CONFIG_NRF700X_RAW_DATA_RX) || defined(CONFIG_NRF700X_PROMISC_DATA_RX)
void (*rx_sniffer_frm_callbk_fn)(void *os_vif_ctx,
void *frm,
struct raw_rx_pkt_header *,
bool pkt_free);
void (*sniffer_callbk_fn)(void *os_vif_ctx,
void *frm,
struct raw_rx_pkt_header *,
bool pkt_free);
#endif /* CONFIG_NRF700X_RAW_DATA_RX || CONFIG_NRF700X_PROMISC_DATA_RX */
void (*reg_change_callbk_fn)(void *os_vif_ctx,
struct nrf_wifi_event_regulatory_change *reg_change,
Expand Down
26 changes: 26 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/fmac_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@
#define NRF_WIFI_FMAC_IPV6_TOS_SHIFT 0x04 /* 4bit */
#define NRF_WIFI_FMAC_ETH_TYPE_MASK 0xFFFF

#if defined(CONFIG_NRF700X_PROMISC_DATA_RX)
#define NRF_WIFI_MGMT_PKT_TYPE 0x00
#define NRF_WIFI_DATA_PKT_TYPE 0x10
#define NRF_WIFI_CTRL_PKT_TYPE 0x01

/* Frame Control structure */
struct nrf_wifi_fmac_frame_ctrl{
unsigned short protocolVersion : 2;
unsigned short type : 2;
unsigned short subtype : 4;
unsigned short toDS : 1;
unsigned short fromDS : 1;
unsigned short moreFragments : 1;
unsigned short retry : 1;
unsigned short powerManagement : 1;
unsigned short moreData : 1;
unsigned short protectedFrame : 1;
unsigned short order : 1;
} __NRF_WIFI_PKD;
#endif

struct nrf_wifi_fmac_ieee80211_hdr {
unsigned short fc;
unsigned short dur_id;
Expand Down Expand Up @@ -131,6 +152,11 @@ void nrf_wifi_util_rx_convert_amsdu_to_eth(struct nrf_wifi_fmac_dev_ctx *fmac_de
bool nrf_wifi_util_is_arr_zero(unsigned char *arr,
unsigned int arr_sz);

#if defined(CONFIG_NRF700X_PROMISC_DATA_RX)
bool nrf_wifi_util_check_filt_setting(struct nrf_wifi_fmac_vif_ctx *vif,
unsigned short *frame_control);
#endif

#endif /* !CONFIG_NRF700X_RADIO_TEST */

void *wifi_fmac_priv(struct nrf_wifi_fmac_priv *def);
Expand Down
93 changes: 93 additions & 0 deletions nrf_wifi/fw_if/umac_if/src/fmac_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "fmac_api_common.h"
#include "fmac_util.h"
#include "host_rpu_umac_if.h"
#include "host_rpu_sys_if.h"

bool nrf_wifi_util_is_multicast_addr(const unsigned char *addr)
{
Expand Down Expand Up @@ -366,6 +367,98 @@ enum nrf_wifi_status nrf_wifi_check_mode_validity(unsigned char mode)
return NRF_WIFI_STATUS_FAIL;
}

#if defined(CONFIG_NRF700X_PROMISC_DATA_RX)
bool nrf_wifi_util_check_filt_setting(struct nrf_wifi_fmac_vif_ctx *vif,
unsigned short *frame_control)
{
bool filter_check = false;
struct nrf_wifi_fmac_frame_ctrl *frm_ctrl =
(struct nrf_wifi_fmac_frame_ctrl *)frame_control;

/**
* The different filter settings for 802.11 packets are a bit map
* and the description of the different valid values for the case
* statements are as follows:
* 0x2 - Enable management packets only
* 0x4 - Enable data packets only
* 0x8 - Enable control packets only
* 0x6 - Enable data and management packets
* 0xa - Enable control and management packets
* 0xb - Enable data and control packets
* if bit 0 is set, all packet types are allowed to be sent upstack
**/
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: is 0x%x",
__func__, *frame_control);

nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: packet_filter is %d",
__func__, vif->packet_filter);

switch (vif->packet_filter) {
case 0x2:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_MGMT_PKT_TYPE",
__func__);
if (frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE) {
filter_check = true;
}
break;
case 0x4:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_DATA_PKT_TYPE",
__func__);
if (frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) {
filter_check = true;
}
break;
case 0x6:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_DATA_PKT_TYPE/NRF_WIFI_MGMT_PKT_TYPE",
__func__);
if ((frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) ||
(frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE)) {
filter_check = true;
}
break;
case 0x8:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_CTRL_PKT_TYPE",
__func__);
if (frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE)
filter_check = true;
break;
case 0xa:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_CTRL_PKT_TYPE/NRF_WIFI_MGMT_PKT_TYPE",
__func__);
if ((frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE) ||
(frm_ctrl->type == NRF_WIFI_MGMT_PKT_TYPE)) {
filter_check = true;
}
break;
case 0xb:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: NRF_WIFI_DATA_PKT_TYPE/NRF_WIFI_CTRL_PKT_TYPE",
__func__);
if ((frm_ctrl->type == NRF_WIFI_DATA_PKT_TYPE) ||
(frm_ctrl->type == NRF_WIFI_CTRL_PKT_TYPE)) {
filter_check = true;
}
/* all other packet_filter cases - bit 0 is set and hence all
* packet types are allowed or in the case of 0xE - all packet
* type bits are enabled */
default:
nrf_wifi_osal_log_err(vif->fmac_dev_ctx->fpriv->opriv,
"%s: default",
__func__);
filter_check = true;
break;
}
return filter_check;
}
#endif

#ifdef CONFIG_NRF700X_RAW_DATA_TX
bool nrf_wifi_util_is_rawpktmode_enabled(struct nrf_wifi_fmac_vif_ctx *vif)
{
Expand Down
38 changes: 30 additions & 8 deletions nrf_wifi/fw_if/umac_if/src/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
struct nrf_wifi_fmac_rx_pool_map_info pool_info;
#if defined(CONFIG_NRF700X_RAW_DATA_RX) || defined(CONFIG_NRF700X_PROMISC_DATA_RX)
struct raw_rx_pkt_header raw_rx_hdr;
unsigned short frame_control;
#endif /* CONFIG_NRF700X_RAW_DATA_RX || CONFIG_NRF700X_PROMISC_DATA_RX */
void *nwb = NULL;
void *nwb_data = NULL;
Expand Down Expand Up @@ -311,10 +312,20 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
raw_rx_hdr.rate_flags = config->rate_flags;
raw_rx_hdr.rate = config->rate;

def_priv->callbk_fns.rx_sniffer_frm_callbk_fn(vif_ctx->os_vif_ctx,
nwb,
&raw_rx_hdr,
false);
nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv,
&frame_control,
nwb_data,
sizeof(unsigned short));

nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: frame_control is 0x%x",
__func__, frame_control);
if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control)) {
def_priv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx,
nwb,
&raw_rx_hdr,
false);
}
}
#endif
#ifdef CONFIG_NRF700X_STA_MODE
Expand Down Expand Up @@ -383,10 +394,21 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
raw_rx_hdr.rate_flags = config->rate_flags;
raw_rx_hdr.rate = config->rate;

def_priv->callbk_fns.rx_sniffer_frm_callbk_fn(vif_ctx->os_vif_ctx,
nwb,
&raw_rx_hdr,
true);
#if defined(CONFIG_NRF700X_PROMISC_DATA_RX)
if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control))
#endif
{
def_priv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx,
nwb,
&raw_rx_hdr,
true);
}
#if defined(CONFIG_NRF700X_PROMISC_DATA_RX)
else {
nrf_wifi_osal_nbuf_free(fmac_dev_ctx->fpriv->opriv,
nwb);
}
#endif
}
#endif /* CONFIG_NRF700X_RAW_DATA_RX || CONFIG_NRF700X_PROMISC_DATA_RX */
else {
Expand Down

0 comments on commit e8f1078

Please sign in to comment.