qcacmn: Introduce API to modify MAC address in action frame

Introduce two APIs which will change the RA, DA and BSSID fields
of 802.11 MAC header.

For any non-public action frame, supplicant will send RA, DA and BSSID
with MLD address which needs to be translated to link addresses to
transmit over the air. wlan_mlo_update_action_frame_from_user() API
will do the address translation from MLD to link.

If any non-public action frame is received over the air that needs
to be sent to userspace, the kernel expects MLD address in RA, DA
and BSSID fields. wlan_mlo_update_action_frame_to_user() API will
do the address translation from link to MLD.

Change-Id: Iab93dd1301003b78edf6d619cfbf552afa53ae7a
CRs-Fixed: 3394706
Tento commit je obsažen v:
Vinod Kumar Pirla
2023-02-01 22:42:05 -08:00
odevzdal Madan Koyyalamudi
rodič c595a4abdf
revize cad19e4fc7
2 změnil soubory, kde provedl 162 přidání a 0 odebrání

Zobrazit soubor

@@ -918,6 +918,42 @@ QDF_STATUS wlan_mlo_check_valid_config(struct wlan_mlo_dev_context *ml_dev,
*/
bool mlo_mgr_ml_peer_exist_on_diff_ml_ctx(uint8_t *peer_addr,
uint8_t *peer_vdev_id);
/**
* wlan_mlo_update_action_frame_from_user() - Change MAC address in WLAN frame
* received from userspace.
* @vdev: VDEV objmgr pointer.
* @frame: Pointer to start of WLAN MAC frame.
* @frame_len: Length of the frame.
*
* The API will translate MLD address in the SA, DA, BSSID for the action
* frames received from userspace with link address to send over the air.
* The API will not modify if the frame is a Public Action category frame and
* for VDEV other then STA mode.
*
* Return: void
*/
void wlan_mlo_update_action_frame_from_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len);
/**
* wlan_mlo_update_action_frame_to_user() - Change MAC address in WLAN frame
* received over the air.
* @vdev: VDEV objmgr pointer.
* @frame: Pointer to start of WLAN MAC frame.
* @frame_len: Length of the frame.
*
* The API will translate link address in the SA, DA, BSSID for the action
* frames received over the air with MLD address to send to userspace.
* The API will not modify if the frame is a Public Action category frame and
* for VDEV other then STA mode.
*
* Return: void
*/
void wlan_mlo_update_action_frame_to_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len);
#else
static inline QDF_STATUS wlan_mlo_mgr_init(void)
{
@@ -943,6 +979,20 @@ bool mlo_mgr_ml_peer_exist_on_diff_ml_ctx(uint8_t *peer_addr,
return false;
}
static inline
void wlan_mlo_update_action_frame_from_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len)
{
}
static inline
void wlan_mlo_update_action_frame_to_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len)
{
}
static inline
uint8_t wlan_mlo_get_sta_mld_ctx_count(void)
{

Zobrazit soubor

@@ -382,6 +382,118 @@ g_ml_ref:
ml_link_lock_release(g_mlo_ctx);
return ret_status;
}
#define WLAN_HDD_MGMT_FRAME_DA_OFFSET 4
#define WLAN_HDD_MGMT_FRAME_SA_OFFSET (WLAN_HDD_MGMT_FRAME_DA_OFFSET + 6)
#define WLAN_HDD_MGMT_FRAME_BSSID_OFFSET (WLAN_HDD_MGMT_FRAME_SA_OFFSET + 6)
#define WLAN_HDD_MGMT_FRAME_ACTION_CATEGORY_OFFSET \
(WLAN_HDD_MGMT_FRAME_BSSID_OFFSET + 6 + 2)
#define WLAN_HDD_MGMT_FRAME_ACTION_TYPE_OFFSET \
(WLAN_HDD_MGMT_FRAME_ACTION_CATEGORY_OFFSET + 1)
#define WLAN_HDD_ACTION_FRAME_CATEGORY_PUBLIC 0x04
/*
* Typical 802.11 Action Frame Format
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* | FC | DUR | DA | SA | BSSID |Seq.|Cat.|Act| Elements | FCS |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* 2 2 6 6 6 2 1 1 Variable Len 4
*/
void wlan_mlo_update_action_frame_from_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len)
{
struct wlan_objmgr_peer *peer;
uint8_t *da, *sa, *bssid;
if (!wlan_vdev_mlme_is_mlo_vdev(vdev) ||
(wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
return;
if (frame_len <= WLAN_HDD_MGMT_FRAME_ACTION_TYPE_OFFSET) {
mlo_debug("Not a valid Action frame len: %d", frame_len);
return;
}
/* Translate address only for action frames
* which are not of public category.
* Reference: 802.11-2012, Subclause: 8.5
*/
if (frame[WLAN_HDD_MGMT_FRAME_ACTION_CATEGORY_OFFSET] ==
WLAN_HDD_ACTION_FRAME_CATEGORY_PUBLIC)
return;
da = frame + WLAN_HDD_MGMT_FRAME_DA_OFFSET;
sa = frame + WLAN_HDD_MGMT_FRAME_SA_OFFSET;
bssid = frame + WLAN_HDD_MGMT_FRAME_BSSID_OFFSET;
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLO_MGR_ID);
if (!peer) {
mlo_debug("Peer not found");
return;
}
mlo_debug("Change MLD addr to link addr for non-Public action frame");
/* DA = VDEV's BSS peer's link address.
* SA = VDEV's link address.
* BSSID = VDEV's BSS peer's link address.
*/
qdf_ether_addr_copy(da, wlan_peer_get_macaddr(peer));
qdf_ether_addr_copy(sa, wlan_vdev_mlme_get_macaddr(vdev));
qdf_ether_addr_copy(bssid, wlan_peer_get_macaddr(peer));
wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID);
}
void wlan_mlo_update_action_frame_to_user(struct wlan_objmgr_vdev *vdev,
uint8_t *frame,
uint32_t frame_len)
{
struct wlan_objmgr_peer *peer;
uint8_t *da, *sa, *bssid;
if (!wlan_vdev_mlme_is_mlo_vdev(vdev) ||
(wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE))
return;
if (frame_len <= WLAN_HDD_MGMT_FRAME_ACTION_TYPE_OFFSET) {
mlo_debug("Not a valid Action frame len: %d", frame_len);
return;
}
/* Translate address only for action frames
* which are not of public category.
* Reference: 802.11-2012, Subclause: 8.5
*/
if (frame[WLAN_HDD_MGMT_FRAME_ACTION_CATEGORY_OFFSET] ==
WLAN_HDD_ACTION_FRAME_CATEGORY_PUBLIC)
return;
da = frame + WLAN_HDD_MGMT_FRAME_DA_OFFSET;
sa = frame + WLAN_HDD_MGMT_FRAME_SA_OFFSET;
bssid = frame + WLAN_HDD_MGMT_FRAME_BSSID_OFFSET;
peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_MLO_MGR_ID);
if (!peer) {
mlo_debug("Peer not found");
return;
}
mlo_debug("Change link addr to MLD addr for non-Public action frame");
/* DA = VDEV's MLD address.
* SA = VDEV's BSS peer's MLD address.
* BSSID = VDEV's BSS peer's MLD address.
*/
qdf_ether_addr_copy(da, wlan_vdev_mlme_get_mldaddr(vdev));
qdf_ether_addr_copy(sa, wlan_peer_mlme_get_mldaddr(peer));
qdf_ether_addr_copy(bssid, wlan_peer_mlme_get_mldaddr(peer));
wlan_objmgr_peer_release_ref(peer, WLAN_MLO_MGR_ID);
}
#endif
static QDF_STATUS mlo_ap_ctx_deinit(struct wlan_mlo_dev_context *ml_dev)