Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203053
b: refs/heads/master
c: 6854296
h: refs/heads/master
i:
  203051: bf2ca8e
v: v3
  • Loading branch information
Juuso Oikarinen authored and John W. Linville committed Jun 14, 2010
1 parent e7ab182 commit d75ba78
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 89 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5ea096c0c85e80335889539899af9a4717976e0b
refs/heads/master: 685429623f88d84f98bd5daffc3c427c408740d4
35 changes: 21 additions & 14 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include <linux/wireless.h>
#include <linux/device.h>
#include <linux/ieee80211.h>
#include <linux/inetdevice.h>
#include <net/cfg80211.h>

/**
Expand Down Expand Up @@ -147,6 +146,7 @@ struct ieee80211_low_level_stats {
* enabled/disabled (beaconing modes)
* @BSS_CHANGED_CQM: Connection quality monitor config changed
* @BSS_CHANGED_IBSS: IBSS join status changed
* @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed.
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
Expand All @@ -161,10 +161,18 @@ enum ieee80211_bss_change {
BSS_CHANGED_BEACON_ENABLED = 1<<9,
BSS_CHANGED_CQM = 1<<10,
BSS_CHANGED_IBSS = 1<<11,
BSS_CHANGED_ARP_FILTER = 1<<12,

/* when adding here, make sure to change ieee80211_reconfig */
};

/*
* The maximum number of IPv4 addresses listed for ARP filtering. If the number
* of addresses for an interface increase beyond this value, hardware ARP
* filtering will be disabled.
*/
#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4

