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