o80211s: (mac80211s) basic mesh interface support
PATCH 3/4 o80211s: (mac80211s) basic mesh interface support
This commit introduces mesh interface support for the mac80211 stack. It provides support for pre-802.11s frame format, static unicast forwarding, mesh beaconing, mesh statistics through debugfs.
--- include/net/mac80211.h | 3 + net/mac80211/Makefile | 1 + net/mac80211/cfg.c | 27 +++++++ net/mac80211/debugfs_netdev.c | 36 +++++++++ net/mac80211/ieee80211.c | 17 ++++- net/mac80211/ieee80211_i.h | 18 ++++- net/mac80211/ieee80211_iface.c | 11 +++ net/mac80211/ieee80211_sta.c | 120 ++++++++++++++++++++++++++++- net/mac80211/ieee80211s.h | 50 ++++++++++++ net/mac80211/mesh_pathtbl.c | 169 ++++++++++++++++++++++++++++++++++++++++ net/mac80211/rx.c | 66 +++++++++++++++- net/mac80211/tx.c | 38 +++++++++- net/mac80211/util.c | 41 ++++++++++ 13 files changed, 590 insertions(+), 7 deletions(-) create mode 100644 net/mac80211/ieee80211s.h create mode 100644 net/mac80211/mesh_pathtbl.c
include/net/mac80211.h +3 -0
@@ -474,6 +474,7 @@ enum ieee80211_if_types {IEEE80211_IF_TYPE_AP ,IEEE80211_IF_TYPE_STA ,IEEE80211_IF_TYPE_IBSS , +IEEE80211_IF_TYPE_MESH ,IEEE80211_IF_TYPE_MNTR ,IEEE80211_IF_TYPE_WDS , IEEE80211_IF_TYPE_VLAN,
@@ -521,6 +522,8 @@ struct ieee80211_if_init_conf {* config_interface() call, so copy the value somewhere if you need * it. * @ssid_len: length of the @ssid field. +* @mesh_id: mesh ID of the mesh network we will be part of. +* @mesh_id_len: length of the @mesh_id field. * @beacon: beacon template. Valid only if @host_gen_beacon_template in * &struct ieee80211_hw is set. The driver is responsible of freeing * the sk_buff.
net/mac80211/Makefile +1 -0
@@ -24,4 +24,5 @@ mac80211-objs := \ key.o \ util.o \ event.o \ + mesh_pathtbl.o \ $(mac80211-objs-y)
net/mac80211/cfg.c +27 -0
@@ -25,6 +25,8 @@ nl80211_type_to_mac80211_type(enum nl80211_iftype type)return IEEE80211_IF_TYPE_STA ;case NL80211_IFTYPE_MONITOR :return IEEE80211_IF_TYPE_MNTR ; +case NL80211_IFTYPE_MESH : +return IEEE80211_IF_TYPE_MESH ;default :return IEEE80211_IF_TYPE_INVALID ; }
@@ -99,8 +101,33 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,return 0 ; } +static int ieee80211_if_set_mesh_cfg (struct wiphy *wiphy, +struct net_device *dev,struct mesh_params *params) +{ +struct ieee80211_local *local =wiphy_priv (wiphy); +struct ieee80211_if_sta *ifsta; +struct ieee80211_sub_if_data *sdata =NULL ; +if (unlikely (local->reg_state !=IEEE80211_DEV_REGISTERED )) +return -ENODEV ; + + sdata =IEEE80211_DEV_TO_SUB_IF (dev); +if (sdata->type !=IEEE80211_IF_TYPE_MESH ) +return -EINVAL ; + + ifsta = &sdata->u.sta; + ifsta->mesh_id_len = params->mesh_id_len; +if (params->mesh_id_len) +memcpy (ifsta->mesh_id, params->mesh_id, params->mesh_id_len); + +/* If the iface is down, it will be configure when it is opened */ +if (netif_running (dev)) +ieee80211_if_config (dev); +return 0 ; +} +struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, .change_virtual_intf = ieee80211_change_iface, + .set_mesh_cfg = ieee80211_if_set_mesh_cfg, };
net/mac80211/debugfs_netdev.c +36 -0
@@ -162,6 +162,10 @@ __IEEE80211_IF_FILE(beacon_tail_len);/* WDS attributes */ IEEE80211_IF_FILE (peer, u.wds.remote_addr,MAC ); +/* Mesh stats attributes */ +IEEE80211_IF_FILE (fwded_frames, u.sta.mshstats.fwded_frames,DEC ); +IEEE80211_IF_FILE (dropped_frames_ttl, u.sta.mshstats.dropped_frames_ttl,DEC ); +#define DEBUGFS_ADD (name, type)\ sdata->debugfs.type.name = debugfs_create_file(#name, 0444,\ sdata->debugfsdir, sdata, &name##_ops);
@@ -226,12 +230,27 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) { } +#define MESHSTATS_ADD (name)\ + sdata->mesh_stats.name = debugfs_create_file(#name, 0444,\ + sdata->mesh_stats_dir, sdata, &name##_ops); + +static void add_mesh_stats (struct ieee80211_sub_if_data *sdata) +{ + sdata->mesh_stats_dir =debugfs_create_dir ("mesh_stats" , + sdata->debugfsdir); +MESHSTATS_ADD (fwded_frames); +MESHSTATS_ADD (dropped_frames_ttl); +} +static void add_files (struct ieee80211_sub_if_data *sdata) {if (!sdata->debugfsdir)return ;switch (sdata->type) { +case IEEE80211_IF_TYPE_MESH : +add_mesh_stats (sdata); +/* fall through */ case IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS :add_sta_files (sdata);
@@ -319,12 +338,29 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata) { } +#define MESHSTATS_DEL (name) \ + do { \ + debugfs_remove(sdata->mesh_stats.name); \ + sdata->mesh_stats.name = NULL; \ + } while (0) + +static void del_mesh_stats (struct ieee80211_sub_if_data *sdata) +{ +MESHSTATS_DEL (fwded_frames); +MESHSTATS_DEL (dropped_frames_ttl); +debugfs_remove (sdata->mesh_stats_dir); + sdata->mesh_stats_dir =NULL ; +} +static void del_files (struct ieee80211_sub_if_data *sdata,int type) {if (!sdata->debugfsdir)return ;switch (type) { +case IEEE80211_IF_TYPE_MESH : +del_mesh_stats (sdata); +/* fall through */ case IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS :del_sta_files (sdata);
net/mac80211/ieee80211.c +16 -1
@@ -26,6 +26,7 @@#include "ieee80211_i.h" #include "ieee80211_rate.h" +#include "ieee80211s.h" #include "wep.h" #include "wme.h" #include "aes_ccm.h"
@@ -126,9 +127,15 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)static int ieee80211_change_mtu (struct net_device *dev,int new_mtu) { +int meshhdrlen; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); + + meshhdrlen = (sdata->type ==IEEE80211_IF_TYPE_MESH ) ?5 :0 ; +/* FIX: what would be proper limits for MTU? * This interface uses 802.3 frames. */ -if (new_mtu <256 || new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 ) { +if (new_mtu <256 || + new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 - meshhdrlen) {printk (KERN_WARNING "%s: invalid MTU %d\n" , dev->name, new_mtu);return -EINVAL ;
@@ -202,6 +209,7 @@ static int ieee80211_open(struct net_device *dev)case IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_MNTR :case IEEE80211_IF_TYPE_IBSS : +case IEEE80211_IF_TYPE_MESH :/* no special treatment */ break ;case IEEE80211_IF_TYPE_INVALID :
@@ -465,6 +473,11 @@ static int __ieee80211_if_config(struct net_device *dev, conf.bssid = sdata->u.sta.bssid; conf.ssid = sdata->u.sta.ssid; conf.ssid_len = sdata->u.sta.ssid_len; + }else if (sdata->type ==IEEE80211_IF_TYPE_MESH ) { +/* SSID is wildcard (all 0s) */ +ieee80211_set_mesh_beacon_template (dev, &conf); + local->hw.flags |=IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE ; +ieee80211_start_mesh (dev); }else if (sdata->type ==IEEE80211_IF_TYPE_AP ) { conf.ssid = sdata->u.ap.ssid; conf.ssid_len = sdata->u.ap.ssid_len;
@@ -1262,6 +1275,8 @@ static void __exit ieee80211_exit(void)ieee80211_rate_control_unregister (&mac80211_rcsimple);#endif +if (mesh_allocated) +mesh_pathtbl_unregister ();ieee80211_wme_unregister ();ieee80211_debugfs_netdev_exit (); }
net/mac80211/ieee80211_i.h +17 -1
@@ -25,6 +25,7 @@#include <net/wireless.h> #include "ieee80211_key.h" #include "sta_info.h" +#include "ieee80211s.h" /* ieee80211.o internal definitions, etc. These are not included into * low-level drivers. */
@@ -235,13 +236,16 @@ struct ieee80211_if_sta {enum {IEEE80211_DISABLED ,IEEE80211_AUTHENTICATE ,IEEE80211_ASSOCIATE ,IEEE80211_ASSOCIATED , -IEEE80211_IBSS_SEARCH ,IEEE80211_IBSS_JOINED +IEEE80211_IBSS_SEARCH ,IEEE80211_IBSS_JOINED , +IEEE80211_MESH } state;struct timer_list timer;struct work_struct work;u8 bssid[ETH_ALEN ], prev_bssid[ETH_ALEN ];u8 ssid[IEEE80211_MAX_SSID_LEN ];size_t ssid_len; +u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN ]; +size_t mesh_id_len;u16 aid;u16 ap_capab, capab;u8 *extra_ie;/* to be added to the end of AssocReq */
@@ -274,6 +278,8 @@ struct ieee80211_if_sta {u32 supp_rates_bits;int wmm_last_param_set; +struct mesh_stats mshstats; +atomic_t mesh_seqnum; };
@@ -384,6 +390,12 @@ struct ieee80211_sub_if_data { } monitor;struct dentry *default_key; } debugfs; + +struct dentry *mesh_stats_dir; +struct { +struct dentry *fwded_frames; +struct dentry *dropped_frames_ttl; + } mesh_stats;#endif };
@@ -759,6 +771,10 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);int ieee80211_sta_disassociate (struct net_device *dev,u16 reason);void ieee80211_erp_info_change_notify (struct net_device *dev,u8 changes);void ieee80211_reset_erp_info (struct net_device *dev); +void ieee80211_start_mesh (struct net_device *dev); +int ieee80211_set_mesh_beacon_template (struct net_device *dev, +struct ieee80211_if_conf *conf); +/* ieee80211_iface.c */ int ieee80211_if_add(struct net_device *dev, const char *name,
net/mac80211/ieee80211_iface.c +11 -0
@@ -15,6 +15,7 @@#include "ieee80211_i.h" #include "sta_info.h" #include "debugfs_netdev.h" +#include "ieee80211s.h" void ieee80211_if_sdata_init (struct ieee80211_sub_if_data *sdata) {
@@ -134,6 +135,15 @@ void ieee80211_if_set_type(struct net_device *dev, int type) sdata->bss = &sdata->u.ap;INIT_LIST_HEAD (&sdata->u.ap.vlans);break ; +case IEEE80211_IF_TYPE_MESH : +if (!mesh_allocated) { +/* Allocate all mesh structures when creating the first +* mesh interface. +*/ +mesh_pathtbl_init (); + mesh_allocated =1 ; + } +/* fall thru */ case IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : {struct ieee80211_sub_if_data *msdata;
@@ -232,6 +242,7 @@ void ieee80211_if_reinit(struct net_device *dev)break ;case IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : +case IEEE80211_IF_TYPE_MESH :kfree (sdata->u.sta.extra_ie); sdata->u.sta.extra_ie =NULL ;kfree (sdata->u.sta.assocreq_ies);
net/mac80211/ieee80211_sta.c +119 -1
156 lines not on this page · raw message
net/mac80211/ieee80211s.h new file +50 -0
50 lines not on this page · raw message
net/mac80211/mesh_pathtbl.c new file +169 -0
169 lines not on this page · raw message
net/mac80211/rx.c +64 -2
108 lines not on this page · raw message
net/mac80211/tx.c +36 -2
@@ -26,6 +26,7 @@#include "ieee80211_i.h" #include "ieee80211_led.h" +#include "ieee80211s.h" #include "wep.h" #include "wpa.h" #include "wme.h"
@@ -230,6 +231,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))return TXRX_DROP ; +if (tx->sdata->type ==IEEE80211_IF_TYPE_MESH ) +return TXRX_CONTINUE ; +if (tx->flags &IEEE80211_TXRXD_TXPS_BUFFERED )return TXRX_CONTINUE ;
@@ -1342,8 +1346,9 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,struct ieee80211_tx_packet_data *pkt_data;struct ieee80211_sub_if_data *sdata;int ret =1 , head_need; -u16 ethertype, hdrlen, fc; +u16 ethertype, hdrlen, meshhdrlen =0 , fc;struct ieee80211_hdr hdr; +struct ieee80211s_hdr mesh_hdr;const u8 *encaps_data;int encaps_len, skip_header_bytes;int nh_pos, h_pos;
@@ -1385,6 +1390,29 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,memcpy (hdr.addr4, skb->data +ETH_ALEN ,ETH_ALEN ); hdrlen =30 ;break ; +case IEEE80211_IF_TYPE_MESH : + fc |=IEEE80211_FCTL_FROMDS |IEEE80211_FCTL_TODS ; +/* RA TA DA SA */ +if (is_multicast_ether_addr (skb->data)) +memcpy (hdr.addr1, skb->data,ETH_ALEN ); +else if (ieee80211s_nh_lookup (skb->data, hdr.addr1)) { + ret =0 ; + goto fail; + } +memcpy (hdr.addr2, dev->dev_addr,ETH_ALEN ); +memcpy (hdr.addr3, skb->data,ETH_ALEN ); +memcpy (hdr.addr4, skb->data +ETH_ALEN ,ETH_ALEN ); +if (skb->pkt_type ==PACKET_OTHERHOST ) { +/* Forwarded frame, keep mesh ttl and seqnum */ +struct ieee80211s_hdr *prev_meshhdr; + prev_meshhdr = ((struct ieee80211s_hdr *)skb->cb); + meshhdrlen =ieee80211_get_mesh_hdrlen (prev_meshhdr); +memcpy (&mesh_hdr, prev_meshhdr, meshhdrlen); + }else + meshhdrlen =ieee80211_new_mesh_header (&mesh_hdr, + sdata); + hdrlen =30 ; +break ;case IEEE80211_IF_TYPE_STA : fc |=IEEE80211_FCTL_TODS ;/* BSSID SA DA */
@@ -1450,7 +1478,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,* build in headroom in __dev_alloc_skb() (linux/skbuff.h) and * alloc_skb() (net/core/skbuff.c) */ - head_need = hdrlen + encaps_len + local->tx_headroom; + head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom; head_need -=skb_headroom (skb);/* We are going to modify skb data, so make a copy of it if happens to
@@ -1484,6 +1512,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, h_pos += encaps_len; } +if (meshhdrlen >0 ) { +memcpy (skb_push (skb, meshhdrlen), &mesh_hdr, meshhdrlen); + nh_pos += meshhdrlen; + h_pos += meshhdrlen; + } +if (fc &IEEE80211_STYPE_QOS_DATA ) {__le16 *qos_control;
net/mac80211/util.c +41 -0
50 lines not on this page · raw message
Signature · 1 line
1.5.2.5
Johannes Berg
maintainerinclude/net/mac80211.h enum ieee80211_if_types { · line 477
Quoted 8 lines
include/net/mac80211.h +1
-0@@ -474,6 +474,7 @@ enum ieee80211_if_types {IEEE80211_IF_TYPE_AP ,IEEE80211_IF_TYPE_STA ,IEEE80211_IF_TYPE_IBSS , + IEEE80211_IF_TYPE_MESH,
What happened to Dan's suggestion of calling this MESH_STA? And maybe in nl80211 as well? I might've missed something, was there a conclusion?
Debugfs code looks good.
Quoted 5 lines
include/net/mac80211.h +3
-0static int ieee80211_change_mtu (struct net_device *dev,int new_mtu) { +int meshhdrlen; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +
include/net/mac80211.h enum ieee80211_if_types {
Quoted 10 lines
include/net/mac80211.h +4
-1+ meshhdrlen = (sdata->type ==IEEE80211_IF_TYPE_MESH ) ?5 :0 ; +/* FIX: what would be proper limits for MTU? * This interface uses 802.3 frames. */ -if (new_mtu <256 || new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 ) { +if (new_mtu <256 || + new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 - meshhdrlen) {printk (KERN_WARNING "%s: invalid MTU %d\n" , dev->name, new_mtu);return -EINVAL ;
Are you sure this is appropriate? As the comment says, interface is 802.3 framed. Don't the 802.11 specifications usually keep the frame payload length and require the device to handle longer frames?
include/net/mac80211.h
Quoted 1 line
include/net/mac80211.h +1
-0+atomic_t mesh_seqnum;
Hmm. Do we really need an atomic_t here?
include/net/mac80211.h
Quoted 9 lines
include/net/mac80211.h +9
-0+case IEEE80211_IF_TYPE_MESH : +if (!mesh_allocated) { +/* Allocate all mesh structures when creating the first +* mesh interface. +*/ +mesh_pathtbl_init (); + mesh_allocated =1 ; + } +/* fall thru */
Will there be other structures to allocate? Maybe we should instead push the "already" check into the _init()?
include/net/mac80211.h
Quoted 3 lines
include/net/mac80211.h +3
-0+/* TODO: check for expired neighbors, paths and frames to non resolved +* hw addresses +*/
Seems dangerous to actually run the code w/o this, no?
include/net/mac80211.h
Quoted 2 lines
include/net/mac80211.h +2
-0+ mgmt->u.beacon.beacon_int = +cpu_to_le16 (local->hw.conf.beacon_int);
Hmm. This is interesting. The beacon interval is a pure beacon configuration after my patches, but here we're using it without having userspace set up a beacon. What do we do in the IBSS case?
include/net/mac80211.h
Quoted 5 lines
include/net/mac80211.h +5
-0+static int o80211s_getmeshpath (struct sk_buff *skb,struct nlmsghdr *nlh, +void *arg) +{ +return 0 ; +}
Uh huh. Why is this here? Should it be filled?
include/net/mac80211.h
Quoted 1 line
include/net/mac80211.h +1
-0+read_lock (&mesh_paths_lock);
When do we need the mesh paths? Should the structure use RCU maybe?
include/net/mac80211.h
Quoted 10 lines
include/net/mac80211.h +10
-0+if (sdata->type ==IEEE80211_IF_TYPE_MESH ) { +int meshhdrlen =ieee80211_get_mesh_hdrlen ( + (struct ieee80211s_hdr *) skb->data); +/* Copy mesh header on cb to be used if forwarded. +* It will be used as mesh header template at +* tx.c:ieee80211_subif_start_xmit() if interface +* type is mesh and skb->pkt_type == PACKET_OTHERHOST +*/ +memcpy (skb->cb, skb->data + hdrlen, meshhdrlen); + hdrlen += meshhdrlen;
Thanks for the explanation. This only happens when we dev_queue_xmit() it right away in the mesh forwarding code, right?
include/net/mac80211.h
Quoted 3 lines
include/net/mac80211.h +3
-0+/* Mesh forwarding */ +if (sdata->type ==IEEE80211_IF_TYPE_MESH ) { +u8 *mesh_ttl = &((struct ieee80211s_hdr *)skb->cb)->ttl;
Oh it's used here too :)
include/net/mac80211.h ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) · line 235
Quoted 6 lines
include/net/mac80211.h +2
-0@@ -230,6 +231,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))return TXRX_DROP ; +if (tx->sdata->type ==IEEE80211_IF_TYPE_MESH ) +return TXRX_CONTINUE ;
Is this right or should there be some other "is forwarded frame" check to go with this? I'm not sure but it seems that frames we send via the netdev need to be still checked? Or not because they're just injected into the mesh? I think I'm confused.
include/net/mac80211.h ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
Quoted 6 lines
include/net/mac80211.h +6
-0+case IEEE80211_IF_TYPE_MESH : + fc |=IEEE80211_FCTL_FROMDS |IEEE80211_FCTL_TODS ; +/* RA TA DA SA */ +if (is_multicast_ether_addr (skb->data)) +memcpy (hdr.addr1, skb->data,ETH_ALEN ); +else if (ieee80211s_nh_lookup (skb->data, hdr.addr1)) {
I think you should use RCU for the locking in the neighbour table. This code should (IIRC) be under rcu read-side lock already so the neighbour table reading would be lockless. Since updates are infrequent, RCU is a good tradeoff.
Quoted 1 line
+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
Don't export this.
include/net/mac80211.h
Quoted 5 lines
include/net/mac80211.h +5
-0+int ieee80211_new_mesh_header (struct ieee80211s_hdr *meshhdr, +struct ieee80211_sub_if_data *sdata) +{ +/* TODO: create a per mesh interface atomic sequence counter */ +int mesh_seqnum =atomic_inc_return (&sdata->u.sta.mesh_seqnum);
Since you use new_mesh_header only from within the TX code which is serialised, you don't need atomic. Also, this *is* per-mesh interface (sdata), the TODO makes no sense.
Quoted 1 line
+EXPORT_SYMBOL(ieee80211_new_mesh_header);
Don't export this either.
johannes
Johannes,
Quoted 10 lines · Johannes Berg
include/net/mac80211.h enum ieee80211_if_types { · line 477
Quoted 7 lines
include/net/mac80211.h +1
-0@@ -474,6 +474,7 @@ enum ieee80211_if_types {IEEE80211_IF_TYPE_AP ,IEEE80211_IF_TYPE_STA ,IEEE80211_IF_TYPE_IBSS , + IEEE80211_IF_TYPE_MESH,What happened to Dan's suggestion of calling this
MESH_STA? And maybe in nl80211 as well? I might've missed something, was there a conclusion?
A mesh AP would have two interfaces, each with a different MAC address. One IF_TYPE_MESH, the other IF_TYPE_AP. Support for MAP, as you suggested, would be implemented in hostapd.
Javier
Johannes Berg
maintainerQuoted 4 lines
A mesh AP would have two interfaces, each with a different MAC address. One
IF_TYPE_MESH, the otherIF_TYPE_AP. Support for MAP, as you suggested, would be implemented in hostapd.
As far as I understand the specification, this is not required. Since we currently have no drivers supporting multi-MAC operation, this is quite a severe limitation and the draft seems to allow MAP operation with a single address, cf. the description of the SSID element in 7.2.3.1 (Beacon frame format). ("Note: the SSID is a required IE in beacon frames. To avoid having non-mesh STAs [...]")
Therefore, I think that having a separate MAP type device would be beneficial because that allows hostapd to generate a beacon including an SSID, respond to probe requests and still be a mesh point on the same interface. The only way hostapd would have to be aware of this is that it needs to create a different type of interface and include the mesh information in the beacon.
Do you see anything precluding such operation? Some more logic would have to be provided to achieve the appropriate mesh broad/multicast vs. AP broad/multicast behaviour, of course, as described elsewhere wrt. mesh broad/multicast frames being broad/multicast to associated STAs.
johannes
Quoted 15 lines · Johannes Berg
As far as I understand the specification, this
[different MAC address for the mesh interface] is not required. Since we currently have no drivers supporting multi-MAC operation, this is quite a severe limitation and the draft seems to allow MAP operation with a single address, cf. the description of the SSID element in 7.2.3.1 (Beacon frame format). ("Note: the SSID is a required IE in beacon frames. To avoid having non-mesh STAs [...]")Therefore, I think that having a separate MAP type device would be beneficial because that allows hostapd to generate a beacon including an SSID, respond to probe requests and still be a mesh point on the same interface. The only way hostapd would have to be aware of this is that it needs to create a different type of interface and include the mesh information in the beacon.
Quoted 4 lines
Do you see anything precluding such operation? Some more logic would have to be provided to achieve the appropriate mesh broad/multicast vs. AP broad/multicast behaviour, of course, as described elsewhere wrt. mesh broad/multicast frames being broad/multicast to associated STAs.
The issue of mesh beacons is an open discussion at TGs right now (and by now I mean this week, in the IEEE 802.11 plenary in Atlanta). It looks like a different mac address will be needed for the mesh interface if collocated with an AP. That will be necessary for security and to avoid conflicts with legacy equipment. In that case, the stack should generate the mesh beacons and hostapd generate the infrastructure beacons.
Anyway, I see no problem in renaming this IEEE80211_IF_TYPE_MESH_POINT (even though I just heard of a proposal to rename Mesh Points as Mesh Stations... )
Javier
Quoted 29 lines · Javier Cardona
Quoted 15 lines · Johannes Berg
As far as I understand the specification, this
[different MAC address for the mesh interface] is not required. Since we currently have no drivers supporting multi-MAC operation, this is quite a severe limitation and the draft seems to allow MAP operation with a single address, cf. the description of the SSID element in 7.2.3.1 (Beacon frame format). ("Note: the SSID is a required IE in beacon frames. To avoid having non-mesh STAs [...]")Therefore, I think that having a separate MAP type device would be beneficial because that allows hostapd to generate a beacon including an SSID, respond to probe requests and still be a mesh point on the same interface. The only way hostapd would have to be aware of this is that it needs to create a different type of interface and include the mesh information in the beacon.
Quoted 4 lines
Do you see anything precluding such operation? Some more logic would have to be provided to achieve the appropriate mesh broad/multicast vs. AP broad/multicast behaviour, of course, as described elsewhere wrt. mesh broad/multicast frames being broad/multicast to associated STAs.
The issue of mesh beacons is an open discussion at TGs right now (and by now I mean this week, in the IEEE 802.11 plenary in Atlanta). It looks like a different mac address will be needed for the mesh interface if collocated with an AP. That will be necessary for security and to avoid conflicts with legacy equipment. In that case, the stack should generate the mesh beacons and hostapd generate the infrastructure beacons.
Quoted 3 lines
Anyway, I see no problem in renaming this
IEEE80211_IF_TYPE_MESH_POINT(even though I just heard of a proposal to rename Mesh Points as Mesh Stations... )
How concrete is that? It could obviously be changed later but best to keep the code terminology consistent with the standards terminology unless the standards terminology is completely wack.
Dan
Hi Dan,
Quoted 5 lines
Quoted 3 lines
Anyway, I see no problem in renaming this
IEEE80211_IF_TYPE_MESH_POINT(even though I just heard of a proposal to rename Mesh Points as Mesh Stations... )How concrete is that?
Well ... I have plans to propose to change some terminology.
Quoted 3 lines
It could obviously be changed later but best to keep the code terminology consistent with the standards terminology unless the standards terminology is completely wack.
Please consider that 802.11s had tremendous changes since 2003. While the original PAR discussed meshing of APs only, the revised PAR is much broader and considers meshing of 802.11 devices in general.
Therefore, some of our old terminology doesn't really fit any longer. Furthermore, the adoption of 802.11 terms for single-hop case often confuses people when being used in the context of a mesh network. It's always painful when the 802.11s task group wastes time because people have different understanding of the words the use ...
Best regards,
Guido
Signature · 3 lines
Dipl.-Ing. Guido R. Hiertz | mailto:[email protected] Chair of Communication Networks | http://www.comnets.rwth-aachen.de/~grh RWTH Aachen University | Phone: +49 241 802 5829
Hi all,
2007-11-13 21:31 wrote Javier Cardona:
Quoted 3 lines · Johannes Berg
Quoted 2 lines
As far as I understand the specification, this [different MAC address for the mesh interface] is not required.
That's true. The current text doesn't require this. However, it'll change.
Quoted 5 lines
Quoted 5 lines
Since we currently have no drivers supporting multi-MAC operation, this is quite a severe limitation and the draft seems to allow MAP operation with a single address, cf. the description of the SSID element in 7.2.3.1 (Beacon frame format). ("Note: the SSID is a required IE in beacon frames. To avoid having non-mesh STAs [...]")
Yeah. It's still a mess. The best thing is to consider an MAP as two separate entities. One is an MP the other is an AP.
802.11-2007 describes the AP. There is nothing that 802.11s would add to that. 802.11s solely defines the MP. As a maximum, 802.11s might give some hints what to observe when an MP collocates with other entities (AP, HC ...).
We had an extensive discussion about the beacon stuff in 802.11s. As the group believes that the MP is a separate logic entity, it sends its own beacon. A combined beacon is not foreseen. However, until now the latest draft still has too much "legacy" (=non-mesh) and refers to BSS operation etc. Therefore, there are these nasty tricks (SSID = wildcard etc.). As soon as the group will require a separate MAC addresses when an MP collocates with an AP, they'll also realize that a lot of existing beacon IEs are unnecessary for the mesh. Then, there will also be no need for tricks to prevent stations from trying to associate with an MP.
Quoted 4 lines
Quoted 4 lines
Therefore, I think that having a separate MAP type device would be beneficial because that allows hostapd to generate a beacon including an SSID, respond to probe requests and still be a mesh point on the same interface.
During the discussion on the 802.11 e-mail reflector some people described such a combined beacon. However, this construct is not foreseen. It's really out of scope of 802.11s.
I know that there are existing products in the market that do similar things. However, 802.11s really decouples its concept of the mesh and the mesh devices from non-mesh devices. Thus, the mesh uses separate beacons.
Quoted 2 lines
Quoted 2 lines
The only way hostapd would have to be aware of this is that it
needs to create a different type of interface and include the mesh information in the beacon.
With separate beacon frames for the mesh and the BSS, the mesh may also use a totally different beacon interval. Thus, 802.11s networks can benefit from reduced overhead.
As there are already concerns about beacon bloat, I fear there will be no chance for a combined beacon that carries information for both the mesh and the BSS.
Quoted 5 lines
Quoted 4 lines
Do you see anything precluding such operation? Some more logic would have to be provided to achieve the appropriate mesh broad/multicast vs. AP broad/multicast behaviour, of course, as described elsewhere wrt. mesh broad/multicast frames being broad/multicast to associated STAs.
Quoted 7 lines
The issue of mesh beacons is an open discussion at TGs right now (and by now I mean this week, in the IEEE 802.11 plenary in Atlanta). It looks like a different mac address will be needed for the mesh interface if collocated with an AP. That will be necessary for security and to avoid conflicts with legacy equipment. In that case, the stack should generate the mesh beacons and hostapd generate the infrastructure beacons.
That's right. I support Javier's point of view. Both networks are very different. The BSS has a hierarchy of an AP and its associated stations. A mesh will always be distributed. Thus, beacon frames serve different purposes in both networks. I would propose to strictly decouple both functionality and to keep them separated.
Quoted 3 lines
Anyway, I see no problem in renaming this
IEEE80211_IF_TYPE_MESH_POINT(even though I just heard of a proposal to rename Mesh Points as Mesh Stations... )
Well ... That's another story :-)
Best regards,
Guido
Signature · 3 lines
Dipl.-Ing. Guido R. Hiertz | mailto:[email protected] Chair of Communication Networks | http://www.comnets.rwth-aachen.de/~grh RWTH Aachen University | Phone: +49 241 802 5829
Johannes Berg
maintainerJavier, Guido,
Thanks for the explanation. In that case, the current proposal makes sense and will simply require bridging between the AP and MP interfaces.
johannes
Quoted 10 lines · Johannes Berg
include/net/mac80211.h enum ieee80211_if_types { · line 477
Quoted 7 lines
include/net/mac80211.h +1
-0@@ -474,6 +474,7 @@ enum ieee80211_if_types {IEEE80211_IF_TYPE_AP ,IEEE80211_IF_TYPE_STA ,IEEE80211_IF_TYPE_IBSS , + IEEE80211_IF_TYPE_MESH,What happened to Dan's suggestion of calling this
MESH_STA? And maybe in nl80211 as well? I might've missed something, was there a conclusion?
There wasn't such suggestion, we were talking about renaming interface state from IEEE80211_MESH to something more specific. I suggested _ACTIVE, _ON or something like that... any preferences? As for the interface name, we have discussed about how MAP would be a different interface type, so it would be a good idea to be more precise with the it. I would go for MESH_POINT though, to follow the nomenclature in the standard.
Quoted 4 lines
Quoted 4 lines
include/net/mac80211.h +1
-1/* FIX: what would be proper limits for MTU? * This interface uses 802.3 frames. */ -if (new_mtu <256 || new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 ) { + if (new_mtu < 256 ||
Quoted 8 lines
include/net/mac80211.h
Quoted 4 lines
include/net/mac80211.h +1
-0+ new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) {printk (KERN_WARNING "%s: invalid MTU %d\n" , dev->name, new_mtu);return -EINVAL ;Are you sure this is appropriate? As the comment says, interface is 802.3 framed. Don't the 802.11 specifications usually keep the frame payload length and require the device to handle longer frames?
802.11s does not modify the PHY at all, and AFAIK does not impose any additional requirement on the devices. So regardless if the code already there was needed, it is necessary to decrease the MTU by meshhdrlen bytes. Another problem is that mesh headers do not always have the same length, but that will be dealt with when support for different length headers is added.
Quoted 4 lines
include/net/mac80211.h
Quoted 2 lines
include/net/mac80211.h +1
-0+atomic_t mesh_seqnum;Hmm. Do we really need an
atomic_there?
We are only using this from subif_start_xmit and it is a per-interface value, so no, not really.
Quoted 14 lines
include/net/mac80211.h
Quoted 10 lines
include/net/mac80211.h +9
-0+case IEEE80211_IF_TYPE_MESH : +if (!mesh_allocated) { +/* Allocate all mesh structures when creating the first +* mesh interface. +*/ +mesh_pathtbl_init (); + mesh_allocated =1 ; + } +/* fall thru */ Will there be other structures to allocate? Maybe we should instead push the "already" check into the
_init()?
Yes, there will be more soon.
Quoted 5 lines
include/net/mac80211.h
Quoted 3 lines
include/net/mac80211.h +3
-0+/* TODO: check for expired neighbors, paths and frames to non resolved +* hw addresses +*/ Seems dangerous to actually run the code w/o this, no?
No, right now we only add paths by manually from user space.
Quoted 9 lines
include/net/mac80211.h
Quoted 4 lines
include/net/mac80211.h +2
-0+ mgmt->u.beacon.beacon_int = +cpu_to_le16 (local->hw.conf.beacon_int);Hmm. This is interesting. The beacon interval is a pure beacon configuration after my patches, but here we're using it without having userspace set up a beacon. What do we do in the IBSS case?
Quoted 7 lines
include/net/mac80211.h
Quoted 5 lines
include/net/mac80211.h +5
-0+static int o80211s_getmeshpath (struct sk_buff *skb,struct nlmsghdr *nlh, +void *arg) +{ +return 0 ; +}Uh huh. Why is this here? Should it be filled?
Of course. Please note this is work in progress. I guess I should return a ENOTSUPP instead.
Quoted 11 lines
include/net/mac80211.h ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) · line 235
Quoted 6 lines
include/net/mac80211.h +2
-0@@ -230,6 +231,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))return TXRX_DROP ; +if (tx->sdata->type ==IEEE80211_IF_TYPE_MESH ) +return TXRX_CONTINUE ;Is this right or should there be some other "is forwarded frame" check to go with this? I'm not sure but it seems that frames we send via the netdev need to be still checked? Or not because they're just injected into the mesh? I think I'm confused.
I'm confused too. ieee80211_subif_start_xmit checks if the frame is forwarded, ieee80211_tx_h_check_assoc does not care about if the frame is forwarded or not. Since there is no interface-wide "association state" in mesh, the association check would always be true.
Quoted 4 lines
I think you should use RCU for the locking in the neighbour table. This code should (IIRC) be under rcu read-side lock already so the neighbour table reading would be lockless. Since updates are infrequent, RCU is a good tradeoff.
Updates are not that infrequent, every mesh path might be updated every few seconds (about 5 or 10). Would RCU be a good trade off in this situation?
Thanks for the comments!
Signature · 2 lines
Luis Carlos Cobo Rus GnuPG ID: 44019B60 cozybit Inc.
Johannes Berg
maintainerQuoted 8 lines
There wasn't such suggestion, we were talking about renaming interface state from
IEEE80211_MESHto something more specific. I suggested_ACTIVE,_ONor something like that... any preferences? As for the interface name, we have discussed about how MAP would be a different interface type, so it would be a good idea to be more precise with the it. I would go forMESH_POINTthough, to follow the nomenclature in the standard.
Hah, ok, I misunderstood the thread then. Sorry. MESH_POINT does sound better than just MESH though.
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
net/mac80211/ieee80211.c +1
-1/* FIX: what would be proper limits for MTU? * This interface uses 802.3 frames. */ -if (new_mtu <256 || new_mtu >IEEE80211_MAX_DATA_LEN -24 -6 ) { + if (new_mtu < 256 ||Quoted 8 lines
net/mac80211/ieee80211.c static void ieee80211_master_set_multicast_list(struct net_device *dev) · line 141
Quoted 4 lines
net/mac80211/ieee80211.c +1
-0+ new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) {printk (KERN_WARNING "%s: invalid MTU %d\n" , dev->name, new_mtu);return -EINVAL ;Are you sure this is appropriate? As the comment says, interface is 802.3 framed. Don't the 802.11 specifications usually keep the frame payload length and require the device to handle longer frames?
Quoted 6 lines
802.11s does not modify the PHY at all, and AFAIK does not impose any additional requirement on the devices. So regardless if the code already there was needed, it is necessary to decrease the MTU by meshhdrlen bytes. Another problem is that mesh headers do not always have the same length, but that will be dealt with when support for different length headers is added.
Ok, thanks for the explanation.
Quoted 7 lines
Quoted 5 lines
net/mac80211/ieee80211_sta.c static void ieee80211_associate(struct net_device *dev, · line 768
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+/* TODO: check for expired neighbors, paths and frames to non resolved +* hw addresses +*/ Seems dangerous to actually run the code w/o this, no?
No, right now we only add paths by manually from user space.
Oh ok. Never bothered to read that long part of the draft copy I have :)
Quoted 10 lines
Quoted 7 lines
net/mac80211/mesh_pathtbl.c line 106
Quoted 5 lines
net/mac80211/mesh_pathtbl.c new file +5
-0+static int o80211s_getmeshpath (struct sk_buff *skb,struct nlmsghdr *nlh, +void *arg) +{ +return 0 ; +}Uh huh. Why is this here? Should it be filled?
Of course. Please note this is work in progress. I guess I should return a ENOTSUPP instead.
That'd indeed be better.
Quoted 12 lines
Quoted 11 lines
net/mac80211/tx.c ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) · line 235
Quoted 6 lines
net/mac80211/tx.c +2
-0@@ -230,6 +231,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))return TXRX_DROP ; +if (tx->sdata->type ==IEEE80211_IF_TYPE_MESH ) +return TXRX_CONTINUE ;Is this right or should there be some other "is forwarded frame" check to go with this? I'm not sure but it seems that frames we send via the netdev need to be still checked? Or not because they're just injected into the mesh? I think I'm confused.
Quoted 4 lines
I'm confused too.
ieee80211_subif_start_xmitchecks if the frame is forwarded,ieee80211_tx_h_check_assocdoes not care about if the frame is forwarded or not. Since there is no interface-wide "association state" in mesh, the association check would always be true.
Ok.
Quoted 8 lines
Quoted 4 lines
I think you should use RCU for the locking in the neighbour table. This code should (IIRC) be under rcu read-side lock already so the neighbour table reading would be lockless. Since updates are infrequent, RCU is a good tradeoff.
Updates are not that infrequent, every mesh path might be updated every few seconds (about 5 or 10). Would RCU be a good trade off in this situation?
I think so, yes. After all, a few seconds is nothing compared to how many frames could be going through (many per second). In fact, the path update might lock out the tx/rx paths for quite a while which is highly undesirable.
johannes
Johannes Berg
maintainerQuoted 3 lines · Luis Carlos Cobo
This commit introduces mesh interface support for the mac80211 stack. It provides support for pre-802.11s frame format, static unicast forwarding, mesh beaconing, mesh statistics through debugfs.
Btw. I just reviewed draft 1.0 (currently have no access to later ones) and it talks a lot about probe responses but never when to send them. Is this clarified later and should it be implemented here? Or is that part of the "mesh AP" stuff that is removed?
johannes
Quoted 4 lines · Johannes Berg
Btw. I just reviewed draft 1.0 (currently have no access to later ones) and it talks a lot about probe responses but never when to send them. Is this clarified later and should it be implemented here? Or is that part of the "mesh AP" stuff that is removed?
Probe responses are sent as usual (in response of a probe request :-) ) Either beacons or probes request/responses are needed to detect neighbors and then start the peer link establishment protocol. So yes, probe responses should and will be implemented, even though it would possible to operate just with beacons.
Signature · 2 lines
Luis Carlos Cobo Rus GnuPG ID: 44019B60 cozybit Inc.