feat: enable monitor packet injection

Build the existing monitor transmit path by default. Validate the radiotap header before parsing it and align the transmit prototype with netdev_tx_t.

Hardware-tested-by: jkroepke (GitHub)
This commit is contained in:
Shen Mintao
2026-08-07 16:15:23 +08:00
parent 531d16c4d6
commit 81b8b3335e
3 changed files with 26 additions and 22 deletions
+1 -1
View File
@@ -154,7 +154,7 @@ CONFIG_RWNX_BCMC ?= y
# Enable Monitor+Data interface support (need FW support) # Enable Monitor+Data interface support (need FW support)
CONFIG_RWNX_MON_DATA =n CONFIG_RWNX_MON_DATA =n
CONFIG_RWNX_MON_XMIT ?= n CONFIG_RWNX_MON_XMIT ?= y
CONFIG_RWNX_MON_RXFILTER ?= n CONFIG_RWNX_MON_RXFILTER ?= n
CONFIG_FILTER_TCP_ACK =y CONFIG_FILTER_TCP_ACK =y
+23 -20
View File
@@ -1991,7 +1991,7 @@ free_use:
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev) netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
int rtap_len, ret, idx, tmp_len; int rtap_len, ret, idx;
struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h struct ieee80211_radiotap_header *rtap_hdr; // net/ieee80211_radiotap.h
struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h struct ieee80211_radiotap_iterator iterator; // net/cfg80211.h
u8_l *rtap_buf = (u8_l *)skb->data; u8_l *rtap_buf = (u8_l *)skb->data;
@@ -2012,10 +2012,30 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
bool offchan = false; bool offchan = false;
int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX;
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
frame_len = skb->len; frame_len = skb->len;
if (unlikely(skb->len < sizeof(*rtap_hdr))) {
AICWFDBG(LOGERROR, "%s radiotap header is truncated\n", __func__);
goto free_tag;
}
rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf);
if (unlikely(rtap_hdr->it_version)) {
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
goto free_tag;
}
rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length
if (unlikely(rtap_len < sizeof(*rtap_hdr))) {
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
goto free_tag;
}
if (unlikely(skb->len < rtap_len)) {
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
goto free_tag;
}
AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len); AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len);
//rwnx_data_dump((char*)__func__, skb->data, skb->len); //rwnx_data_dump((char*)__func__, skb->data, skb->len);
if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) ||
@@ -2023,23 +2043,6 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){
nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC; nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX_FOR_OLD_IC;
} }
if (unlikely(rtap_hdr->it_version)){
AICWFDBG(LOGERROR, "%s itv \r\n", __func__);
goto free_tag;
}
if (unlikely(skb->len < rtap_len)){
AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__);
goto free_tag;
}
if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){
AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__);
goto free_tag;
}
frame_len -= rtap_len; frame_len -= rtap_len;
pframe = rtap_buf + rtap_len; pframe = rtap_buf + rtap_len;
+2 -1
View File
@@ -172,7 +172,8 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
u64 *cookie); u64 *cookie);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
#ifdef CONFIG_RWNX_MON_XMIT #ifdef CONFIG_RWNX_MON_XMIT
int rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb,
struct net_device *dev);
#endif #endif
int rwnx_txdatacfm(void *pthis, void *host_id); int rwnx_txdatacfm(void *pthis, void *host_id);