qcacmn: Add WDS Vendor Extension ECM Framework
Add WDS tx/rx policy checks in Tx and Rx datapaths. In Rx path, check packets against rx policy configured In Tx Reinject path, checks are to process or drop 4-addr/3-addr packets to peers decisively Change-Id: I0a6c01b7555fa5d369ab2c9baf454d49808857fc
This commit is contained in:

committed by
snandini

parent
9dee72a40c
commit
2a5fc625d2
@@ -571,6 +571,9 @@ struct cdp_wds_ops {
|
|||||||
void
|
void
|
||||||
(*txrx_set_wds_rx_policy)(struct cdp_vdev *vdev,
|
(*txrx_set_wds_rx_policy)(struct cdp_vdev *vdev,
|
||||||
u_int32_t val);
|
u_int32_t val);
|
||||||
|
void
|
||||||
|
(*txrx_wds_peer_tx_policy_update)(struct cdp_peer *peer,
|
||||||
|
int wds_tx_ucast, int wds_tx_mcast);
|
||||||
int (*vdev_set_wds)(void *vdev, uint32_t val);
|
int (*vdev_set_wds)(void *vdev, uint32_t val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -58,6 +58,33 @@ cdp_set_wds_rx_policy(ol_txrx_soc_handle soc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief set the wds rx filter policy of the device
|
||||||
|
* @details
|
||||||
|
* This flag sets the wds rx policy on the vdev. Rx frames not compliant
|
||||||
|
* with the policy will be dropped.
|
||||||
|
*
|
||||||
|
* @param vdev - the data virtual device object
|
||||||
|
* @param val - the wds rx policy bitmask
|
||||||
|
* @return - void
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
cdp_set_wds_tx_policy_update(ol_txrx_soc_handle soc,
|
||||||
|
struct cdp_peer *peer,
|
||||||
|
int wds_tx_ucast, int wds_tx_mcast)
|
||||||
|
{
|
||||||
|
if (!soc || !soc->ops || !soc->ops->wds_ops) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||||
|
"%s invalid instance", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (soc->ops->wds_ops->txrx_wds_peer_tx_policy_update)
|
||||||
|
return soc->ops->wds_ops->txrx_wds_peer_tx_policy_update(
|
||||||
|
peer, wds_tx_ucast, wds_tx_mcast);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cdp_vdev_set_wds() - Set/unset wds_enable flag in vdev
|
* cdp_vdev_set_wds() - Set/unset wds_enable flag in vdev
|
||||||
* @soc - data path soc handle
|
* @soc - data path soc handle
|
||||||
|
@@ -5328,8 +5328,81 @@ QDF_STATUS dp_update_config_parameters(struct cdp_soc *psoc,
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_txrx_set_wds_rx_policy() - API to store datapath
|
||||||
|
* config parameters
|
||||||
|
* @vdev_handle - datapath vdev handle
|
||||||
|
* @cfg: ini parameter handle
|
||||||
|
*
|
||||||
|
* Return: status
|
||||||
|
*/
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
void
|
||||||
|
dp_txrx_set_wds_rx_policy(
|
||||||
|
struct cdp_vdev *vdev_handle,
|
||||||
|
u_int32_t val)
|
||||||
|
{
|
||||||
|
struct dp_vdev *vdev = (struct dp_vdev *)vdev_handle;
|
||||||
|
struct dp_peer *peer;
|
||||||
|
if (vdev->opmode == wlan_op_mode_ap) {
|
||||||
|
/* for ap, set it on bss_peer */
|
||||||
|
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
||||||
|
if (peer->bss_peer) {
|
||||||
|
peer->wds_ecm.wds_rx_filter = 1;
|
||||||
|
peer->wds_ecm.wds_rx_ucast_4addr = (val & WDS_POLICY_RX_UCAST_4ADDR) ? 1:0;
|
||||||
|
peer->wds_ecm.wds_rx_mcast_4addr = (val & WDS_POLICY_RX_MCAST_4ADDR) ? 1:0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (vdev->opmode == wlan_op_mode_sta) {
|
||||||
|
peer = TAILQ_FIRST(&vdev->peer_list);
|
||||||
|
peer->wds_ecm.wds_rx_filter = 1;
|
||||||
|
peer->wds_ecm.wds_rx_ucast_4addr = (val & WDS_POLICY_RX_UCAST_4ADDR) ? 1:0;
|
||||||
|
peer->wds_ecm.wds_rx_mcast_4addr = (val & WDS_POLICY_RX_MCAST_4ADDR) ? 1:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_txrx_peer_wds_tx_policy_update() - API to set tx wds policy
|
||||||
|
*
|
||||||
|
* @peer_handle - datapath peer handle
|
||||||
|
* @wds_tx_ucast: policy for unicast transmission
|
||||||
|
* @wds_tx_mcast: policy for multicast transmission
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dp_txrx_peer_wds_tx_policy_update(struct cdp_peer *peer_handle,
|
||||||
|
int wds_tx_ucast, int wds_tx_mcast)
|
||||||
|
{
|
||||||
|
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||||
|
if (wds_tx_ucast || wds_tx_mcast) {
|
||||||
|
peer->wds_enabled = 1;
|
||||||
|
peer->wds_ecm.wds_tx_ucast_4addr = wds_tx_ucast;
|
||||||
|
peer->wds_ecm.wds_tx_mcast_4addr = wds_tx_mcast;
|
||||||
|
} else {
|
||||||
|
peer->wds_enabled = 0;
|
||||||
|
peer->wds_ecm.wds_tx_ucast_4addr = 0;
|
||||||
|
peer->wds_ecm.wds_tx_mcast_4addr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||||
|
FL("Policy Update set to :\
|
||||||
|
peer->wds_enabled %d\
|
||||||
|
peer->wds_ecm.wds_tx_ucast_4addr %d\
|
||||||
|
peer->wds_ecm.wds_tx_mcast_4addr %d\n"),
|
||||||
|
peer->wds_enabled, peer->wds_ecm.wds_tx_ucast_4addr,
|
||||||
|
peer->wds_ecm.wds_tx_mcast_4addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct cdp_wds_ops dp_ops_wds = {
|
static struct cdp_wds_ops dp_ops_wds = {
|
||||||
.vdev_set_wds = dp_vdev_set_wds,
|
.vdev_set_wds = dp_vdev_set_wds,
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
.txrx_set_wds_rx_policy = dp_txrx_set_wds_rx_policy,
|
||||||
|
.txrx_wds_peer_tx_policy_update = dp_txrx_peer_wds_tx_policy_update,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -817,7 +817,7 @@ static inline void dp_rx_adjust_nbuf_len(qdf_nbuf_t nbuf, uint16_t *mpdu_len)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
|
void dp_rx_sg_create(qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
|
||||||
uint16_t *mpdu_len, bool *is_first_frag,
|
uint16_t *mpdu_len, bool *is_first_frag,
|
||||||
uint16_t *frag_list_len, qdf_nbuf_t *head_frag_nbuf,
|
uint16_t *frag_list_len, qdf_nbuf_t *head_frag_nbuf,
|
||||||
qdf_nbuf_t *frag_list_head, qdf_nbuf_t *frag_list_tail)
|
qdf_nbuf_t *frag_list_head, qdf_nbuf_t *frag_list_tail)
|
||||||
{
|
{
|
||||||
@@ -888,6 +888,98 @@ static inline void dp_rx_deliver_to_stack(struct dp_vdev *vdev,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
int dp_wds_rx_policy_check(
|
||||||
|
uint8_t *rx_tlv_hdr,
|
||||||
|
struct dp_vdev *vdev,
|
||||||
|
struct dp_peer *peer,
|
||||||
|
int rx_mcast
|
||||||
|
)
|
||||||
|
{
|
||||||
|
struct dp_peer *bss_peer;
|
||||||
|
int fr_ds, to_ds, rx_3addr, rx_4addr;
|
||||||
|
int rx_policy_ucast, rx_policy_mcast;
|
||||||
|
|
||||||
|
if (vdev->opmode == wlan_op_mode_ap) {
|
||||||
|
TAILQ_FOREACH(bss_peer, &vdev->peer_list, peer_list_elem) {
|
||||||
|
if (bss_peer->bss_peer) {
|
||||||
|
/* if wds policy check is not enabled on this vdev, accept all frames */
|
||||||
|
if (!bss_peer->wds_ecm.wds_rx_filter) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rx_policy_ucast = bss_peer->wds_ecm.wds_rx_ucast_4addr;
|
||||||
|
rx_policy_mcast = bss_peer->wds_ecm.wds_rx_mcast_4addr;
|
||||||
|
} else { /* sta mode */
|
||||||
|
if (!peer->wds_ecm.wds_rx_filter) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
rx_policy_ucast = peer->wds_ecm.wds_rx_ucast_4addr;
|
||||||
|
rx_policy_mcast = peer->wds_ecm.wds_rx_mcast_4addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------
|
||||||
|
* self
|
||||||
|
* peer- rx rx-
|
||||||
|
* wds ucast mcast dir policy accept note
|
||||||
|
* ------------------------------------------------
|
||||||
|
* 1 1 0 11 x1 1 AP configured to accept ds-to-ds Rx ucast from wds peers, constraint met; so, accept
|
||||||
|
* 1 1 0 01 x1 0 AP configured to accept ds-to-ds Rx ucast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 1 0 10 x1 0 AP configured to accept ds-to-ds Rx ucast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 1 0 00 x1 0 bad frame, won't see it
|
||||||
|
* 1 0 1 11 1x 1 AP configured to accept ds-to-ds Rx mcast from wds peers, constraint met; so, accept
|
||||||
|
* 1 0 1 01 1x 0 AP configured to accept ds-to-ds Rx mcast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 0 1 10 1x 0 AP configured to accept ds-to-ds Rx mcast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 0 1 00 1x 0 bad frame, won't see it
|
||||||
|
* 1 1 0 11 x0 0 AP configured to accept from-ds Rx ucast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 1 0 01 x0 0 AP configured to accept from-ds Rx ucast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 1 0 10 x0 1 AP configured to accept from-ds Rx ucast from wds peers, constraint met; so, accept
|
||||||
|
* 1 1 0 00 x0 0 bad frame, won't see it
|
||||||
|
* 1 0 1 11 0x 0 AP configured to accept from-ds Rx mcast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 0 1 01 0x 0 AP configured to accept from-ds Rx mcast from wds peers, constraint not met; so, drop
|
||||||
|
* 1 0 1 10 0x 1 AP configured to accept from-ds Rx mcast from wds peers, constraint met; so, accept
|
||||||
|
* 1 0 1 00 0x 0 bad frame, won't see it
|
||||||
|
*
|
||||||
|
* 0 x x 11 xx 0 we only accept td-ds Rx frames from non-wds peers in mode.
|
||||||
|
* 0 x x 01 xx 1
|
||||||
|
* 0 x x 10 xx 0
|
||||||
|
* 0 x x 00 xx 0 bad frame, won't see it
|
||||||
|
* ------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
fr_ds = hal_rx_mpdu_get_fr_ds(rx_tlv_hdr);
|
||||||
|
to_ds = hal_rx_mpdu_get_to_ds(rx_tlv_hdr);
|
||||||
|
rx_3addr = fr_ds ^ to_ds;
|
||||||
|
rx_4addr = fr_ds & to_ds;
|
||||||
|
|
||||||
|
if (vdev->opmode == wlan_op_mode_ap) {
|
||||||
|
if ((!peer->wds_enabled && rx_3addr && to_ds) ||
|
||||||
|
(peer->wds_enabled && !rx_mcast && (rx_4addr == rx_policy_ucast)) ||
|
||||||
|
(peer->wds_enabled && rx_mcast && (rx_4addr == rx_policy_mcast))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else { /* sta mode */
|
||||||
|
if ((!rx_mcast && (rx_4addr == rx_policy_ucast)) ||
|
||||||
|
(rx_mcast && (rx_4addr == rx_policy_mcast))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int dp_wds_rx_policy_check(
|
||||||
|
uint8_t *rx_tlv_hdr,
|
||||||
|
struct dp_vdev *vdev,
|
||||||
|
struct dp_peer *peer,
|
||||||
|
int rx_mcast
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_rx_process() - Brain of the Rx processing functionality
|
* dp_rx_process() - Brain of the Rx processing functionality
|
||||||
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
|
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
|
||||||
@@ -1182,6 +1274,18 @@ done:
|
|||||||
*/
|
*/
|
||||||
dp_rx_peer_validity_check(peer);
|
dp_rx_peer_validity_check(peer);
|
||||||
|
|
||||||
|
if (!dp_wds_rx_policy_check(rx_tlv_hdr, vdev, peer,
|
||||||
|
hal_rx_msdu_end_da_is_mcbc_get(rx_tlv_hdr))) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
|
FL("Policy Check Drop pkt"));
|
||||||
|
/* Drop & free packet */
|
||||||
|
qdf_nbuf_free(nbuf);
|
||||||
|
/* Statistics */
|
||||||
|
nbuf = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (qdf_unlikely(peer && peer->bss_peer)) {
|
if (qdf_unlikely(peer && peer->bss_peer)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
|
@@ -659,4 +659,7 @@ void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||||
uint8_t *rx_tlv_hdr);
|
uint8_t *rx_tlv_hdr);
|
||||||
|
|
||||||
|
int dp_wds_rx_policy_check(uint8_t *rx_tlv_hdr, struct dp_vdev *vdev,
|
||||||
|
struct dp_peer *peer, int rx_mcast);
|
||||||
|
|
||||||
#endif /* _DP_RX_H */
|
#endif /* _DP_RX_H */
|
||||||
|
@@ -494,6 +494,16 @@ skip_mec_check:
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dp_wds_rx_policy_check(rx_desc->rx_buf_start, vdev, peer,
|
||||||
|
hal_rx_msdu_end_da_is_mcbc_get(rx_desc->rx_buf_start))) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
|
FL("mcast Policy Check Drop pkt"));
|
||||||
|
/* Drop & free packet */
|
||||||
|
qdf_nbuf_free(nbuf);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* WDS Source Port Learning */
|
/* WDS Source Port Learning */
|
||||||
if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))
|
if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet))
|
||||||
dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf);
|
dp_rx_wds_srcport_learn(soc, rx_desc->rx_buf_start, peer, nbuf);
|
||||||
|
@@ -1746,6 +1746,12 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
|||||||
struct dp_ast_entry *ast_entry = NULL;
|
struct dp_ast_entry *ast_entry = NULL;
|
||||||
struct dp_soc *soc = NULL;
|
struct dp_soc *soc = NULL;
|
||||||
struct ether_header *eh = (struct ether_header *)qdf_nbuf_data(nbuf);
|
struct ether_header *eh = (struct ether_header *)qdf_nbuf_data(nbuf);
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
int is_mcast = 0, is_ucast = 0;
|
||||||
|
int num_peers_3addr = 0;
|
||||||
|
struct ether_header *eth_hdr = (struct ether_header *)(qdf_nbuf_data(nbuf));
|
||||||
|
struct ieee80211_frame_addr4 *wh = (struct ieee80211_frame_addr4 *)(qdf_nbuf_data(nbuf));
|
||||||
|
#endif
|
||||||
|
|
||||||
vdev = tx_desc->vdev;
|
vdev = tx_desc->vdev;
|
||||||
soc = vdev->pdev->soc;
|
soc = vdev->pdev->soc;
|
||||||
@@ -1762,7 +1768,6 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
|||||||
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
|
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
|
||||||
qdf_nbuf_len(tx_desc->nbuf));
|
qdf_nbuf_len(tx_desc->nbuf));
|
||||||
|
|
||||||
|
|
||||||
qdf_spin_lock_bh(&(soc->ast_lock));
|
qdf_spin_lock_bh(&(soc->ast_lock));
|
||||||
|
|
||||||
ast_entry = dp_peer_ast_hash_find(soc, (uint8_t *)(eh->ether_shost), 0);
|
ast_entry = dp_peer_ast_hash_find(soc, (uint8_t *)(eh->ether_shost), 0);
|
||||||
@@ -1771,16 +1776,53 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
|
|||||||
|
|
||||||
qdf_spin_unlock_bh(&(soc->ast_lock));
|
qdf_spin_unlock_bh(&(soc->ast_lock));
|
||||||
|
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
if (qdf_unlikely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) {
|
||||||
|
is_mcast = (IS_MULTICAST(wh->i_addr1)) ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
is_mcast = (IS_MULTICAST(eth_hdr->ether_dhost)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
is_ucast = !is_mcast;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
||||||
|
if (peer->bss_peer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Detect wds peers that use 3-addr framing for mcast.
|
||||||
|
* if there are any, the bss_peer is used to send the
|
||||||
|
* the mcast frame using 3-addr format. all wds enabled
|
||||||
|
* peers that use 4-addr framing for mcast frames will
|
||||||
|
* be duplicated and sent as 4-addr frames below.
|
||||||
|
*/
|
||||||
|
if (!peer->wds_enabled || !peer->wds_ecm.wds_tx_mcast_4addr) {
|
||||||
|
num_peers_3addr = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (qdf_unlikely(vdev->mesh_vdev)) {
|
if (qdf_unlikely(vdev->mesh_vdev)) {
|
||||||
DP_TX_FREE_SINGLE_BUF(vdev->pdev->soc, tx_desc->nbuf);
|
DP_TX_FREE_SINGLE_BUF(vdev->pdev->soc, tx_desc->nbuf);
|
||||||
} else {
|
} else {
|
||||||
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
|
||||||
if ((peer->peer_ids[0] != HTT_INVALID_PEER) &&
|
if ((peer->peer_ids[0] != HTT_INVALID_PEER) &&
|
||||||
((peer->bss_peer &&
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
!(vdev->osif_proxy_arp(
|
/*
|
||||||
vdev->osif_vdev,
|
* . if 3-addr STA, then send on BSS Peer
|
||||||
nbuf))) ||
|
* . if Peer WDS enabled and accept 4-addr mcast,
|
||||||
peer->nawds_enabled)) {
|
* send mcast on that peer only
|
||||||
|
* . if Peer WDS enabled and accept 4-addr ucast,
|
||||||
|
* send ucast on that peer only
|
||||||
|
*/
|
||||||
|
((peer->bss_peer && num_peers_3addr && is_mcast) ||
|
||||||
|
(peer->wds_enabled &&
|
||||||
|
((is_mcast && peer->wds_ecm.wds_tx_mcast_4addr) ||
|
||||||
|
(is_ucast && peer->wds_ecm.wds_tx_ucast_4addr))))) {
|
||||||
|
#else
|
||||||
|
((peer->bss_peer &&
|
||||||
|
!(vdev->osif_proxy_arp(vdev->osif_vdev, nbuf))) ||
|
||||||
|
peer->nawds_enabled)) {
|
||||||
|
#endif
|
||||||
peer_id = DP_INVALID_PEER;
|
peer_id = DP_INVALID_PEER;
|
||||||
|
|
||||||
if (peer->nawds_enabled) {
|
if (peer->nawds_enabled) {
|
||||||
|
@@ -1217,6 +1217,17 @@ enum {
|
|||||||
dp_sec_ucast
|
dp_sec_ucast
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
typedef struct {
|
||||||
|
uint8_t wds_tx_mcast_4addr:1,
|
||||||
|
wds_tx_ucast_4addr:1,
|
||||||
|
wds_rx_filter:1, /* enforce rx filter */
|
||||||
|
wds_rx_ucast_4addr:1, /* when set, accept 4addr unicast frames */
|
||||||
|
wds_rx_mcast_4addr:1; /* when set, accept 4addr multicast frames */
|
||||||
|
|
||||||
|
} dp_ecm_policy;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Peer structure for data path state */
|
/* Peer structure for data path state */
|
||||||
struct dp_peer {
|
struct dp_peer {
|
||||||
/* VDEV to which this peer is associated */
|
/* VDEV to which this peer is associated */
|
||||||
@@ -1265,7 +1276,8 @@ struct dp_peer {
|
|||||||
/* NAWDS Flag and Bss Peer bit */
|
/* NAWDS Flag and Bss Peer bit */
|
||||||
uint8_t nawds_enabled:1,
|
uint8_t nawds_enabled:1,
|
||||||
bss_peer:1,
|
bss_peer:1,
|
||||||
wapi:1;
|
wapi:1,
|
||||||
|
wds_enabled:1;
|
||||||
|
|
||||||
/* MCL specific peer local id */
|
/* MCL specific peer local id */
|
||||||
uint16_t local_id;
|
uint16_t local_id;
|
||||||
@@ -1280,6 +1292,10 @@ struct dp_peer {
|
|||||||
|
|
||||||
TAILQ_HEAD(, dp_ast_entry) ast_entry_list;
|
TAILQ_HEAD(, dp_ast_entry) ast_entry_list;
|
||||||
/* TBD */
|
/* TBD */
|
||||||
|
|
||||||
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
|
dp_ecm_policy wds_ecm;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_WIN
|
#ifdef CONFIG_WIN
|
||||||
|
Reference in New Issue
Block a user