qcacld-3.0: Fix DHCP indication to FW feature for broadcast exchange

Use "client mac address" in bootp protocol to get
station id to handle scenarion when
DHCP exchanges(discover/offer/request/ack) happens
with broadcast address as destination address.

Change-Id: Ie233b2ffed1533f0a45fded199bb09649e48b4dd
CRs-Fixed: 2506023
This commit is contained in:
Nirav Shah 2019-08-05 22:59:56 +05:30 • committed by nshrivas
commit a7fa192dbd
3 changed files with 36 additions and 47 deletions

View file

@ -244,18 +244,16 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
uint8_t sta_id, uint16_t type);
/**
* hdd_inspect_dhcp_packet() - Inspect DHCP packet
* hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
* @adapter: pointer to hdd adapter
* @sta_id: peer station ID
* @skb: pointer to OS packet (sk_buff)
* @dir: direction
*
* Return: error number
*/
int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
uint8_t sta_id,
struct sk_buff *skb,
enum qdf_proto_dir dir);
int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
struct sk_buff *skb,
enum qdf_proto_dir dir);
#else
static inline
int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
@ -265,14 +263,12 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
}
static inline
int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
uint8_t sta_id,
struct sk_buff *skb,
enum qdf_proto_dir dir)
int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
struct sk_buff *skb,
enum qdf_proto_dir dir)
{
return 0;
}
#endif
#endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */

View file

@ -406,7 +406,6 @@ void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t nbuf, qdf_netdev_t dev)
struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
int result;
unsigned int cpu_index;
uint8_t sta_id;
uint32_t enabled;
if (hdd_validate_adapter(adapter)) {
@ -422,12 +421,7 @@ void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t nbuf, qdf_netdev_t dev)
if ((adapter->device_mode == QDF_SAP_MODE) &&
(qdf_nbuf_is_ipv4_dhcp_pkt(nbuf) == true)) {
/* Send DHCP Indication to FW */
struct qdf_mac_addr *src_mac =
(struct qdf_mac_addr *)(nbuf->data +
QDF_NBUF_SRC_MAC_OFFSET);
if (QDF_STATUS_SUCCESS ==
hdd_softap_get_sta_id(adapter, src_mac, &sta_id))
hdd_inspect_dhcp_packet(adapter, sta_id, nbuf, QDF_RX);
hdd_softap_inspect_dhcp_packet(adapter, nbuf, QDF_RX);
}
qdf_dp_trace_set_track(nbuf, QDF_RX);

View file

@ -280,6 +280,8 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
return 0;
}
#define DHCP_CLIENT_MAC_ADDR_OFFSET 0x46
/**
* hdd_softap_notify_dhcp_ind() - Notify SAP for DHCP indication for tx desc
* @context: pointer to HDD context
@ -303,32 +305,24 @@ static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
return;
}
dest_mac_addr = (struct qdf_mac_addr *)netbuf->data;
dest_mac_addr = (struct qdf_mac_addr *)(netbuf->data +
DHCP_CLIENT_MAC_ADDR_OFFSET);
if (QDF_NBUF_CB_GET_IS_BCAST(netbuf) ||
QDF_NBUF_CB_GET_IS_MCAST(netbuf)) {
/* The BC/MC station ID is assigned during BSS
* starting phase. SAP will return the station ID
* used for BC/MC traffic.
*/
sta_id = hdd_ap_ctx->broadcast_sta_id;
} else {
if (QDF_STATUS_SUCCESS !=
if (QDF_STATUS_SUCCESS !=
hdd_softap_get_sta_id(adapter,
dest_mac_addr, &sta_id)) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
"%s: Failed to find right station", __func__);
return;
}
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
"%s: Failed to find right station", __func__);
return;
}
hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND);
}
/**
* hdd_inspect_dhcp_packet() - Inspect DHCP packet
* hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
* @adapter: pointer to hdd adapter
* @sta_id: peer station ID
* @skb: pointer to OS packet (sk_buff)
* @dir: direction
*
@ -353,19 +347,17 @@ static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
*
* Return: error number
*/
int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
uint8_t sta_id,
struct sk_buff *skb,
enum qdf_proto_dir dir)
int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
struct sk_buff *skb,
enum qdf_proto_dir dir)
{
enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
struct hdd_station_info *hdd_sta_info;
uint8_t sta_id;
int errno = 0;
struct qdf_mac_addr *src_mac;
QDF_STATUS status;
if (sta_id >= WLAN_MAX_STA_COUNT) {
hdd_err("Invalid sta id: %d", sta_id);
return -EINVAL;
}
if (((adapter->device_mode == QDF_SAP_MODE) ||
(adapter->device_mode == QDF_P2P_GO_MODE)) &&
@ -373,6 +365,14 @@ int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
(dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) {
src_mac = (struct qdf_mac_addr *)(skb->data +
DHCP_CLIENT_MAC_ADDR_OFFSET);
status = hdd_softap_get_sta_id(adapter, src_mac, &sta_id);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("invalid station id");
return -EINVAL;
}
subtype = qdf_nbuf_get_dhcp_subtype(skb);
hdd_sta_info = &adapter->sta_info[sta_id];
@ -613,8 +613,7 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb,
QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0;
if (sta_id != ap_ctx->broadcast_sta_id)
hdd_inspect_dhcp_packet(adapter, sta_id, skb, QDF_TX);
hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_TX);
hdd_event_eapol_log(skb, QDF_TX);
QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
@ -951,8 +950,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
adapter->sta_info[sta_id].rx_bytes += skb->len;
adapter->sta_info[sta_id].last_tx_rx_ts =
qdf_system_ticks();
hdd_inspect_dhcp_packet(adapter, sta_id,
skb, QDF_RX);
hdd_softap_inspect_dhcp_packet(adapter, skb,
QDF_RX);
}
}