aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mesh.c')
-rw-r--r--net/mac80211/mesh.c88
1 files changed, 39 insertions, 49 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c8a4f19ed13b..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -124,15 +124,6 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata); 124 ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
125} 125}
126 126
127void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
128{
129 sta->mesh_pp_id = 0; /* HWMP */
130 sta->mesh_pm_id = 0; /* Airtime */
131 sta->mesh_cc_id = 0; /* Disabled */
132 sta->mesh_sp_id = 0; /* Neighbor Offset */
133 sta->mesh_auth_id = 0; /* Disabled */
134}
135
136int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 127int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
137{ 128{
138 int i; 129 int i;
@@ -287,6 +278,13 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
287 *pos++ |= sdata->u.mesh.accepting_plinks ? 278 *pos++ |= sdata->u.mesh.accepting_plinks ?
288 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00; 279 MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
289 *pos++ = 0x00; 280 *pos++ = 0x00;
281
282 if (sdata->u.mesh.vendor_ie) {
283 int len = sdata->u.mesh.vendor_ie_len;
284 const u8 *data = sdata->u.mesh.vendor_ie;
285 if (skb_tailroom(skb) > len)
286 memcpy(skb_put(skb, len), data, len);
287 }
290} 288}
291 289
292u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) 290u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
@@ -412,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
412 * ieee80211_new_mesh_header - create a new mesh header 410 * ieee80211_new_mesh_header - create a new mesh header
413 * @meshhdr: uninitialized mesh header 411 * @meshhdr: uninitialized mesh header
414 * @sdata: mesh interface to be used 412 * @sdata: mesh interface to be used
415 * @addr4: addr4 of the mesh frame (1st in ae header) 413 * @addr4or5: 1st address in the ae header, which may correspond to address 4
416 * may be NULL 414 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
417 * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) 415 * be NULL.
418 * may be NULL unless addr6 is present 416 * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
419 * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) 417 * mesh frame
420 * may be NULL unless addr5 is present
421 * 418 *
422 * Return the header length. 419 * Return the header length.
423 */ 420 */
424int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 421int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
425 struct ieee80211_sub_if_data *sdata, char *addr4, 422 struct ieee80211_sub_if_data *sdata, char *addr4or5,
426 char *addr5, char *addr6) 423 char *addr6)
427{ 424{
428 int aelen = 0; 425 int aelen = 0;
426 BUG_ON(!addr4or5 && addr6);
429 memset(meshhdr, 0, sizeof(*meshhdr)); 427 memset(meshhdr, 0, sizeof(*meshhdr));
430 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
431 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 429 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
432 sdata->u.mesh.mesh_seqnum++; 430 sdata->u.mesh.mesh_seqnum++;
433 if (addr4) { 431 if (addr4or5 && !addr6) {
434 meshhdr->flags |= MESH_FLAGS_AE_A4; 432 meshhdr->flags |= MESH_FLAGS_AE_A4;
435 aelen += ETH_ALEN; 433 aelen += ETH_ALEN;
436 memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); 434 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
437 } 435 } else if (addr4or5 && addr6) {
438 if (addr5 && addr6) {
439 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 436 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
440 aelen += 2 * ETH_ALEN; 437 aelen += 2 * ETH_ALEN;
441 if (!addr4) { 438 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
442 memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); 439 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
443 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
444 } else {
445 memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
446 memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
447 }
448 } 440 }
449 return 6 + aelen; 441 return 6 + aelen;
450} 442}
@@ -513,6 +505,14 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
513 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 505 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
514 struct ieee80211_local *local = sdata->local; 506 struct ieee80211_local *local = sdata->local;
515 507
508 local->fif_other_bss++;
509 /* mesh ifaces must set allmulti to forward mcast traffic */
510 atomic_inc(&local->iff_allmultis);
511 ieee80211_configure_filter(local);
512
513 ifmsh->mesh_cc_id = 0; /* Disabled */
514 ifmsh->mesh_sp_id = 0; /* Neighbor Offset */
515 ifmsh->mesh_auth_id = 0; /* Disabled */
516 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 516 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
517 ieee80211_mesh_root_setup(ifmsh); 517 ieee80211_mesh_root_setup(ifmsh);
518 ieee80211_queue_work(&local->hw, &sdata->work); 518 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -524,6 +524,13 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
524 524
525void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) 525void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
526{ 526{
527 struct ieee80211_local *local = sdata->local;
528 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
529
530 ifmsh->mesh_id_len = 0;
531 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
532 sta_info_flush(local, NULL);
533
527 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 534 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
528 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 535 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
529 /* 536 /*
@@ -534,6 +541,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
534 * it no longer is. 541 * it no longer is.
535 */ 542 */
536 cancel_work_sync(&sdata->work); 543 cancel_work_sync(&sdata->work);
544
545 local->fif_other_bss--;
546 atomic_dec(&local->iff_allmultis);
547 ieee80211_configure_filter(local);
537} 548}
538 549
539static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, 550static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
@@ -663,26 +674,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
663 ieee80211_mesh_housekeeping_timer, 674 ieee80211_mesh_housekeeping_timer,
664 (unsigned long) sdata); 675 (unsigned long) sdata);
665 676
666 ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T;
667 ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T;
668 ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T;
669 ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR;
670 ifmsh->mshcfg.dot11MeshTTL = MESH_TTL;
671 ifmsh->mshcfg.auto_open_plinks = true;
672 ifmsh->mshcfg.dot11MeshMaxPeerLinks =
673 MESH_MAX_ESTAB_PLINKS;
674 ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout =
675 MESH_PATH_TIMEOUT;
676 ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval =
677 MESH_PREQ_MIN_INT;
678 ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime =
679 MESH_DIAM_TRAVERSAL_TIME;
680 ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries =
681 MESH_MAX_PREQ_RETRIES;
682 ifmsh->mshcfg.path_refresh_time =
683 MESH_PATH_REFRESH_TIME;
684 ifmsh->mshcfg.min_discovery_timeout =
685 MESH_MIN_DISCOVERY_TIMEOUT;
686 ifmsh->accepting_plinks = true; 677 ifmsh->accepting_plinks = true;
687 ifmsh->preq_id = 0; 678 ifmsh->preq_id = 0;
688 ifmsh->sn = 0; 679 ifmsh->sn = 0;
@@ -692,7 +683,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
692 /* Allocate all mesh structures when creating the first mesh interface. */ 683 /* Allocate all mesh structures when creating the first mesh interface. */
693 if (!mesh_allocated) 684 if (!mesh_allocated)
694 ieee80211s_init(); 685 ieee80211s_init();
695 mesh_ids_set_default(ifmsh);
696 setup_timer(&ifmsh->mesh_path_timer, 686 setup_timer(&ifmsh->mesh_path_timer,
697 ieee80211_mesh_path_timer, 687 ieee80211_mesh_path_timer,
698 (unsigned long) sdata); 688 (unsigned long) sdata);