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.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8b5906c83f93..ca3af4685b0a 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -410,39 +410,33 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
410 * ieee80211_new_mesh_header - create a new mesh header 410 * ieee80211_new_mesh_header - create a new mesh header
411 * @meshhdr: uninitialized mesh header 411 * @meshhdr: uninitialized mesh header
412 * @sdata: mesh interface to be used 412 * @sdata: mesh interface to be used
413 * @addr4: addr4 of the mesh frame (1st in ae header) 413 * @addr4or5: 1st address in the ae header, which may correspond to address 4
414 * may be NULL 414 * (if addr6 is NULL) or address 5 (if addr6 is present). It may
415 * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) 415 * be NULL.
416 * may be NULL unless addr6 is present 416 * @addr6: 2nd address in the ae header, which corresponds to addr6 of the
417 * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) 417 * mesh frame
418 * may be NULL unless addr5 is present
419 * 418 *
420 * Return the header length. 419 * Return the header length.
421 */ 420 */
422int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 421int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
423 struct ieee80211_sub_if_data *sdata, char *addr4, 422 struct ieee80211_sub_if_data *sdata, char *addr4or5,
424 char *addr5, char *addr6) 423 char *addr6)
425{ 424{
426 int aelen = 0; 425 int aelen = 0;
426 BUG_ON(!addr4or5 && addr6);
427 memset(meshhdr, 0, sizeof(*meshhdr)); 427 memset(meshhdr, 0, sizeof(*meshhdr));
428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 428 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
429 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);
430 sdata->u.mesh.mesh_seqnum++; 430 sdata->u.mesh.mesh_seqnum++;
431 if (addr4) { 431 if (addr4or5 && !addr6) {
432 meshhdr->flags |= MESH_FLAGS_AE_A4; 432 meshhdr->flags |= MESH_FLAGS_AE_A4;
433 aelen += ETH_ALEN; 433 aelen += ETH_ALEN;
434 memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); 434 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
435 } 435 } else if (addr4or5 && addr6) {
436 if (addr5 && addr6) {
437 meshhdr->flags |= MESH_FLAGS_AE_A5_A6; 436 meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
438 aelen += 2 * ETH_ALEN; 437 aelen += 2 * ETH_ALEN;
439 if (!addr4) { 438 memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN);
440 memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); 439 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
441 memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
442 } else {
443 memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
444 memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
445 }
446 } 440 }
447 return 6 + aelen; 441 return 6 + aelen;
448} 442}