/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
Expand Down Expand Up @@ -200,6 +208,15 @@ enum ieee80211_bss_change {
* @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value
* implies disabled
* @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis
* @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The
* may filter ARP queries targeted for other addresses than listed here.
* The driver must allow ARP queries targeted for all address listed here
* to pass through. An empty list implies no ARP queries need to pass.
* @arp_addr_cnt: Number of addresses currently on the list.
* @arp_filter_enabled: Enable ARP filtering - if enabled, the hardware may
* filter ARP queries based on the @arp_addr_list, if disabled, the
* hardware must not perform any ARP filtering. Note, that the filter will
* be enabled also in promiscuous mode.
*/
struct ieee80211_bss_conf {
const u8 *bssid;
Expand All @@ -220,6 +237,9 @@ struct ieee80211_bss_conf {
s32 cqm_rssi_thold;
u32 cqm_rssi_hyst;
enum nl80211_channel_type channel_type;
__be32 arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];
u8 arp_addr_cnt;
bool arp_filter_enabled;
};

/**
Expand Down Expand Up @@ -1529,16 +1549,6 @@ enum ieee80211_ampdu_mlme_action {
* of the bss parameters has changed when a call is made. The callback
* can sleep.
*
* @configure_arp_filter: Configuration function for hardware ARP query filter.
* This function is called with all the IP addresses configured to the
* interface as argument - all ARP queries targeted to any of these
* addresses must pass through. If the hardware filter does not support
* enought addresses, hardware filtering must be disabled. The ifa_list
* argument may be NULL, indicating that filtering must be disabled.
* This function is called upon association complete with current
* address(es), and while associated whenever the IP address(es) change.
* The callback can sleep.
*
* @prepare_multicast: Prepare for multicast filter configuration.
* This callback is optional, and its return value is passed
* to configure_filter(). This callback must be atomic.
Expand Down Expand Up @@ -1678,9 +1688,6 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed);
int (*configure_arp_filter)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct in_ifaddr *ifa_list);
u64 (*prepare_multicast)(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list);
void (*configure_filter)(struct ieee80211_hw *hw,
Expand Down
17 changes: 0 additions & 17 deletions trunk/net/mac80211/driver-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,6 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
trace_drv_return_void(local);
}

struct in_ifaddr;
static inline int drv_configure_arp_filter(struct ieee80211_local *local,
struct ieee80211_vif *vif,
struct in_ifaddr *ifa_list)
{
int ret = 0;

might_sleep();

trace_drv_configure_arp_filter(local, vif_to_sdata(vif));
if (local->ops->configure_arp_filter)
ret = local->ops->configure_arp_filter(&local->hw, vif,
ifa_list);
trace_drv_return_int(local, ret);
return ret;
}

static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
struct netdev_hw_addr_list *mc_list)
{
Expand Down
22 changes: 0 additions & 22 deletions trunk/net/mac80211/driver-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,28 +251,6 @@ TRACE_EVENT(drv_bss_info_changed,
)
);

TRACE_EVENT(drv_configure_arp_filter,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata),

TP_ARGS(local, sdata),

TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
),

TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
),

TP_printk(
VIF_PR_FMT LOCAL_PR_FMT,
VIF_PR_ARG, LOCAL_PR_ARG
)
);

TRACE_EVENT(drv_prepare_multicast,
TP_PROTO(struct ieee80211_local *local, int mc_count),

Expand Down
2 changes: 2 additions & 0 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ struct ieee80211_sub_if_data {
struct work_struct work;
struct sk_buff_head skb_queue;

bool arp_filter_state;

/*
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/mac80211/iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
sdata->wdev.wiphy = local->hw.wiphy;
sdata->local = local;
sdata->dev = ndev;
#ifdef CONFIG_INET
sdata->arp_filter_state = true;
#endif

for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
skb_queue_head_init(&sdata->fragments[i].skb_list);
Expand Down
54 changes: 34 additions & 20 deletions trunk/net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/rtnetlink.h>
#include <linux/bitmap.h>
#include <linux/pm_qos_params.h>
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>

Expand Down Expand Up @@ -317,23 +318,6 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
}

#ifdef CONFIG_INET
int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata)
{
struct in_device *idev;
int ret = 0;

BUG_ON(!sdata);
ASSERT_RTNL();

idev = sdata->dev->ip_ptr;
if (!idev)
return 0;

ret = drv_configure_arp_filter(sdata->local, &sdata->vif,
idev->ifa_list);
return ret;
}

static int ieee80211_ifa_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
Expand All @@ -343,8 +327,11 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
ifa_notifier);
struct net_device *ndev = ifa->ifa_dev->dev;
struct wireless_dev *wdev = ndev->ieee80211_ptr;
struct in_device *idev;
struct ieee80211_sub_if_data *sdata;
struct ieee80211_bss_conf *bss_conf;
struct ieee80211_if_managed *ifmgd;
int c = 0;

if (!netif_running(ndev))
return NOTIFY_DONE;
Expand All @@ -356,17 +343,44 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
if (wdev->wiphy != local->hw.wiphy)
return NOTIFY_DONE;

/* We are concerned about IP addresses only when associated */
sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
bss_conf = &sdata->vif.bss_conf;

/* ARP filtering is only supported in managed mode */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return NOTIFY_DONE;

idev = sdata->dev->ip_ptr;
if (!idev)
return NOTIFY_DONE;

ifmgd = &sdata->u.mgd;
mutex_lock(&ifmgd->mtx);
if (ifmgd->associated)
ieee80211_set_arp_filter(sdata);

/* Copy the addresses to the bss_conf list */
ifa = idev->ifa_list;
while (c < IEEE80211_BSS_ARP_ADDR_LIST_LEN && ifa) {
bss_conf->arp_addr_list[c] = ifa->ifa_address;
ifa = ifa->ifa_next;
c++;
}

/* If not all addresses fit the list, disable filtering */
if (ifa) {
sdata->arp_filter_state = false;
c = 0;
} else {
sdata->arp_filter_state = true;
}
bss_conf->arp_addr_cnt = c;

/* Configure driver only if associated */
if (ifmgd->associated) {
bss_conf->arp_filter_enabled = sdata->arp_filter_state;
ieee80211_bss_info_change_notify(sdata,
BSS_CHANGED_ARP_FILTER);
}

mutex_unlock(&ifmgd->mtx);

return NOTIFY_DONE;
Expand Down
34 changes: 19 additions & 15 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,11 +806,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
{
struct ieee80211_bss *bss = (void *)cbss->priv;
struct ieee80211_local *local = sdata->local;
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;

bss_info_changed |= BSS_CHANGED_ASSOC;
/* set timing information */
sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
sdata->vif.bss_conf.timestamp = cbss->tsf;
bss_conf->beacon_int = cbss->beacon_interval;
bss_conf->timestamp = cbss->tsf;

bss_info_changed |= BSS_CHANGED_BEACON_INT;
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
Expand All @@ -835,7 +836,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,

ieee80211_led_assoc(local, 1);

sdata->vif.bss_conf.assoc = 1;
bss_conf->assoc = 1;
/*
* For now just always ask the driver to update the basic rateset
* when we have associated, we aren't checking whether it actually
Expand All @@ -848,9 +849,15 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,

/* Tell the driver to monitor connection quality (if supported) */
if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
sdata->vif.bss_conf.cqm_rssi_thold)
bss_conf->cqm_rssi_thold)
bss_info_changed |= BSS_CHANGED_CQM;

/* Enable ARP filtering */
if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) {
bss_conf->arp_filter_enabled = sdata->arp_filter_state;
bss_info_changed |= BSS_CHANGED_ARP_FILTER;
}

ieee80211_bss_info_change_notify(sdata, bss_info_changed);

mutex_lock(&local->iflist_mtx);
Expand Down Expand Up @@ -932,6 +939,12 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,

ieee80211_hw_config(local, config_changed);

/* Disable ARP filtering */
if (sdata->vif.bss_conf.arp_filter_enabled) {
sdata->vif.bss_conf.arp_filter_enabled = false;
changed |= BSS_CHANGED_ARP_FILTER;
}

/* The BSSID (not really interesting) and HT changed */
changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
ieee80211_bss_info_change_notify(sdata, changed);
Expand Down Expand Up @@ -2018,18 +2031,9 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
cfg80211_send_assoc_timeout(wk->sdata->dev,
wk->filter_ta);
return WORK_DONE_DESTROY;
} else {
mutex_unlock(&wk->sdata->u.mgd.mtx);
#ifdef CONFIG_INET
/*
* configure ARP filter IP addresses to the driver,
* intentionally outside the mgd mutex.
*/
rtnl_lock();
ieee80211_set_arp_filter(wk->sdata);
rtnl_unlock();
#endif
}

mutex_unlock(&wk->sdata->u.mgd.mtx);
}

cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
Expand Down

0 comments on commit d75ba78

Please sign in to comment.