455 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			455 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/net80211/ieee80211_node.c
 | |
| +++ b/net80211/ieee80211_node.c
 | |
| @@ -123,6 +123,9 @@ static void ieee80211_node_table_cleanup
 | |
|  static void ieee80211_node_table_reset(struct ieee80211_node_table *,
 | |
|  	struct ieee80211vap *);
 | |
|  
 | |
| +static struct ieee80211_node *
 | |
| +lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, const u_int8_t *addr);
 | |
| +
 | |
|  MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
 | |
|  
 | |
|  void
 | |
| @@ -697,7 +700,7 @@ ieee80211_sta_join(struct ieee80211vap *
 | |
|  	struct ieee80211com *ic = vap->iv_ic;
 | |
|  	struct ieee80211_node *ni;
 | |
|  
 | |
| -	ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr);
 | |
| +	ni = lookup_rxnode(ic, vap, se->se_macaddr);
 | |
|  	if (ni == NULL) {
 | |
|  		ni = ieee80211_alloc_node_table(vap, se->se_macaddr);
 | |
|  		IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
 | |
| @@ -1394,6 +1397,53 @@ ieee80211_add_neighbor(struct ieee80211v
 | |
|  	return ni;
 | |
|  }
 | |
|  
 | |
| +struct ieee80211vap *
 | |
| +ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac)
 | |
| +{
 | |
| +	struct ieee80211vap *vap;
 | |
| +
 | |
| +	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 | |
| +		if (IEEE80211_ADDR_EQ(vap->iv_myaddr, mac))
 | |
| +			return vap;
 | |
| +	}
 | |
| +	return NULL;
 | |
| +}
 | |
| +EXPORT_SYMBOL(ieee80211_find_rxvap);
 | |
| +
 | |
| +static struct ieee80211_node *
 | |
| +lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
 | |
| +	const u_int8_t *addr)
 | |
| +{
 | |
| +	struct ieee80211_node_table *nt;
 | |
| +	struct ieee80211_node *ni = NULL;
 | |
| +	int use_bss = 0;
 | |
| +	int hash;
 | |
| +
 | |
| +	nt = &ic->ic_sta;
 | |
| +	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
 | |
| +	hash = IEEE80211_NODE_HASH(addr);
 | |
| +	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
 | |
| +		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, addr)) {
 | |
| +			/* allow multiple nodes on different vaps */
 | |
| +			if (vap && (ni->ni_vap != vap))
 | |
| +				continue;
 | |
| +
 | |
| +			ieee80211_ref_node(ni);
 | |
| +			goto out;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* no match found */
 | |
| +	ni = NULL;
 | |
| +
 | |
| +out:
 | |
| +	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
 | |
| +	return ni;
 | |
| +#undef IS_PSPOLL
 | |
| +#undef IS_CTL
 | |
| +}
 | |
| +
 | |
| +
 | |
|  /*
 | |
|   * Return the node for the sender of a frame; if the sender is unknown return 
 | |
|   * NULL. The caller is expected to deal with this. (The frame is sent to all 
 | |
| @@ -1403,10 +1453,10 @@ ieee80211_add_neighbor(struct ieee80211v
 | |
|   */
 | |
|  struct ieee80211_node *
 | |
|  #ifdef IEEE80211_DEBUG_REFCNT
 | |
