qcacmn: Add support for peer based rule in iot_sim

Add support for peer based rule in iot_sim for frame
drop and delay operations.

Change-Id: I9d5b330d750aee868cf7ea2932bf8d7ce1d0d54f
CRs-Fixed: 2733909
This commit is contained in:
Jayachandran Sreekumaran
2020-07-14 14:10:59 +05:30
committed by snandini
parent 1d96b191cf
commit acd85ae613
4 changed files with 170 additions and 24 deletions

View File

@@ -86,6 +86,18 @@ QDF_STATUS wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat, QDF_STATUS iot_sim_get_index_for_action_frm(uint8_t *frm, uint8_t *cat,
uint8_t *act, bool rx); uint8_t *act, bool rx);
/**
* iot_sim_find_peer_from_mac - function to find the iot sim peer data
* based on the mac address provided
*
* @isc: iot_sim pdev private object
* @mac: mac address of the peer
* Return: iot_sim_rule_per_peer reference if exists else NULL
*/
struct iot_sim_rule_per_peer *
iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
struct qdf_mac_addr *mac);
/** /**
* iot_sim_frame_update() - Management frame update * iot_sim_frame_update() - Management frame update
* @pdev: reference to global pdev object * @pdev: reference to global pdev object

View File

@@ -131,12 +131,110 @@ struct iot_sim_rule_per_peer *
iot_sim_find_peer_from_mac(struct iot_sim_context *isc, iot_sim_find_peer_from_mac(struct iot_sim_context *isc,
struct qdf_mac_addr *mac) struct qdf_mac_addr *mac)
{ {
struct iot_sim_rule_per_peer *peer_rule = NULL;
qdf_list_node_t *node = NULL, *next_node = NULL;
if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac))
return &isc->bcast_peer; return &isc->bcast_peer;
else else {
if (qdf_list_empty(&isc->peer_list)) {
iot_sim_debug("peer_list empty");
return NULL; return NULL;
} }
qdf_spin_lock_bh(&isc->iot_sim_lock);
if (QDF_STATUS_SUCCESS !=
qdf_list_peek_front(&isc->peer_list, &next_node)) {
qdf_spin_unlock_bh(&isc->iot_sim_lock);
iot_sim_err("Failed to get peer rule from peer_list");
return NULL;
}
do {
node = next_node;
peer_rule =
qdf_container_of(node,
struct iot_sim_rule_per_peer,
node);
if (qdf_is_macaddr_equal(&peer_rule->addr, mac)) {
qdf_spin_unlock_bh(&isc->iot_sim_lock);
return peer_rule;
}
} while (QDF_STATUS_SUCCESS ==
qdf_list_peek_next(&isc->peer_list, node, &next_node));
qdf_spin_unlock_bh(&isc->iot_sim_lock);
iot_sim_err("Failed to find peer");
}
return NULL;
}
/*
* iot_sim_add_peer - function to add the iot sim peer data
*
* @isc: iot_sim pdev private object
* @mac: mac address of the peer
*
* Return: iot_sim_rule_per_peer reference
*/
struct iot_sim_rule_per_peer *
iot_sim_add_peer(struct iot_sim_context *isc, struct qdf_mac_addr *mac)
{
struct iot_sim_rule_per_peer *peer_rule = NULL;
QDF_STATUS status;
if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) {
iot_sim_err("called iot_sim_add_peer for broadcast address");
return &isc->bcast_peer;
}
qdf_spin_lock_bh(&isc->iot_sim_lock);
if (qdf_list_size(&isc->peer_list) < MAX_PEER_COUNT) {
peer_rule = qdf_mem_malloc(sizeof
(struct iot_sim_rule_per_peer));
if (!peer_rule) {
iot_sim_err("Memory alloc failed for peer: "
QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(mac->bytes));
goto rel_lock;
}
qdf_copy_macaddr(&peer_rule->addr, mac);
status = qdf_list_insert_back(&isc->peer_list,
&peer_rule->node);
if (QDF_IS_STATUS_ERROR(status)) {
iot_sim_err("peer_list enqueue failed for peer "
QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(mac->bytes));
qdf_mem_free(peer_rule);
peer_rule = NULL;
}
} else {
iot_sim_err("peer_list already reached max limit");
}
rel_lock:
qdf_spin_unlock_bh(&isc->iot_sim_lock);
return peer_rule;
}
/*
* iot_sim_remove_peer - function to remove the iot sim peer data
*
* @isc: iot_sim pdev private object
* @mac: mac address of the peer
*
* Return: void
*/
void iot_sim_remove_peer(struct iot_sim_context *isc,
struct iot_sim_rule_per_peer *peer_rule)
{
qdf_spin_lock_bh(&isc->iot_sim_lock);
qdf_list_remove_node(&isc->peer_list, &peer_rule->node);
qdf_spin_unlock_bh(&isc->iot_sim_lock);
}
/* /*
* iot_sim_validate_content - function to validate frame content. User provided * iot_sim_validate_content - function to validate frame content. User provided
* content must be either full frame or full frame * content must be either full frame or full frame
@@ -696,6 +794,8 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
struct iot_sim_rule_per_seq **s_e; struct iot_sim_rule_per_seq **s_e;
struct iot_sim_rule **f_e; struct iot_sim_rule **f_e;
struct iot_sim_rule_per_peer *peer; struct iot_sim_rule_per_peer *peer;
bool peer_remove = 1, broadcast_peer = 0;
uint8_t i;
if (qdf_is_macaddr_zero(mac)) if (qdf_is_macaddr_zero(mac))
iot_sim_info("Rule deletion for all peers"); iot_sim_info("Rule deletion for all peers");
@@ -716,12 +816,16 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
if (oper == DROP || oper == DELAY) if (oper == DROP || oper == DELAY)
iot_sim_remap_type_subtype(&type, &subtype, &seq, action); iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
if (qdf_is_macaddr_zero(mac) || qdf_is_macaddr_broadcast(mac)) {
peer = &isc->bcast_peer;
broadcast_peer = 1;
} else
peer = iot_sim_find_peer_from_mac(isc, mac); peer = iot_sim_find_peer_from_mac(isc, mac);
if (peer) { if (peer) {
qdf_spin_lock(&peer->iot_sim_lock); qdf_spin_lock_bh(&isc->iot_sim_lock);
s_e = &peer->rule_per_seq[seq]; s_e = &peer->rule_per_seq[seq];
if (!*s_e) { if (!*s_e) {
qdf_spin_unlock(&peer->iot_sim_lock); qdf_spin_unlock_bh(&isc->iot_sim_lock);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -732,7 +836,15 @@ iot_sim_delete_rule_for_mac(struct iot_sim_context *isc,
if (*f_e) if (*f_e)
status = iot_sim_del_rule(s_e, f_e, oper); status = iot_sim_del_rule(s_e, f_e, oper);
qdf_spin_unlock(&peer->iot_sim_lock);
for (i = 0; i < MAX_SEQ; i++)
if (peer->rule_per_seq[i])
peer_remove = 0;
qdf_spin_unlock_bh(&isc->iot_sim_lock);
if (!broadcast_peer && peer_remove) {
iot_sim_remove_peer(isc, peer);
qdf_mem_free(peer);
}
} }
return status; return status;
@@ -831,15 +943,17 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
iot_sim_remap_type_subtype(&type, &subtype, &seq, action); iot_sim_remap_type_subtype(&type, &subtype, &seq, action);
peer = iot_sim_find_peer_from_mac(isc, mac); peer = iot_sim_find_peer_from_mac(isc, mac);
if (!peer)
peer = iot_sim_add_peer(isc, mac);
if (peer) { if (peer) {
qdf_spin_lock(&peer->iot_sim_lock); qdf_spin_lock_bh(&isc->iot_sim_lock);
s_e = &peer->rule_per_seq[seq]; s_e = &peer->rule_per_seq[seq];
if (!*s_e) { if (!*s_e) {
*s_e = qdf_mem_malloc(sizeof(struct *s_e = qdf_mem_malloc(sizeof(struct
iot_sim_rule_per_seq)); iot_sim_rule_per_seq));
if (!*s_e) { if (!*s_e) {
iot_sim_err("can't allocate s_e"); iot_sim_err("can't allocate s_e");
qdf_spin_unlock(&peer->iot_sim_lock); qdf_spin_unlock_bh(&isc->iot_sim_lock);
return QDF_STATUS_E_NOMEM; return QDF_STATUS_E_NOMEM;
} }
} }
@@ -861,7 +975,7 @@ iot_sim_add_rule_for_mac(struct iot_sim_context *isc,
type, subtype); type, subtype);
status = iot_sim_add_rule(s_e, f_e, oper, frm, offset, len); status = iot_sim_add_rule(s_e, f_e, oper, frm, offset, len);
qdf_spin_unlock(&peer->iot_sim_lock); qdf_spin_unlock_bh(&isc->iot_sim_lock);
} else { } else {
/* TBD: clear the rules for peer with address 'mac'*/ /* TBD: clear the rules for peer with address 'mac'*/
} }
@@ -1089,6 +1203,9 @@ iot_sim_parse_user_input_drop(struct iot_sim_context *isc,
if (argv[5]) if (argv[5])
status = qdf_mac_parse(argv[5], addr); status = qdf_mac_parse(argv[5], addr);
iot_sim_err("drop rule mac address " QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(addr->bytes));
return status; return status;
err: err:
iot_sim_err("kstrtoXX failed: %d", ret); iot_sim_err("kstrtoXX failed: %d", ret);
@@ -1393,8 +1510,8 @@ wlan_iot_sim_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
} }
qdf_set_macaddr_broadcast(&isc->bcast_peer.addr); qdf_set_macaddr_broadcast(&isc->bcast_peer.addr);
qdf_spinlock_create(&isc->bcast_peer.iot_sim_lock); qdf_spinlock_create(&isc->iot_sim_lock);
qdf_list_create(&isc->bcast_peer.list, 0); qdf_list_create(&isc->peer_list, 2);
isc->bcn_buf = NULL; isc->bcn_buf = NULL;
wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP, wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_IOT_SIM_COMP,
@@ -1426,9 +1543,10 @@ wlan_iot_sim_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev,
/* Deinitilise function pointers from iot_sim context */ /* Deinitilise function pointers from iot_sim context */
iot_sim_debugfs_deinit(isc); iot_sim_debugfs_deinit(isc);
iot_sim_remove_all_rules(isc); iot_sim_remove_all_rules(isc);
qdf_list_destroy(&isc->peer_list);
if (isc->bcn_buf) if (isc->bcn_buf)
qdf_nbuf_free(isc->bcn_buf); qdf_nbuf_free(isc->bcn_buf);
qdf_spinlock_destroy(&isc->bcast_peer.iot_sim_lock); qdf_spinlock_destroy(&isc->iot_sim_lock);
qdf_mem_free(isc); qdf_mem_free(isc);
} }
iot_sim_debug("iot_sim component pdev%u object destroyed", iot_sim_debug("iot_sim component pdev%u object destroyed",

View File

@@ -75,6 +75,7 @@
#define N_FRAME_TYPE 0x4 #define N_FRAME_TYPE 0x4
#define N_FRAME_SUBTYPE 0xF #define N_FRAME_SUBTYPE 0xF
#define MAX_SEQ 0x4 #define MAX_SEQ 0x4
#define MAX_PEER_COUNT 0x2
#define MAX_ACTION 0x3 #define MAX_ACTION 0x3
#define IOT_SIM_DEBUGFS_FILE_NUM 3 #define IOT_SIM_DEBUGFS_FILE_NUM 3
#define FRAME_TYPE_IS_BEACON(type, subtype) ((type) == 0 && (subtype) == 8) #define FRAME_TYPE_IS_BEACON(type, subtype) ((type) == 0 && (subtype) == 8)
@@ -136,10 +137,9 @@ struct iot_sim_rule_per_seq {
* @list - list variable * @list - list variable
*/ */
struct iot_sim_rule_per_peer { struct iot_sim_rule_per_peer {
qdf_list_node_t node;
struct qdf_mac_addr addr; struct qdf_mac_addr addr;
qdf_spinlock_t iot_sim_lock;
struct iot_sim_rule_per_seq *rule_per_seq[MAX_SEQ]; struct iot_sim_rule_per_seq *rule_per_seq[MAX_SEQ];
qdf_list_t list;
}; };
/** /**
@@ -152,6 +152,8 @@ struct iot_sim_context {
struct wlan_objmgr_pdev *pdev_obj; struct wlan_objmgr_pdev *pdev_obj;
/* IOT_SIM Peer list & Bcast Peer */ /* IOT_SIM Peer list & Bcast Peer */
struct iot_sim_rule_per_peer *iot_sim_peer_list, bcast_peer; struct iot_sim_rule_per_peer *iot_sim_peer_list, bcast_peer;
qdf_list_t peer_list;
qdf_spinlock_t iot_sim_lock;
struct iot_sim_debugfs iot_sim_dbgfs_ctx; struct iot_sim_debugfs iot_sim_dbgfs_ctx;
void (*iot_sim_update_beacon_trigger)(mlme_pdev_ext_t *); void (*iot_sim_update_beacon_trigger)(mlme_pdev_ext_t *);
qdf_nbuf_t bcn_buf; qdf_nbuf_t bcn_buf;

View File

@@ -250,6 +250,9 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
int auth_seq_index = 0; int auth_seq_index = 0;
struct iot_sim_rule *piot_sim_rule = NULL; struct iot_sim_rule *piot_sim_rule = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct iot_sim_rule_per_peer *peer_rule;
struct ieee80211_frame *wh = (struct ieee80211_frame *)buf;
struct qdf_mac_addr *mac_addr;
isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_IOT_SIM_COMP); isc = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_IOT_SIM_COMP);
if (!isc) { if (!isc) {
@@ -293,20 +296,28 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
type, subtype, seq, is_action_frm, type, subtype, seq, is_action_frm,
tx ? "TX" : "RX"); tx ? "TX" : "RX");
/** if (tx)
* Only broadcast peer is getting handled right now. mac_addr = (struct qdf_mac_addr *)wh->i_addr1;
* Need to add support for peer based content modification else
*/ mac_addr = (struct qdf_mac_addr *)wh->i_addr2;
qdf_spin_lock(&isc->bcast_peer.iot_sim_lock);
if (!isc->bcast_peer.rule_per_seq[seq]) peer_rule = iot_sim_find_peer_from_mac(isc, mac_addr);
if (!peer_rule)
peer_rule = &isc->bcast_peer;
if (!peer_rule)
goto no_peer_rule;
qdf_spin_lock_bh(&isc->iot_sim_lock);
if (!peer_rule->rule_per_seq[seq])
goto norule; goto norule;
if (is_action_frm) if (is_action_frm)
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]-> piot_sim_rule = peer_rule->rule_per_seq[seq]->
rule_per_action_frm[cat][cat_index]; rule_per_action_frm[cat][cat_index];
else else
piot_sim_rule = isc->bcast_peer.rule_per_seq[seq]-> piot_sim_rule = peer_rule->rule_per_seq[seq]->
rule_per_type[type][subtype]; rule_per_type[type][subtype];
if (!piot_sim_rule) if (!piot_sim_rule)
@@ -341,11 +352,14 @@ QDF_STATUS iot_sim_frame_update(struct wlan_objmgr_pdev *pdev, qdf_nbuf_t nbuf,
status = QDF_STATUS_E_NULL_VALUE; status = QDF_STATUS_E_NULL_VALUE;
} }
qdf_spin_unlock(&isc->bcast_peer.iot_sim_lock); qdf_spin_unlock_bh(&isc->iot_sim_lock);
return status; return status;
norule: norule:
iot_sim_debug("Rule not set for this frame"); iot_sim_debug("Rule not set for this frame");
qdf_spin_unlock(&isc->bcast_peer.iot_sim_lock); qdf_spin_unlock_bh(&isc->iot_sim_lock);
return QDF_STATUS_SUCCESS;
no_peer_rule:
iot_sim_debug("Rule not set for this peer");
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }