| 1449 | | /* NB: don't permit it to go negative */ |
|---|
| 1450 | | if (ni->ni_inact > 0) |
|---|
| 1451 | | ni->ni_inact--; |
|---|
| 1452 | | continue; |
|---|
| 1453 | | } |
|---|
| 1454 | | ni->ni_inact--; |
|---|
| 1455 | | if (ni->ni_associd != 0 || isadhoc) { |
|---|
| 1456 | | struct ieee80211vap *vap = ni->ni_vap; |
|---|
| 1457 | | /* |
|---|
| 1458 | | * Age frames on the power save queue. |
|---|
| 1459 | | */ |
|---|
| 1460 | | if (ieee80211_node_saveq_age(ni) != 0 && |
|---|
| 1461 | | IEEE80211_NODE_SAVEQ_QLEN(ni) == 0 && |
|---|
| 1462 | | vap->iv_set_tim != NULL) |
|---|
| 1463 | | vap->iv_set_tim(ni, 0); |
|---|
| 1464 | | /* |
|---|
| 1465 | | * Probe the station before time it out. We |
|---|
| 1466 | | * send a null data frame which may not be |
|---|
| 1467 | | * universally supported by drivers (need it |
|---|
| 1468 | | * for ps-poll support so it should be...). |
|---|
| 1469 | | */ |
|---|
| 1470 | | if (0 < ni->ni_inact && |
|---|
| 1471 | | ni->ni_inact <= vap->iv_inact_probe) { |
|---|
| 1472 | | IEEE80211_NOTE(vap, |
|---|
| 1473 | | IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, |
|---|
| 1474 | | ni, "%s", |
|---|
| 1475 | | "probe station due to inactivity"); |
|---|
| | 1449 | if (ni->ni_inact < 0) |
|---|
| | 1450 | ni->ni_inact = 0; |
|---|
| | 1451 | } else { |
|---|
| | 1452 | if ((ni->ni_associd != 0) || isadhoc) { |
|---|
| | 1453 | struct ieee80211vap *vap = ni->ni_vap; |
|---|
| | 1457 | if (ieee80211_node_saveq_age(ni) && |
|---|
| | 1458 | !IEEE80211_NODE_SAVEQ_QLEN(ni) && |
|---|
| | 1459 | (vap->iv_set_tim != NULL)) |
|---|
| | 1460 | vap->iv_set_tim(ni, 0); |
|---|
| | 1461 | |
|---|
| | 1462 | /* Probe the station before time it out. We |
|---|
| | 1463 | * send a null data frame which may not be |
|---|
| | 1464 | * universally supported by drivers (need it |
|---|
| | 1465 | * for ps-poll support so it should be...). */ |
|---|
| | 1466 | if ((0 < ni->ni_inact) && |
|---|
| | 1467 | (ni->ni_inact <= vap->iv_inact_probe)) { |
|---|
| | 1468 | IEEE80211_NOTE(vap, |
|---|
| | 1469 | IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, |
|---|
| | 1470 | ni, "%s", |
|---|
| | 1471 | "probe station due to inactivity"); |
|---|
| | 1472 | /* |
|---|
| | 1473 | * Grab a reference before unlocking the table |
|---|
| | 1474 | * so the node cannot be reclaimed before we |
|---|
| | 1475 | * send the frame. ieee80211_send_nulldata |
|---|
| | 1476 | * understands we've done this and reclaims the |
|---|
| | 1477 | * ref. for us as needed. |
|---|
| | 1478 | */ |
|---|
| | 1479 | ieee80211_ref_node(ni); |
|---|
| | 1480 | IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); |
|---|
| | 1481 | |
|---|
| | 1482 | ieee80211_send_nulldata(PASS_NODE(ni)); |
|---|
| | 1483 | |
|---|
| | 1484 | /* XXX stat? */ |
|---|
| | 1485 | goto restart; |
|---|
| | 1486 | } |
|---|
| | 1487 | } |
|---|
| | 1488 | |
|---|
| | 1489 | if (ni->ni_inact <= 0) { |
|---|
| | 1490 | IEEE80211_NOTE(ni->ni_vap, |
|---|
| | 1491 | IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, ni, |
|---|
| | 1492 | "station timed out due to inactivity (refcnt %u)", |
|---|
| | 1493 | ieee80211_node_refcnt(ni)); |
|---|
| | 1494 | /* |
|---|
| | 1495 | * Send a deauthenticate frame and drop the station. |
|---|
| | 1496 | * We grab a reference before unlocking the table so |
|---|
| | 1497 | * the node cannot be reclaimed before we complete our |
|---|
| | 1498 | * work. |
|---|
| | 1499 | * |
|---|
| | 1500 | * Separately we must drop the node lock before sending |
|---|
| | 1501 | * in case the driver takes a lock, as this may result |
|---|
| | 1502 | * in a LOR between the node lock and the driver lock. |
|---|
| | 1503 | */ |
|---|
| | 1504 | ni->ni_vap->iv_stats.is_node_timeout++; |
|---|
| 1489 | | } |
|---|
| 1490 | | if (ni->ni_inact <= 0) { |
|---|
| 1491 | | IEEE80211_NOTE(ni->ni_vap, |
|---|
| 1492 | | IEEE80211_MSG_INACT | IEEE80211_MSG_NODE, ni, |
|---|
| 1493 | | "station timed out due to inactivity (refcnt %u)", |
|---|
| 1494 | | ieee80211_node_refcnt(ni)); |
|---|
| 1495 | | /* |
|---|
| 1496 | | * Send a deauthenticate frame and drop the station. |
|---|
| 1497 | | * We grab a reference before unlocking the table so |
|---|
| 1498 | | * the node cannot be reclaimed before we complete our |
|---|
| 1499 | | * work. |
|---|
| 1500 | | * |
|---|
| 1501 | | * Separately we must drop the node lock before sending |
|---|
| 1502 | | * in case the driver takes a lock, as this may result |
|---|
| 1503 | | * in a LOR between the node lock and the driver lock. |
|---|
| 1504 | | */ |
|---|
| 1505 | | ni->ni_vap->iv_stats.is_node_timeout++; |
|---|
| 1506 | | ieee80211_ref_node(ni); |
|---|
| 1507 | | IEEE80211_NODE_TABLE_UNLOCK_IRQ_EARLY(nt); |
|---|
| 1508 | | if (ni->ni_associd != 0) { |
|---|
| 1509 | | IEEE80211_SEND_MGMT(ni, |
|---|
| 1510 | | IEEE80211_FC0_SUBTYPE_DEAUTH, |
|---|
| 1511 | | IEEE80211_REASON_AUTH_EXPIRE); |
|---|
| 1512 | | } |
|---|
| 1513 | | ieee80211_node_leave(ni); |
|---|
| 1514 | | ieee80211_unref_node(&ni); |
|---|
| 1515 | | goto restart; |
|---|