mac80211: fix DS to MBSS address translation
The destination address of unicast frames forwarded through a mesh gate was being replaced with the broadcast address. Instead leave the original destination address as the mesh DA. If the nexthop address is not in the mpath table it will be resolved. If that fails, the frame will be forwarded to known mesh gates. Reported-by: Cedric Voncken <cedric.voncken@acksys.fr> Signed-off-by: Thomas Pedersen <thomas@cozybit.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
899852af60
commit
27f011243a
|
@ -1811,37 +1811,31 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||||
meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
|
meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
|
||||||
sdata, NULL, NULL);
|
sdata, NULL, NULL);
|
||||||
} else {
|
} else {
|
||||||
int is_mesh_mcast = 1;
|
/* DS -> MBSS (802.11-2012 13.11.3.3).
|
||||||
const u8 *mesh_da;
|
* For unicast with unknown forwarding information,
|
||||||
|
* destination might be in the MBSS or if that fails
|
||||||
|
* forwarded to another mesh gate. In either case
|
||||||
|
* resolution will be handled in ieee80211_xmit(), so
|
||||||
|
* leave the original DA. This also works for mcast */
|
||||||
|
const u8 *mesh_da = skb->data;
|
||||||
|
|
||||||
|
if (mppath)
|
||||||
|
mesh_da = mppath->mpp;
|
||||||
|
else if (mpath)
|
||||||
|
mesh_da = mpath->dst;
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (is_multicast_ether_addr(skb->data))
|
|
||||||
/* DA TA mSA AE:SA */
|
|
||||||
mesh_da = skb->data;
|
|
||||||
else {
|
|
||||||
static const u8 bcast[ETH_ALEN] =
|
|
||||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
|
||||||
if (mppath) {
|
|
||||||
/* RA TA mDA mSA AE:DA SA */
|
|
||||||
mesh_da = mppath->mpp;
|
|
||||||
is_mesh_mcast = 0;
|
|
||||||
} else if (mpath) {
|
|
||||||
mesh_da = mpath->dst;
|
|
||||||
is_mesh_mcast = 0;
|
|
||||||
} else {
|
|
||||||
/* DA TA mSA AE:SA */
|
|
||||||
mesh_da = bcast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
|
hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
|
||||||
mesh_da, sdata->vif.addr);
|
mesh_da, sdata->vif.addr);
|
||||||
rcu_read_unlock();
|
if (is_multicast_ether_addr(mesh_da))
|
||||||
if (is_mesh_mcast)
|
/* DA TA mSA AE:SA */
|
||||||
meshhdrlen =
|
meshhdrlen =
|
||||||
ieee80211_new_mesh_header(&mesh_hdr,
|
ieee80211_new_mesh_header(&mesh_hdr,
|
||||||
sdata,
|
sdata,
|
||||||
skb->data + ETH_ALEN,
|
skb->data + ETH_ALEN,
|
||||||
NULL);
|
NULL);
|
||||||
else
|
else
|
||||||
|
/* RA TA mDA mSA AE:DA SA */
|
||||||
meshhdrlen =
|
meshhdrlen =
|
||||||
ieee80211_new_mesh_header(&mesh_hdr,
|
ieee80211_new_mesh_header(&mesh_hdr,
|
||||||
sdata,
|
sdata,
|
||||||
|
|
Loading…
Reference in New Issue