diff options
author | Joel A Fernandes <agnel.joel@gmail.com> | 2010-12-28 20:28:11 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-04 14:43:01 -0500 |
commit | f76b57b47e5fd423f9827c7b0ba7bbd06cca6b9b (patch) | |
tree | 8ff2b50bb0e57611f5d37fe6abaef75f9fcd34a6 /net | |
parent | 1c30cc19081c16b1fe73ac13f2cb2abc009cdcc4 (diff) |
mac80211: Fix mesh portal communication with other mesh nodes.
Fixed a bug where if a mesh interface has a different MAC address from its bridge
interface, then it would not be able to send data traffic to any other mesh node.
This also adds support for communication between mesh nodes and external bridged
nodes by using a 6 address format if the source is a node within the mesh and the
destination is an external node proxied by a mesh portal.
Signed-off-by: Joel A Fernandes <agnel.joel@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/tx.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d2b4b67a7b53..11d013590166 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1747,6 +1747,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1747 | __le16 fc; | 1747 | __le16 fc; |
1748 | struct ieee80211_hdr hdr; | 1748 | struct ieee80211_hdr hdr; |
1749 | struct ieee80211s_hdr mesh_hdr __maybe_unused; | 1749 | struct ieee80211s_hdr mesh_hdr __maybe_unused; |
1750 | struct mesh_path *mppath = NULL; | ||
1750 | const u8 *encaps_data; | 1751 | const u8 *encaps_data; |
1751 | int encaps_len, skip_header_bytes; | 1752 | int encaps_len, skip_header_bytes; |
1752 | int nh_pos, h_pos; | 1753 | int nh_pos, h_pos; |
@@ -1807,16 +1808,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1807 | ret = NETDEV_TX_OK; | 1808 | ret = NETDEV_TX_OK; |
1808 | goto fail; | 1809 | goto fail; |
1809 | } | 1810 | } |
1811 | if (!is_multicast_ether_addr(skb->data)) | ||
1812 | mppath = mpp_path_lookup(skb->data, sdata); | ||
1810 | 1813 | ||
1814 | /* | ||
1815 | * Do not use address extension, if it is a packet from | ||
1816 | * the same interface and the destination is not being | ||
1817 | * proxied by any other mest point. | ||
1818 | */ | ||
1811 | if (compare_ether_addr(sdata->vif.addr, | 1819 | if (compare_ether_addr(sdata->vif.addr, |
1812 | skb->data + ETH_ALEN) == 0) { | 1820 | skb->data + ETH_ALEN) == 0 && |
1821 | (!mppath || !compare_ether_addr(mppath->mpp, skb->data))) { | ||
1813 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1822 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1814 | skb->data, skb->data + ETH_ALEN); | 1823 | skb->data, skb->data + ETH_ALEN); |
1815 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, | 1824 | meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, |
1816 | sdata, NULL, NULL); | 1825 | sdata, NULL, NULL); |
1817 | } else { | 1826 | } else { |
1818 | /* packet from other interface */ | 1827 | /* packet from other interface */ |
1819 | struct mesh_path *mppath; | ||
1820 | int is_mesh_mcast = 1; | 1828 | int is_mesh_mcast = 1; |
1821 | const u8 *mesh_da; | 1829 | const u8 *mesh_da; |
1822 | 1830 | ||
@@ -1827,8 +1835,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1827 | else { | 1835 | else { |
1828 | static const u8 bcast[ETH_ALEN] = | 1836 | static const u8 bcast[ETH_ALEN] = |
1829 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 1837 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
1830 | |||
1831 | mppath = mpp_path_lookup(skb->data, sdata); | ||
1832 | if (mppath) { | 1838 | if (mppath) { |
1833 | /* RA TA mDA mSA AE:DA SA */ | 1839 | /* RA TA mDA mSA AE:DA SA */ |
1834 | mesh_da = mppath->mpp; | 1840 | mesh_da = mppath->mpp; |