| -ieee80211_find_rxnode_debug(struct ieee80211com *ic,
 | |
| +ieee80211_find_rxnode_debug(struct ieee80211com *ic, struct ieee80211vap *vap,
 | |
|  	const struct ieee80211_frame_min *wh, const char *func, int line)
 | |
|  #else
 | |
| -ieee80211_find_rxnode(struct ieee80211com *ic,
 | |
| +ieee80211_find_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
 | |
|  	const struct ieee80211_frame_min *wh)
 | |
|  #endif
 | |
|  {
 | |
| @@ -1414,9 +1464,8 @@ ieee80211_find_rxnode(struct ieee80211co
 | |
|  	((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
 | |
|  #define	IS_PSPOLL(wh) \
 | |
|  	((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
 | |
| -	struct ieee80211_node_table *nt;
 | |
| -	struct ieee80211_node *ni;
 | |
| -	struct ieee80211vap *vap, *avp;
 | |
| +	struct ieee80211_node *ni = NULL;
 | |
| +	struct ieee80211vap *avp;
 | |
|  	const u_int8_t *addr;
 | |
|  
 | |
|  	if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
 | |
| @@ -1429,32 +1478,25 @@ ieee80211_find_rxnode(struct ieee80211co
 | |
|  
 | |
|  	/* XXX check ic_bss first in station mode */
 | |
|  	/* XXX 4-address frames? */
 | |
| -	nt = &ic->ic_sta;
 | |
| -	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
 | |
|  	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) {
 | |
| -		TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 | |
| +		if (vap) { /* assume unicast if vap is set, mcast not supported for wds */
 | |
|  			TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
 | |
| -				if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac))
 | |
| +				if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac) ||
 | |
| +					!IEEE80211_ADDR_EQ(wh->i_addr1, avp->iv_myaddr))
 | |
|  					continue;
 | |
|  
 | |
|  				if (avp->iv_wdsnode)
 | |
| -					return ieee80211_ref_node(avp->iv_wdsnode);
 | |
| -				else
 | |
| -					return NULL;
 | |
| +					ni = ieee80211_ref_node(avp->iv_wdsnode);
 | |
| +				return ni;
 | |
|  			}
 | |
| +			if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS))
 | |
| +				return NULL;
 | |
| +		} else {
 | |
| +			return NULL;
 | |
|  		}
 | |
|  	}
 | |
|  
 | |
| -#ifdef IEEE80211_DEBUG_REFCNT
 | |
| -	ni = ieee80211_find_node_locked_debug(nt, addr, func, line);
 | |
| -#else
 | |
| -	ni = ieee80211_find_node_locked(nt, addr);
 | |
| -#endif
 | |
| -	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
 | |
| -
 | |
| -	return ni;
 | |
| -#undef IS_PSPOLL
 | |
| -#undef IS_CTL
 | |
| +	return lookup_rxnode(ic, vap, addr);
 | |
|  }
 | |
|  #ifdef IEEE80211_DEBUG_REFCNT
 | |
|  EXPORT_SYMBOL(ieee80211_find_rxnode_debug);
 | |
| @@ -1479,15 +1521,14 @@ ieee80211_find_txnode(struct ieee80211va
 | |
|  	struct ieee80211com *ic = vap->iv_ic;
 | |
|  	struct ieee80211_node_table *nt;
 | |
|  	struct ieee80211_node *ni = NULL;
 | |
| +	int hash;
 | |
|  
 | |
| -	IEEE80211_LOCK_IRQ(ic);
 | |
|  	if (vap->iv_opmode == IEEE80211_M_WDS) {
 | |
|  		if (vap->iv_wdsnode && (vap->iv_state == IEEE80211_S_RUN))
 | |
|  			return ieee80211_ref_node(vap->iv_wdsnode);
 | |
|  		else
 | |
|  			return NULL;
 | |
|  	}
 | |
| -	IEEE80211_UNLOCK_IRQ(ic);
 | |
|  
 | |
|  	/*
 | |
|  	 * The destination address should be in the node table
 | |
| @@ -1505,11 +1546,22 @@ ieee80211_find_txnode(struct ieee80211va
 | |
|  	/* XXX: Can't hold lock across dup_bss due to recursive locking. */
 | |
|  	nt = &vap->iv_ic->ic_sta;
 | |
|  	IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
 | |
| +	hash = IEEE80211_NODE_HASH(mac);
 | |
| +	LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
 | |
| +		if (ni->ni_vap != vap)
 | |
| +			continue;
 | |
| +
 | |
| +		if (IEEE80211_ADDR_EQ(ni->ni_macaddr, mac)) {
 | |
|  #ifdef IEEE80211_DEBUG_REFCNT
 | |
| -	ni = ieee80211_find_node_locked_debug(nt, mac, func, line);
 | |
| +			ieee80211_ref_node_debug(ni, func, line);
 | |
|  #else
 | |
| -	ni = ieee80211_find_node_locked(nt, mac);
 | |
| +			ieee80211_ref_node(ni);
 | |
|  #endif
 | |
| +			goto found;
 | |
| +		}
 | |
| +	}
 | |
| +	ni = NULL;
 | |
| +found:
 | |
|  	IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
 | |
|  
 | |
|  	if (ni == NULL) {
 | |
| @@ -1964,13 +2016,32 @@ remove_worse_nodes(void *arg, struct iee
 | |
|  		}
 | |
|  }
 | |
|  
 | |
| +static void
 | |
| +remove_duplicate_nodes(void *arg, struct ieee80211_node *ni)
 | |
