qcacld-3.0: Send L2UF frame to update bridge forwarding table

Generate a Level 2 update frame and send it to the bridge in SAP
mode when a new station connects.

It will update the forwarding table of all the bridge devices
through source port learning.

Change-Id: Ia804968453c051e4c8322d3735506a912c0d963d
CRs-Fixed: 2997409
This commit is contained in:
Subrat Dash
2021-06-25 22:38:17 +05:30
committed by Madan Koyyalamudi
parent 87304f21e8
commit 19619ce40b
4 changed files with 108 additions and 1 deletions

View File

@@ -4501,4 +4501,16 @@ uint32_t ucfg_mlme_get_user_mcc_quota_percentage(struct wlan_objmgr_psoc *psoc)
{
return wlan_mlme_get_user_mcc_duty_cycle_percentage(psoc);
}
/**
* ucfg_mlme_get_wds_mode() - Get the configured WDS mode
* @psoc: pointer to psoc object
*
* Return: supported wds mode from enum wlan_wds_mode
*/
static inline uint32_t
ucfg_mlme_get_wds_mode(struct wlan_objmgr_psoc *psoc)
{
return wlan_mlme_get_wds_mode(psoc);
}
#endif /* _WLAN_MLME_UCFG_API_H_ */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -324,4 +324,31 @@ int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
*/
void hdd_softap_check_wait_for_tx_eap_pkt(struct hdd_adapter *adapter,
struct qdf_mac_addr *mac_addr);
#ifdef FEATURE_WDS
/**
* hdd_softap_ind_l2_update() - Send L2 update frame to bridge
* @adapter: pointer to adapter context
* @sta_mac: pointer to the MAC address of the station
*
* The layer-2 update frame is an 802.2 type LLC exchange identifier (XID)
* update response frame. This frame is sent using a MAC source address of
* the newly associated station. Upon the reception of this frame,
* all the layer-2 devices update their forwarding tables with the correct
* port to reach the new location of the station according to the ieee802.1d
* bridge table self learning procedure.
*
* Return: QDF_STATUS_E_FAILURE if any errors encountered,
* QDF_STATUS_SUCCESS otherwise
*/
QDF_STATUS hdd_softap_ind_l2_update(struct hdd_adapter *adapter,
struct qdf_mac_addr *sta_mac);
#else
static inline
QDF_STATUS hdd_softap_ind_l2_update(struct hdd_adapter *adapter,
struct qdf_mac_addr *sta_mac)
{
return QDF_STATUS_SUCCESS;
}
#endif
#endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */

View File

@@ -2567,6 +2567,11 @@ QDF_STATUS hdd_hostapd_sap_event_cb(struct sap_event *sap_event,
(const u8 *)&event->
staMac.bytes[0],
sta_info, GFP_KERNEL);
if (adapter->device_mode == QDF_SAP_MODE &&
ucfg_mlme_get_wds_mode(hdd_ctx->psoc))
hdd_softap_ind_l2_update(adapter,
&event->staMac);
qdf_mem_free(sta_info);
}
/* Lets abort scan to ensure smooth authentication for client */

View File

@@ -51,11 +51,28 @@
#include <wlan_hdd_sar_limits.h>
#include "wlan_hdd_tsf.h"
#include "wlan_hdd_wds.h"
#include <cdp_txrx_ctrl.h>
#ifdef FEATURE_WDS
#include <net/llc_pdu.h>
#endif
/* Preprocessor definitions and constants */
#undef QCA_HDD_SAP_DUMP_SK_BUFF
/* Type declarations */
#ifdef FEATURE_WDS
/**
* Layer-2 update frame format
* @eh: ethernet header
* @l2_update_pdu: llc pdu format
* @l2_update_xid_info: xid command information field
*/
struct l2_update_frame {
struct ethhdr eh;
struct llc_pdu_un l2_update_pdu;
struct llc_xid_info l2_update_xid_info;
} qdf_packed;
#endif
/* Function definitions and documenation */
#ifdef QCA_HDD_SAP_DUMP_SK_BUFF
@@ -1649,3 +1666,49 @@ QDF_STATUS hdd_softap_change_sta_state(struct hdd_adapter *adapter,
return status;
}
#ifdef FEATURE_WDS
QDF_STATUS hdd_softap_ind_l2_update(struct hdd_adapter *adapter,
struct qdf_mac_addr *sta_mac)
{
qdf_nbuf_t nbuf;
struct l2_update_frame *msg;
nbuf = qdf_nbuf_alloc(NULL, sizeof(*msg), 0, 4, false);
if (!nbuf)
return QDF_STATUS_E_FAILURE;
msg = (struct l2_update_frame *)qdf_nbuf_data(nbuf);
/* 802.2 LLC XID update frame carried over 802.3 */
ether_addr_copy(msg->eh.h_source, sta_mac->bytes);
eth_broadcast_addr(msg->eh.h_dest);
/* packet length - dummy 802.3 packet */
msg->eh.h_proto = htons(sizeof(*msg) - sizeof(struct ethhdr));
/* null DSAP and a null SSAP is a way to solicit a response from any
* station (i.e., any DA)
*/
msg->l2_update_pdu.dsap = LLC_NULL_SAP;
msg->l2_update_pdu.ssap = LLC_NULL_SAP;
/*
* unsolicited XID response frame to announce presence.
* lsb.11110101.
*/
msg->l2_update_pdu.ctrl_1 = LLC_PDU_TYPE_U | LLC_1_PDU_CMD_XID;
/* XID information field 129.1.0 to indicate connectionless service */
msg->l2_update_xid_info.fmt_id = LLC_XID_FMT_ID;
msg->l2_update_xid_info.type = LLC_XID_NULL_CLASS_1;
msg->l2_update_xid_info.rw = 0;
qdf_nbuf_set_pktlen(nbuf, sizeof(*msg));
nbuf->dev = adapter->dev;
nbuf->protocol = eth_type_trans(nbuf, adapter->dev);
qdf_net_buf_debug_release_skb(nbuf);
netif_rx_ni(nbuf);
return QDF_STATUS_SUCCESS;
}
#endif