• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*****************************************************************************
17   1 头文件包含
18 *****************************************************************************/
19 #include "frw_util_notifier.h"
20 #include "hmac_feature_interface.h"
21 #include "hmac_ext_if.h"
22 #include "hmac_tx_data.h"
23 #include "oam_struct.h"
24 #include "hmac_11i.h"
25 #include "hmac_frag.h"
26 
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif
31 #endif
32 
33 #undef THIS_FILE_ID
34 #define THIS_FILE_ID DIAG_FILE_ID_WIFI_HOST_HMAC_FRAG_C
35 
36 #undef THIS_MOD_ID
37 #define THIS_MOD_ID DIAG_MOD_ID_WIFI_HOST
38 
39 /*****************************************************************************
40   2 全局变量定义
41 *****************************************************************************/
42 typedef struct {
43     frw_timeout_stru defrag_timer;  /* 去分片超时定时器 */
44     oal_netbuf_stru *defrag_netbuf; /* 去分片重组报文指针 */
45 } hmac_frag_user_info_stru;
46 
47 OAL_STATIC hmac_frag_user_info_stru *g_hmac_defrag_info[WLAN_USER_MAX_USER_LIMIT];
48 
hmac_frag_get_user_info(osal_u16 user_idx)49 OAL_STATIC WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT hmac_frag_user_info_stru *hmac_frag_get_user_info(osal_u16 user_idx)
50 {
51     if (osal_unlikely(user_idx >= WLAN_USER_MAX_USER_LIMIT)) {
52         return OSAL_NULL;
53     }
54     return g_hmac_defrag_info[user_idx];
55 }
56 
hmac_frag_set_user_info(osal_u16 user_idx,osal_void * mem_ptr)57 OAL_STATIC osal_void hmac_frag_set_user_info(osal_u16 user_idx, osal_void *mem_ptr)
58 {
59     g_hmac_defrag_info[user_idx] = (hmac_frag_user_info_stru *)mem_ptr;
60 }
61 /*****************************************************************************
62   3 函数实现
63 *****************************************************************************/
64 #ifdef _PRE_WLAN_FFD
65 osal_u8 g_frame_pn_enable = 0;
66 
hmac_config_frame_pn_enable(hmac_vap_stru * hmac_vap,frw_msg * msg)67 OAL_STATIC osal_s32 hmac_config_frame_pn_enable(hmac_vap_stru *hmac_vap, frw_msg *msg)
68 {
69     osal_s32 ret;
70 
71     if (OAL_UNLIKELY((hmac_vap == OAL_PTR_NULL) || (msg->data == OAL_PTR_NULL))) {
72         return OAL_ERR_CODE_PTR_NULL;
73     }
74     g_frame_pn_enable = *(osal_u8 *)msg->data;
75     oam_info_log1(0, OAM_SF_ANY, "{hmac_config_frame_pn_enable:: g_frame_pn_enable[%d]}", g_frame_pn_enable);
76 
77     /* 抛事件至Device侧DMAC,释放VAP下的发送队列 */
78     ret = frw_send_msg_to_device(hmac_vap->vap_id, WLAN_MSG_H2D_C_CFG_FRAG_PN_ENABLE, msg, OSAL_TRUE);
79     if (ret != OAL_SUCC) {
80         oam_error_log2(0, OAM_SF_ANY, "hmac_config_frame_pn_enable:fail, vap_id[%d] ret[%d]", hmac_vap->vap_id, ret);
81     }
82     return ret;
83 }
84 #endif
85 
86 /* 设置分片门限 */
hmac_config_frag_threshold(hmac_vap_stru * hmac_vap,frw_msg * msg)87 OAL_STATIC osal_s32 hmac_config_frag_threshold(hmac_vap_stru *hmac_vap, frw_msg *msg)
88 {
89     mac_cfg_frag_threshold_stru *frag_threshold = OAL_PTR_NULL;
90     if (OAL_UNLIKELY((hmac_vap == OAL_PTR_NULL) || (msg->data == OAL_PTR_NULL))) {
91         return OAL_ERR_CODE_PTR_NULL;
92     }
93     frag_threshold = (mac_cfg_frag_threshold_stru *)msg->data;
94     if (hmac_vap->mib_info == OAL_PTR_NULL) {
95         oam_error_log2(0, OAM_SF_ANY, "vap_id[%d] {hmac_config_frag_threshold: frag_threshold[%d]!}",
96             hmac_vap->vap_id, frag_threshold->frag_threshold);
97         return OAL_ERR_CODE_PTR_NULL;
98     }
99     mac_mib_set_FragmentationThreshold(hmac_vap, frag_threshold->frag_threshold);
100     return OAL_SUCC;
101 }
102 
103 /* 获取分片门限 */
hmac_config_show_frag_threshold(hmac_vap_stru * hmac_vap,frw_msg * msg)104 OAL_STATIC osal_s32 hmac_config_show_frag_threshold(hmac_vap_stru *hmac_vap, frw_msg *msg)
105 {
106     unref_param(msg);
107     oam_warning_log1(0, OAM_SF_ANY, "FragmentationThreshold:%d.", mac_mib_get_FragmentationThreshold(hmac_vap));
108     return OAL_SUCC;
109 }
110 
111 /* 检查该报文是否需要分片 */
hmac_tx_need_frag(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,const oal_netbuf_stru * netbuf,mac_tx_ctl_stru * tx_ctl)112 osal_u32 hmac_tx_need_frag(hmac_vap_stru *hmac_vap, hmac_user_stru *hmac_user,
113     const oal_netbuf_stru *netbuf, mac_tx_ctl_stru *tx_ctl)
114 {
115     osal_u32        threshold;
116 
117     /* 判断报文是否需要进行分片 */
118     /* 1、长度大于门限          */
119     /* 2、是legac协议模式       */
120     /* 3、不是广播帧            */
121     /* 4、不是聚合帧            */
122     /* 6、DHCP帧不进行分片      */
123 
124     if (mac_get_cb_is_vipframe(tx_ctl)) {
125         return 0;
126     }
127 
128     threshold = mac_mib_get_FragmentationThreshold(hmac_vap);
129     threshold = (threshold & (~(BIT0 | BIT1))) + 2; /* 2:长度 */
130 
131     if (((OAL_NETBUF_LEN(netbuf) + mac_get_cb_frame_header_length(tx_ctl)) > threshold) &&
132         (mac_get_cb_is_mcast(tx_ctl) == OAL_FALSE) &&
133         (mac_get_cb_is_amsdu(tx_ctl) == OAL_FALSE) &&
134 #ifdef _PRE_WLAN_FEATURE_MULTI_NETBUF_AMSDU
135         (mac_get_cb_has_ether_head(tx_ctl) == OAL_FALSE) &&
136 #endif
137         (hmac_user->cur_protocol_mode < WLAN_HT_MODE || hmac_vap->protocol < WLAN_HT_MODE) &&
138         (hmac_tid_ba_is_setup(hmac_user, mac_get_cb_wme_tid_type(tx_ctl)) == OAL_FALSE)) {
139         return threshold;
140     }
141 
142     return 0;
143 }
144 
145 /* 报文分片处理 */
hmac_frag_process(oal_netbuf_stru * netbuf_orig,mac_tx_ctl_stru * tx_ctrl,osal_u32 cip_hdrsize,osal_u32 max_tx_unit)146 osal_u32 hmac_frag_process(oal_netbuf_stru *netbuf_orig, mac_tx_ctl_stru *tx_ctrl,
147     osal_u32 cip_hdrsize, osal_u32 max_tx_unit)
148 {
149     mac_ieee80211_frame_stru *mac_header = mac_get_cb_frame_header_addr(tx_ctrl);
150     mac_ieee80211_frame_stru *frag_header = OAL_PTR_NULL;
151     oal_netbuf_stru          *netbuf = OAL_PTR_NULL;
152     oal_netbuf_stru          *netbuf_prev = OAL_PTR_NULL;
153     osal_u32                frag_num = 1;
154     osal_u32                frag_size;
155     osal_u32                payload;
156     mac_tx_ctl_stru          *tx_ctrl_copy = OAL_PTR_NULL;
157     osal_u32                mac_hdr_size = mac_get_cb_frame_header_length(tx_ctrl);
158     osal_u32                total_hdrsize = mac_hdr_size + cip_hdrsize;
159     osal_u32                offset = max_tx_unit - cip_hdrsize - mac_hdr_size;
160     osal_s32                 remainder = (osal_s32)(OAL_NETBUF_LEN(netbuf_orig) - offset);
161 
162     mac_header->frame_control.more_frag = OAL_TRUE;
163     /* 加密字节数包含在分片门限中,预留加密字节长度,由硬件填写加密头 */
164     netbuf_prev = netbuf_orig;
165 
166     do {
167         frag_size = total_hdrsize + (osal_u32)remainder;
168 
169         /* 判断是否还有更多的分片 */
170         frag_size = (frag_size > max_tx_unit) ? max_tx_unit : frag_size;
171 
172         /* 防止反复扩充头部空间预留32字节 */
173         netbuf = oal_netbuf_alloc_ext(frag_size);
174         if (netbuf == OAL_PTR_NULL) {
175             /* 在外部释放之前申请的报文 */
176             return OAL_ERR_CODE_PTR_NULL;
177         }
178         oal_netbuf_put(netbuf, frag_size);
179         tx_ctrl_copy = (mac_tx_ctl_stru *)OAL_NETBUF_CB(netbuf);
180         /* 拷贝cb字段 */
181         if (memcpy_s(tx_ctrl_copy, MAC_TX_CTL_SIZE, tx_ctrl, MAC_TX_CTL_SIZE) != EOK) {
182             oam_warning_log0(0, OAM_SF_ANY, "{hmac_frag_process::memcpy_s fail.}");
183         }
184         oal_netbuf_copy_queue_mapping(netbuf, netbuf_orig);
185 
186         /* netbuf的headroom大于802.11 mac头长度 */
187         frag_header = (mac_ieee80211_frame_stru *)OAL_NETBUF_PAYLOAD(netbuf);
188         /* 拷贝帧头内容 */
189         if (memcpy_s(frag_header, mac_hdr_size, mac_header, mac_hdr_size) != EOK) {
190             oam_warning_log0(0, OAM_SF_ANY, "{hmac_frag_process::memcpy_s fail.}");
191         }
192         /* 赋值分片号 */
193         frag_header->frag_num = (osal_u16)frag_num++;
194 
195         /* 计算分片报文帧体长度 */
196         payload = frag_size - total_hdrsize;
197         oal_netbuf_pull(netbuf, mac_get_cb_frame_header_length(tx_ctrl_copy));
198         oal_netbuf_copydata(netbuf_orig, offset, OAL_NETBUF_PAYLOAD(netbuf), payload, payload);
199 
200         oal_netbuf_set_len(netbuf, payload);
201         mac_get_cb_frame_header_addr(tx_ctrl_copy) = frag_header;
202         mac_get_cb_mpdu_len(tx_ctrl_copy)      = (osal_u16)payload;
203         OAL_NETBUF_NEXT(netbuf_prev)          = netbuf;
204         netbuf_prev                           = netbuf;
205 
206         /* 计算下一个分片报文的长度和偏移 */
207         remainder    -= (osal_s32)payload;
208         offset       += payload;
209     } while (remainder > 0);
210 
211     frag_header->frame_control.more_frag = OAL_FALSE;
212     OAL_NETBUF_NEXT(netbuf) = OAL_PTR_NULL;
213 
214     /* 原始报文作为分片报文的第一个 */
215     oal_netbuf_trim(netbuf_orig, OAL_NETBUF_LEN(netbuf_orig) - (max_tx_unit - cip_hdrsize - mac_hdr_size));
216     mac_get_cb_mpdu_len(tx_ctrl) = (osal_u16)(OAL_NETBUF_LEN(netbuf_orig));
217     return OAL_SUCC;
218 }
219 
hmac_frag_start(hmac_vap_stru * hmac_vap,hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf,mac_tx_ctl_stru * tx_ctl)220 OAL_STATIC WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT osal_u32 hmac_frag_start(hmac_vap_stru *hmac_vap,
221     hmac_user_stru *hmac_user, oal_netbuf_stru *netbuf, mac_tx_ctl_stru *tx_ctl)
222 {
223     osal_u8 ic_header = 0;
224     osal_u32 threshold;
225     osal_u32 ret = OAL_SUCC;
226 
227     if (osal_unlikely(hmac_user == OAL_PTR_NULL || hmac_vap == OAL_PTR_NULL)) {
228         return ret;
229     }
230 
231     if (osal_unlikely(hmac_vap->mib_info == OAL_PTR_NULL)) {
232         oam_error_log1(0, OAM_SF_ANY, "vap_id[%d] {hmac_frag_start::hmac_vap[%d] mib_info NULL.}", hmac_vap->vap_id);
233         return ret;
234     }
235 
236     /* 非legacy模式不分片 */
237     if (hmac_user->cur_protocol_mode >= WLAN_HT_MODE && hmac_vap->protocol >= WLAN_HT_MODE) {
238         return ret;
239     }
240 
241     threshold = hmac_tx_need_frag(hmac_vap, hmac_user, netbuf, tx_ctl);
242     if (threshold != 0) {
243         ret = hmac_en_mic_etc(hmac_vap, hmac_user, netbuf, &ic_header);
244         if (ret != OAL_SUCC) {
245             return ret;
246         }
247         /* 进行分片处理 */
248         ret = hmac_frag_process(netbuf, tx_ctl, (osal_u32)ic_header, threshold);
249     }
250     return ret;
251 }
252 
253 /* 解分片超时处理 */
hmac_defrag_timeout_fn_etc(osal_void * arg)254 OAL_STATIC osal_u32 hmac_defrag_timeout_fn_etc(osal_void *arg)
255 {
256     hmac_user_stru  *hmac_user = (hmac_user_stru *)arg;
257     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
258     oal_netbuf_stru *netbuf = OAL_PTR_NULL;
259 
260     /* 超时后释放正在重组的分片报文 */
261     if (frag_user_info->defrag_netbuf) {
262         netbuf = frag_user_info->defrag_netbuf;
263         oal_netbuf_free(netbuf);
264         frag_user_info->defrag_netbuf = OAL_PTR_NULL;
265     }
266     return OAL_SUCC;
267 }
268 
hmac_defrag_first_frag(hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf)269 OAL_STATIC oal_netbuf_stru *hmac_defrag_first_frag(hmac_user_stru *hmac_user, oal_netbuf_stru *netbuf)
270 {
271     oal_netbuf_stru  *new_buf = OAL_PTR_NULL;
272     hmac_device_stru *hmac_device = OAL_PTR_NULL;
273     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
274 #ifdef _PRE_WLAN_FFD
275     mac_rx_ctl_stru          *rx_ctl = OSAL_NULL;
276 #endif
277 
278     hmac_device = hmac_res_get_mac_dev_etc((osal_u32)hmac_user->device_id);
279     if (hmac_device == OAL_PTR_NULL) {
280         oam_error_log1(0, OAM_SF_ANY, "{hmac_defrag_first_frag::user index[%d]}", hmac_user->assoc_id);
281         /* user异常,丢弃报文 */
282         OAM_STAT_VAP_INCR(hmac_user->vap_id, rx_defrag_process_dropped, 1);
283         return OAL_PTR_NULL;
284     }
285 
286     /* 启动超时定时器,超时释放重组报文 */
287     frw_create_timer_entry(&frag_user_info->defrag_timer, hmac_defrag_timeout_fn_etc, HMAC_FRAG_TIMEOUT, hmac_user,
288         OAL_FALSE);
289 
290     /* 内存池netbuf只有1600 可能不够,参照A公司申请2500操作系统原生态报文 */
291 #ifdef _PRE_LWIP_ZERO_COPY
292     new_buf = oal_pbuf_netbuf_alloc(HMAC_MAX_FRAG_SIZE);
293 #else
294     new_buf = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, HMAC_MAX_FRAG_SIZE, OAL_NETBUF_PRIORITY_MID);
295 #endif
296     if (new_buf == OAL_PTR_NULL) {
297         /* 内存申请失败异常返回,也需要释放传入的分片报文 */
298         oam_error_log2(0, OAM_SF_ANY, "vap_id[%d] {hmac_defrag_first_frag::Alloc new_buf null,size[%d].}",
299             hmac_user->vap_id, HMAC_MAX_FRAG_SIZE);
300         return OAL_PTR_NULL;
301     }
302 
303 #ifdef _PRE_LWIP_ZERO_COPY
304     skb_reserve(new_buf, PBUF_ZERO_COPY_RESERVE);
305 #endif
306     /* 将分片报文拷贝到新申请的报文中并挂接到用户结构体下,释放原有的报文 */
307     oal_netbuf_init(new_buf, OAL_NETBUF_LEN(netbuf));
308 
309     oal_netbuf_copydata(netbuf, 0, oal_netbuf_data(new_buf), OAL_NETBUF_LEN(netbuf), OAL_NETBUF_LEN(netbuf));
310     (osal_void)memcpy_s(OAL_NETBUF_CB(new_buf), MAC_TX_CTL_SIZE, OAL_NETBUF_CB(netbuf), MAC_TX_CTL_SIZE);
311 #ifdef _PRE_WLAN_FFD
312     rx_ctl = (mac_rx_ctl_stru *)oal_netbuf_cb(new_buf);
313     hmac_user->last_frame_pn = rx_ctl->latency_index;
314 #endif
315     frag_user_info->defrag_netbuf = new_buf; /* 复用latency_index用于上报pn */
316     oal_netbuf_free(netbuf);
317 
318     return frag_user_info->defrag_netbuf;
319 }
320 
hmac_defrag_process(hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf,osal_u32 hrdsize)321 OAL_STATIC oal_netbuf_stru *hmac_defrag_process(hmac_user_stru *hmac_user, oal_netbuf_stru *netbuf, osal_u32 hrdsize)
322 {
323     mac_ieee80211_frame_stru *last_hdr = OAL_PTR_NULL;
324     mac_ieee80211_frame_stru *mac_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(netbuf);
325     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
326 #ifdef _PRE_WLAN_FFD
327     mac_rx_ctl_stru *rx_cb = (mac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
328 #endif
329     /* 判断到来的分片报文是否是第一个分片 */
330     if (frag_user_info->defrag_netbuf == OAL_PTR_NULL) {
331         /* 首片分片的分片号不为0则释放 */
332         if (mac_hdr->frag_num != 0) {
333             OAM_STAT_VAP_INCR(hmac_user->vap_id, rx_defrag_process_dropped, 1);
334             oam_info_log4(0, OAM_SF_ANY,
335                 "vap_id[%d] {hmac_defrag_process::The first frag_num is not Zero(%d), seq_num[%d], more_frag[%d].}",
336                 hmac_user->vap_id, mac_hdr->frag_num, mac_hdr->seq_num, mac_hdr->frame_control.more_frag);
337             return OAL_PTR_NULL;
338         }
339 
340         /* 首片分片处理,成功返回首片分片指针,失败返回NULL */
341         return hmac_defrag_first_frag(hmac_user, netbuf);
342     }
343     /* 此分片是期望的到来的分片,重启定时器,并进行重组 */
344     frw_timer_restart_timer(&frag_user_info->defrag_timer, HMAC_FRAG_TIMEOUT, OAL_FALSE);
345     last_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(frag_user_info->defrag_netbuf);
346 
347     /* 记录最新分片报文的分片号,mac_hdr不可能为空,这是队列中的元素,队列不可能为空 */
348     last_hdr->seq_num   = mac_hdr->seq_num;
349     last_hdr->frag_num  = mac_hdr->frag_num;
350 #ifdef _PRE_WLAN_FFD
351     hmac_user->last_frame_pn = rx_cb->latency_index; /* 复用latency_index用于上报pn */
352 #endif
353     oal_netbuf_pull(netbuf, hrdsize);
354 
355     /* 此接口内会调用dev_kfree_skb */
356     oal_netbuf_concat(frag_user_info->defrag_netbuf, netbuf);
357 
358     return frag_user_info->defrag_netbuf;
359 }
360 
361 /* 去分片处理 */
hmac_defrag_start_etc(hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf,osal_u32 hrdsize)362 oal_netbuf_stru *hmac_defrag_start_etc(hmac_user_stru *hmac_user, oal_netbuf_stru *netbuf, osal_u32 hrdsize)
363 {
364     mac_ieee80211_frame_stru *mac_hdr   = (mac_ieee80211_frame_stru *)oal_netbuf_data(netbuf);
365     mac_ieee80211_frame_stru *last_hdr  = OAL_PTR_NULL;
366     oal_bool_enum_uint8       more_frag = (oal_bool_enum_uint8)mac_hdr->frame_control.more_frag;
367     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
368     oal_netbuf_stru *defrag_netbuf = OAL_PTR_NULL;
369 #ifdef _PRE_WLAN_FFD
370     mac_rx_ctl_stru *rx_cb = (mac_rx_ctl_stru *)oal_netbuf_cb(netbuf);
371 #endif
372     /* 首先检查到来的分片报文是不是属于正在重组的分片报文 */
373     if (frag_user_info->defrag_netbuf != OAL_PTR_NULL) {
374         frw_timer_restart_timer(&frag_user_info->defrag_timer, HMAC_FRAG_TIMEOUT, OAL_FALSE);
375         last_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(frag_user_info->defrag_netbuf);
376         /* 如果地址不匹配,序列号不匹配,分片号不匹配则释放现在正在重组的报文 */
377         if (mac_hdr->seq_num != last_hdr->seq_num || mac_hdr->frag_num != (last_hdr->frag_num + 1) ||
378             (oal_compare_mac_addr(last_hdr->address1, mac_hdr->address1) != 0) ||
379             (oal_compare_mac_addr(last_hdr->address2, mac_hdr->address2) != 0)) {
380             frw_destroy_timer_entry(&frag_user_info->defrag_timer);
381             oal_netbuf_free(frag_user_info->defrag_netbuf);
382             frag_user_info->defrag_netbuf = OAL_PTR_NULL;
383         }
384 #ifdef _PRE_WLAN_FFD
385         if ((frag_user_info->defrag_netbuf != OAL_PTR_NULL) &&
386             (g_frame_pn_enable == OSAL_TRUE) && (rx_cb->latency_index != hmac_user->last_frame_pn + 1)) {
387             frw_destroy_timer_entry(&frag_user_info->defrag_timer);
388             oal_netbuf_free(frag_user_info->defrag_netbuf);
389             frag_user_info->defrag_netbuf = OAL_PTR_NULL;
390         }
391 #endif
392     }
393 
394     /* 开始重组, 重组成功返回重组报文指针,重组失败则返回空,并释放报文 */
395     if (hmac_defrag_process(hmac_user, netbuf, hrdsize) == OAL_PTR_NULL) {
396         oal_netbuf_free(netbuf);
397         return OAL_PTR_NULL;
398     }
399 
400     /* 判断是否重组完毕,是则返回组好的报文 */
401     if (more_frag == 0) {
402         frw_destroy_timer_entry(&frag_user_info->defrag_timer);
403         defrag_netbuf = frag_user_info->defrag_netbuf;
404         frag_user_info->defrag_netbuf = OAL_PTR_NULL;
405 
406         /* 对重组好的报文进行mic检查 */
407         if (hmac_de_mic_etc(hmac_user, defrag_netbuf) != OAL_SUCC) {
408             oal_netbuf_free(defrag_netbuf);
409             return OAL_PTR_NULL;
410         }
411 
412         mac_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(defrag_netbuf);
413         mac_hdr->frag_num = 0;
414         return defrag_netbuf;
415     }
416     /* 判断是否重组完毕,如果存在更多报文待重组则返回空指针 */
417     return OAL_PTR_NULL;
418 }
419 
hmac_defrag_start(hmac_user_stru * hmac_user,oal_netbuf_stru * netbuf,osal_u32 hrdsize)420 OAL_STATIC WIFI_HMAC_TCM_TEXT WIFI_TCM_TEXT oal_netbuf_stru *hmac_defrag_start(hmac_user_stru *hmac_user,
421     oal_netbuf_stru *netbuf, osal_u32 hrdsize)
422 {
423     mac_ieee80211_frame_stru *mac_hdr   = (mac_ieee80211_frame_stru *)oal_netbuf_data(netbuf);
424     osal_u8                   frag_num = (osal_u8)mac_hdr->frag_num;
425     oal_bool_enum_uint8       more_frag = (oal_bool_enum_uint8)mac_hdr->frame_control.more_frag;
426     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
427 
428     if (osal_unlikely(hrdsize == 0)) {
429         oal_netbuf_free(netbuf);
430         return OAL_PTR_NULL;
431     }
432 
433     /* hmac_user已被删除,不做分片重组 */
434     if (osal_unlikely(frag_user_info == OSAL_NULL)) {
435         return netbuf;
436     }
437 
438     /* 如果没有什么可以去分片的则直接返回 */
439     if ((more_frag == OAL_FALSE) && (frag_num == 0) && (frag_user_info->defrag_netbuf == OAL_PTR_NULL)) {
440         return netbuf;
441     }
442 
443     return hmac_defrag_start_etc(hmac_user, netbuf, hrdsize);
444 }
445 
446 /*****************************************************************************
447  清除user下的分片缓存,防止重关联或者rekey流程报文重组attack
448 *****************************************************************************/
hmac_user_clear_defrag_res(hmac_user_stru * hmac_user)449 OAL_STATIC osal_void hmac_user_clear_defrag_res(hmac_user_stru *hmac_user)
450 {
451     hmac_frag_user_info_stru *frag_user_info = OSAL_NULL;
452 
453     if (hmac_user == OSAL_NULL) {
454         oam_error_log0(0, OAM_SF_ANY, "{hmac_user_clear_defrag_res::hmac_user is null ptr.}");
455         return;
456     }
457 
458     frag_user_info = hmac_frag_get_user_info(hmac_user->assoc_id);
459     if (frag_user_info == OSAL_NULL) {
460         return;
461     }
462 
463     if (frag_user_info->defrag_timer.is_registerd == OSAL_TRUE) {
464         frw_destroy_timer_entry(&frag_user_info->defrag_timer);
465     }
466 
467     if (frag_user_info->defrag_netbuf != NULL) {
468         oal_netbuf_free(frag_user_info->defrag_netbuf);
469         frag_user_info->defrag_netbuf = NULL;
470     }
471 }
472 
hmac_frag_del_user(osal_void * notify_data)473 OAL_STATIC osal_bool hmac_frag_del_user(osal_void *notify_data)
474 {
475     hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
476     osal_u16 user_idx = hmac_user->assoc_id;
477     hmac_frag_user_info_stru *frag_user_info = hmac_frag_get_user_info(user_idx);
478     hmac_user_clear_defrag_res(hmac_user);
479 
480     if (frag_user_info != OSAL_NULL) {
481         oal_mem_free(frag_user_info, OAL_TRUE);
482     }
483     hmac_frag_set_user_info(user_idx, OAL_PTR_NULL);
484     return OSAL_TRUE;
485 }
486 
hmac_frag_add_user(osal_void * notify_data)487 OAL_STATIC osal_bool hmac_frag_add_user(osal_void *notify_data)
488 {
489     hmac_user_stru *hmac_user = (hmac_user_stru *)notify_data;
490     osal_void *mem_ptr = OSAL_NULL;
491     osal_u16 user_idx = hmac_user->assoc_id;
492 
493     if (hmac_frag_get_user_info(user_idx) != OSAL_NULL) {
494         oam_warning_log1(0, OAM_SF_CSA, "user_idx[%d] hmac_frag_add_user mem already malloc!", user_idx);
495         return OSAL_TRUE;
496     }
497     mem_ptr = oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(hmac_frag_user_info_stru), OAL_TRUE);
498     if (mem_ptr == OSAL_NULL) {
499         oam_error_log1(0, OAM_SF_CSA, "user_idx[%d] hmac_frag_add_user malloc null!", user_idx);
500         return OSAL_FALSE;
501     }
502     (osal_void)memset_s(mem_ptr, sizeof(hmac_frag_user_info_stru), 0, sizeof(hmac_frag_user_info_stru));
503     hmac_frag_set_user_info(user_idx, mem_ptr);
504     return OSAL_TRUE;
505 }
506 
hmac_frag_init(osal_void)507 osal_u32 hmac_frag_init(osal_void)
508 {
509     /* 消息注册 */
510 #ifdef _PRE_WLAN_FFD
511     frw_msg_hook_register(WLAN_MSG_W2H_CFG_FRAG_PN_ENABLE, hmac_config_frame_pn_enable);
512 #endif
513     frw_msg_hook_register(WLAN_MSG_W2H_CFG_FRAG_THRESHOLD_REG, hmac_config_frag_threshold);
514     frw_msg_hook_register(WLAN_MSG_W2H_CFG_SHOW_FRAG_THRESHOLD_REG, hmac_config_show_frag_threshold);
515     /* notify注册 */
516     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_frag_add_user);
517     frw_util_notifier_register(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_frag_del_user);
518     /* 对外接口注册 */
519     hmac_feature_hook_register(HMAC_FHOOK_FRAG_START, hmac_frag_start);
520     hmac_feature_hook_register(HMAC_FHOOK_FRAG_DERAG_START, hmac_defrag_start);
521     hmac_feature_hook_register(HMAC_FHOOK_FRAG_DERAG_CLEAR, hmac_user_clear_defrag_res);
522 
523     return OAL_SUCC;
524 }
525 
hmac_frag_deinit(osal_void)526 osal_void hmac_frag_deinit(osal_void)
527 {
528 #ifdef _PRE_WLAN_FFD
529     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_FRAG_PN_ENABLE);
530 #endif
531     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_FRAG_THRESHOLD_REG);
532     frw_msg_hook_unregister(WLAN_MSG_W2H_CFG_SHOW_FRAG_THRESHOLD_REG);
533 
534     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_ADD_USER, hmac_frag_add_user);
535     frw_util_notifier_unregister(WLAN_UTIL_NOTIFIER_EVENT_DEL_USER, hmac_frag_del_user);
536 
537     hmac_feature_hook_unregister(HMAC_FHOOK_FRAG_START);
538     hmac_feature_hook_unregister(HMAC_FHOOK_FRAG_DERAG_START);
539     hmac_feature_hook_unregister(HMAC_FHOOK_FRAG_DERAG_CLEAR);
540 }
541 
542 #ifdef __cplusplus
543 #if __cplusplus
544 }
545 #endif
546 #endif
547 
548