| +{
 | |
| +	struct ieee80211_node *rni = arg;
 | |
| +
 | |
| +	if (ni == rni)
 | |
| +		return;
 | |
| +
 | |
| +	if (ni->ni_vap == rni->ni_vap)
 | |
| +		return;
 | |
| +
 | |
| +	if (!IEEE80211_ADDR_EQ(rni->ni_macaddr, ni->ni_macaddr))
 | |
| +		return;
 | |
| +
 | |
| +	ieee80211_node_leave(ni);
 | |
| +}
 | |
| +
 | |
|  void
 | |
|  ieee80211_node_join(struct ieee80211_node *ni, int resp)
 | |
|  {
 | |
|  	struct ieee80211com *ic = ni->ni_ic;
 | |
|  	struct ieee80211vap *vap = ni->ni_vap;
 | |
| +	struct ieee80211_node *tni;
 | |
|  	int newassoc;
 | |
|  
 | |
| +	ieee80211_iterate_nodes(&ic->ic_sta, remove_duplicate_nodes, ni);
 | |
|  	if (ni->ni_associd == 0) {
 | |
|  		u_int16_t aid;
 | |
|  
 | |
| --- a/net80211/ieee80211_input.c
 | |
| +++ b/net80211/ieee80211_input.c
 | |
| @@ -216,16 +216,14 @@ ieee80211_input(struct ieee80211vap * va
 | |
|  
 | |
|  	type = -1;			/* undefined */
 | |
|  
 | |
| -	if (!vap)
 | |
| -		goto out;
 | |
| +	if (!vap || !vap->iv_bss || !vap->iv_dev || !vap->iv_ic)
 | |
| +		goto discard;
 | |
|  
 | |
|  	ic = vap->iv_ic;
 | |
| -	if (!ic)
 | |
| -		goto out;
 | |
| -
 | |
|  	dev = vap->iv_dev;
 | |
| -	if (!dev)
 | |
| -		goto out;
 | |
| +
 | |
| +	if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
 | |
| +		goto discard;
 | |
|  
 | |
|  	/* initialize ni as in the previous API */
 | |
|  	if (ni_or_null == NULL) {
 | |
| @@ -233,9 +231,10 @@ ieee80211_input(struct ieee80211vap * va
 | |
|                  * guarantee its existence during the following call, hence
 | |
|                  * briefly grab our own reference. */
 | |
|  		ni = ieee80211_ref_node(vap->iv_bss);
 | |
| +		KASSERT(ni != NULL, ("null node"));
 | |
| +	} else {
 | |
| +		ni->ni_inact = ni->ni_inact_reload;
 | |
|  	}
 | |
| -	KASSERT(ni != NULL, ("null node"));
 | |
| -	ni->ni_inact = ni->ni_inact_reload;
 | |
|  
 | |
|  	KASSERT(skb->len >= sizeof(struct ieee80211_frame_min),
 | |
|  		("frame length too short: %u", skb->len));
 | |
| @@ -844,10 +843,11 @@ ieee80211_input(struct ieee80211vap * va
 | |
|  err:
 | |
|  	vap->iv_devstats.rx_errors++;
 | |
|  out:
 | |
| -	if (skb != NULL)
 | |
| -		ieee80211_dev_kfree_skb(&skb);
 | |
|  	if (ni_or_null == NULL)
 | |
|  		ieee80211_unref_node(&ni);
 | |
| +discard:
 | |
| +	if (skb != NULL)
 | |
| +		ieee80211_dev_kfree_skb(&skb);
 | |
|  	return type;
 | |
|  #undef HAS_SEQ
 | |
|  }
 | |
| @@ -929,16 +929,23 @@ int
 | |
|  ieee80211_input_all(struct ieee80211com *ic,
 | |
|  	struct sk_buff *skb, int rssi, u_int64_t rtsf)
 | |
|  {
 | |
| +	struct ieee80211_frame_min *wh = (struct ieee80211_frame_min *) skb->data;
 | |
|  	struct ieee80211vap *vap;
 | |
|  	int type = -1;
 | |
|  
 | |
|  	/* XXX locking */
 | |
|  	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 | |
| +		struct ieee80211_node *ni = NULL;
 | |
|  		struct sk_buff *skb1;
 | |
|  
 | |
|  		if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
 | |
|  			continue;
 | |
|  
 | |
| +		if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
 | |
| +			!IEEE80211_IS_MULTICAST(wh->i_addr1))
 | |
| +			continue;
 | |
| +
 | |
| +		ni = ieee80211_find_rxnode(ic, vap, wh);
 | |
|  		if (TAILQ_NEXT(vap, iv_next) != NULL) {
 | |
|  			skb1 = skb_copy(skb, GFP_ATOMIC);
 | |
|  			if (skb1 == NULL) {
 | |
| @@ -950,8 +957,10 @@ ieee80211_input_all(struct ieee80211com 
 | |
|  			skb1 = skb;
 | |
|  			skb = NULL;
 | |
|  		}
 | |
| -		type = ieee80211_input(vap, NULL, skb1, rssi, rtsf);
 | |
| +		type = ieee80211_input(vap, ni, skb1, rssi, rtsf);
 | |
|  	}
 | |
| +
 | |
| +out:
 | |
|  	if (skb != NULL)		/* no vaps, reclaim skb */
 | |
|  		ieee80211_dev_kfree_skb(&skb);
 | |
|  	return type;
 | |
| @@ -1146,11 +1155,9 @@ ieee80211_deliver_data(struct ieee80211_
 | |
|  			 * sending it will not work; just let it be
 | |
|  			 * delivered normally.
 | |
|  			 */
 | |
| -			struct ieee80211_node *ni1 = ieee80211_find_node(
 | |
| -				&vap->iv_ic->ic_sta, eh->ether_dhost);
 | |
| +			struct ieee80211_node *ni1 = ieee80211_find_txnode(vap, eh->ether_dhost);
 | |
|  			if (ni1 != NULL) {
 | |
| -				if (ni1->ni_vap == vap &&
 | |
| -				    ieee80211_node_is_authorized(ni1) &&
 | |
| +				if (ieee80211_node_is_authorized(ni1) &&
 | |
|  					!ni1->ni_subif &&
 | |
|  				    ni1 != vap->iv_bss) {
 | |
|  
 | |
| --- a/ath/if_ath.c
 | |
| +++ b/ath/if_ath.c
 | |
| @@ -6578,9 +6578,8 @@ ath_recv_mgmt(struct ieee80211vap * vap,
 | |
|  
 | |
|  	sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
 | |
|  
 | |
| -
 | |
|  	/* Lookup the new node if any (this grabs a reference to it) */
 | |
| -	ni = ieee80211_find_rxnode(vap->iv_ic,
 | |
| +	ni = ieee80211_find_rxnode(vap->iv_ic, vap,
 | |
|  	         (const struct ieee80211_frame_min *)skb->data);
 | |
|  	if (ni == NULL) {
 | |
|  		DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
 | |
| @@ -6735,7 +6734,9 @@ ath_rx_poll(struct net_device *dev, int 
 | |
|  	struct ath_desc *ds;
 | |
|  	struct ath_rx_status *rs;
 | |
|  	struct sk_buff *skb = NULL;
 | |
| +	struct ieee80211vap *vap;
 | |
|  	struct ieee80211_node *ni;
 | |
| +	const struct ieee80211_frame_min *wh;
 | |
|  	unsigned int len;
 | |
|  	int type;
 | |
|  	u_int phyerr;
 | |
| @@ -6890,12 +6891,15 @@ rx_accept:
 | |
|  		skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
 | |
|  
 | |
|  		if (mic_fail) {
 | |
| +			wh = (const struct ieee80211_frame_min *) skb->data;
 | |
| +
 | |
|  			/* Ignore control frames which are reported with mic error */
 | |
| -		    if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
 | |
| +		    if ((wh->i_fc[0] &
 | |
|  					IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
 | |
|  				goto drop_micfail;
 | |
|  
 | |
| -			ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
 | |
| +			vap = ieee80211_find_rxvap(ic, wh->i_addr1);
 | |
| +			ni = ieee80211_find_rxnode(ic, vap, wh);
 | |
|  
 | |
|  			if (ni && ni->ni_table) {
 | |
|  				ieee80211_check_mic(ni, skb);
 | |
| @@ -6957,11 +6961,24 @@ drop_micfail:
 | |
|  		 * for its use.  If the sender is unknown spam the
 | |
|  		 * frame; it'll be dropped where it's not wanted.
 | |
|  		 */
 | |
| -		if (rs->rs_keyix != HAL_RXKEYIX_INVALID &&
 | |
| +		wh = (const struct ieee80211_frame_min *) skb->data;
 | |
| +		if ((rs->rs_keyix != HAL_RXKEYIX_INVALID) &&
 | |
|  		    (ni = sc->sc_keyixmap[rs->rs_keyix]) != NULL) {
 | |
|  			/* Fast path: node is present in the key map;
 | |
|  			 * grab a reference for processing the frame. */
 | |
| -			ni = ieee80211_ref_node(ni);
 | |
| +			ieee80211_ref_node(ni);
 | |
| +			if ((ATH_GET_VAP_ID(wh->i_addr1) !=
 | |
| +			     ATH_GET_VAP_ID(ni->ni_vap->iv_myaddr)) ||
 | |
| +				((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
 | |
| +				 IEEE80211_FC1_DIR_DSTODS)) {
 | |
| +				/* key cache node lookup is fast, but it can
 | |
| +				 * lead to problems in multi-bss (foreign vap
 | |
| +				 * node reference) or wds (wdsap node ref instead
 | |
| +				 * of base ap node ref).
 | |
| +				 * use slowpath lookup in both cases
 | |
| +				 */
 | |
| +				goto lookup_slowpath;
 | |
| +			}
 | |
|  			ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
 | |
|  			type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
 | |
|  			ieee80211_unref_node(&ni);
 | |
| @@ -6970,24 +6987,35 @@ drop_micfail:
 | |
|  			 * No key index or no entry, do a lookup and
 | |
|  			 * add the node to the mapping table if possible.
 | |
|  			 */
 | |
| -			ni = ieee80211_find_rxnode(ic,
 | |
| -				(const struct ieee80211_frame_min *)skb->data);
 | |
| +
 | |
| +lookup_slowpath:
 | |
| +			vap = ieee80211_find_rxvap(ic, wh->i_addr1);
 | |
| +			if (vap)
 | |
| +				ni = ieee80211_find_rxnode(ic, vap, wh);
 | |
| +			else
 | |
| +				ni = NULL;
 | |
| +
 | |
|  			if (ni != NULL) {
 | |
|  				ieee80211_keyix_t keyix;
 | |
|  
 | |
|  				ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
 | |
| -				type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
 | |
| +				type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
 | |
|  				/*
 | |
|  				 * If the station has a key cache slot assigned
 | |
|  				 * update the key->node mapping table.
 | |
|  				 */
 | |
|  				keyix = ni->ni_ucastkey.wk_keyix;
 | |
|  				if (keyix != IEEE80211_KEYIX_NONE &&
 | |
| -				    sc->sc_keyixmap[keyix] == NULL)
 | |
| +				    sc->sc_keyixmap[keyix] == NULL) {
 | |
|  					sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni);
 | |
| +				}
 | |
|  				ieee80211_unref_node(&ni);
 | |
| -			} else
 | |
| -				type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
 | |
| +			} else {
 | |
| +				if (vap)
 | |
| +					type = ieee80211_input(vap, NULL, skb, rs->rs_rssi, bf->bf_tsf);
 | |
| +				else
 | |
| +					type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
 | |
| +			}
 | |
|  		}
 | |
|  
 | |
|  		if (sc->sc_diversity) {
 | |
| --- a/net80211/ieee80211_node.h
 | |
| +++ b/net80211/ieee80211_node.h
 | |
| @@ -286,15 +286,18 @@ struct ieee80211_node *ieee80211_find_no
 | |
|  	const u_int8_t *);
 | |
|  #endif /* #ifdef IEEE80211_DEBUG_REFCNT */
 | |
|  
 | |
| +struct ieee80211vap *
 | |
| +ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac);
 | |
| +
 | |
|  /* Returns a ieee80211_node* with refcount incremented, if found */
 | |
|  #ifdef IEEE80211_DEBUG_REFCNT
 | |
| -#define	ieee80211_find_rxnode(_nt, _wh) \
 | |
| -	ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__)
 | |
| +#define	ieee80211_find_rxnode(_nt, _vap, _wh) \
 | |
| +	ieee80211_find_rxnode_debug(_nt, _vap, _wh, __func__, __LINE__)
 | |
|  struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *,
 | |
| -	const struct ieee80211_frame_min *, const char *, int);
 | |
| +	struct ieee80211vap *, const struct ieee80211_frame_min *, const char *, int);
 | |
|  #else
 | |
|  struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *,
 | |
| -	const struct ieee80211_frame_min *);
 | |
| +	struct ieee80211vap *, const struct ieee80211_frame_min *);
 | |
|  #endif /* #ifdef IEEE80211_DEBUG_REFCNT */
 | |
|  
 | |
|  /* Returns a ieee80211_node* with refcount incremented, if found */
 |