Loading net/mac80211/rx.c +39 −49 Original line number Original line Diff line number Diff line Loading @@ -1892,15 +1892,16 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) static ieee80211_rx_result static ieee80211_rx_result ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) { { struct ieee80211_hdr *hdr; struct ieee80211_hdr *fwd_hdr, *hdr; struct ieee80211_tx_info *info; struct ieee80211s_hdr *mesh_hdr; struct ieee80211s_hdr *mesh_hdr; unsigned int hdrlen; struct sk_buff *skb = rx->skb, *fwd_skb; struct sk_buff *skb = rx->skb, *fwd_skb; struct ieee80211_local *local = rx->local; struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD); __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD); u16 q; u16 q, hdrlen; hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); hdrlen = ieee80211_hdrlen(hdr->frame_control); Loading @@ -1916,7 +1917,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) return RX_CONTINUE; return RX_CONTINUE; if (!mesh_hdr->ttl) if (!mesh_hdr->ttl) /* illegal frame */ return RX_DROP_MONITOR; return RX_DROP_MONITOR; if (mesh_hdr->flags & MESH_FLAGS_AE) { if (mesh_hdr->flags & MESH_FLAGS_AE) { Loading Loading @@ -1952,28 +1952,26 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) q = ieee80211_select_queue_80211(local, skb, hdr); q = ieee80211_select_queue_80211(local, skb, hdr); if (ieee80211_queue_stopped(&local->hw, q)) { if (ieee80211_queue_stopped(&local->hw, q)) { IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); dropped_frames_congestion); return RX_DROP_MONITOR; return RX_DROP_MONITOR; } } skb_set_queue_mapping(skb, q); skb_set_queue_mapping(skb, q); mesh_hdr->ttl--; if (status->rx_flags & IEEE80211_RX_RA_MATCH) { if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) if (!mesh_hdr->ttl) goto out; IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, dropped_frames_ttl); else { struct ieee80211_hdr *fwd_hdr; struct ieee80211_tx_info *info; fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); return RX_DROP_MONITOR; } if (!fwd_skb && net_ratelimit()) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { if (net_ratelimit()) printk(KERN_DEBUG "%s: failed to clone mesh frame\n", printk(KERN_DEBUG "%s: failed to clone mesh frame\n", sdata->name); sdata->name); if (!fwd_skb) goto out; goto out; } fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; info = IEEE80211_SKB_CB(fwd_skb); info = IEEE80211_SKB_CB(fwd_skb); Loading @@ -1982,28 +1980,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) info->control.vif = &rx->sdata->vif; info->control.vif = &rx->sdata->vif; info->control.jiffies = jiffies; info->control.jiffies = jiffies; if (is_multicast_ether_addr(fwd_hdr->addr1)) { if (is_multicast_ether_addr(fwd_hdr->addr1)) { IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); fwded_mcast); memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); } else if (!mesh_nexthop_lookup(fwd_skb, sdata)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); } else { } else { if (mesh_nexthop_lookup(fwd_skb, sdata)) { /* unable to resolve next hop */ /* can't resolve next hop, send a PERR */ mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 0, reason, fwd_hdr->addr2, sdata); fwd_hdr->addr3, 0, reason, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); fwd_hdr->addr2, sdata); sdata->u.mesh.mshstats.dropped_frames_no_route++; return RX_DROP_MONITOR; return RX_DROP_MONITOR; } } IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); fwded_unicast); } IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, fwded_frames); ieee80211_add_pending_skb(local, fwd_skb); ieee80211_add_pending_skb(local, fwd_skb); } } out: out: if (is_multicast_ether_addr(hdr->addr1) || if (is_multicast_ether_addr(hdr->addr1) || sdata->dev->flags & IFF_PROMISC) sdata->dev->flags & IFF_PROMISC) Loading Loading
net/mac80211/rx.c +39 −49 Original line number Original line Diff line number Diff line Loading @@ -1892,15 +1892,16 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) static ieee80211_rx_result static ieee80211_rx_result ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) { { struct ieee80211_hdr *hdr; struct ieee80211_hdr *fwd_hdr, *hdr; struct ieee80211_tx_info *info; struct ieee80211s_hdr *mesh_hdr; struct ieee80211s_hdr *mesh_hdr; unsigned int hdrlen; struct sk_buff *skb = rx->skb, *fwd_skb; struct sk_buff *skb = rx->skb, *fwd_skb; struct ieee80211_local *local = rx->local; struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD); __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD); u16 q; u16 q, hdrlen; hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); hdrlen = ieee80211_hdrlen(hdr->frame_control); Loading @@ -1916,7 +1917,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) return RX_CONTINUE; return RX_CONTINUE; if (!mesh_hdr->ttl) if (!mesh_hdr->ttl) /* illegal frame */ return RX_DROP_MONITOR; return RX_DROP_MONITOR; if (mesh_hdr->flags & MESH_FLAGS_AE) { if (mesh_hdr->flags & MESH_FLAGS_AE) { Loading Loading @@ -1952,28 +1952,26 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) q = ieee80211_select_queue_80211(local, skb, hdr); q = ieee80211_select_queue_80211(local, skb, hdr); if (ieee80211_queue_stopped(&local->hw, q)) { if (ieee80211_queue_stopped(&local->hw, q)) { IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); dropped_frames_congestion); return RX_DROP_MONITOR; return RX_DROP_MONITOR; } } skb_set_queue_mapping(skb, q); skb_set_queue_mapping(skb, q); mesh_hdr->ttl--; if (status->rx_flags & IEEE80211_RX_RA_MATCH) { if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) if (!mesh_hdr->ttl) goto out; IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, dropped_frames_ttl); else { struct ieee80211_hdr *fwd_hdr; struct ieee80211_tx_info *info; fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); return RX_DROP_MONITOR; } if (!fwd_skb && net_ratelimit()) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { if (net_ratelimit()) printk(KERN_DEBUG "%s: failed to clone mesh frame\n", printk(KERN_DEBUG "%s: failed to clone mesh frame\n", sdata->name); sdata->name); if (!fwd_skb) goto out; goto out; } fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; info = IEEE80211_SKB_CB(fwd_skb); info = IEEE80211_SKB_CB(fwd_skb); Loading @@ -1982,28 +1980,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) info->control.vif = &rx->sdata->vif; info->control.vif = &rx->sdata->vif; info->control.jiffies = jiffies; info->control.jiffies = jiffies; if (is_multicast_ether_addr(fwd_hdr->addr1)) { if (is_multicast_ether_addr(fwd_hdr->addr1)) { IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); fwded_mcast); memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); } else if (!mesh_nexthop_lookup(fwd_skb, sdata)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); } else { } else { if (mesh_nexthop_lookup(fwd_skb, sdata)) { /* unable to resolve next hop */ /* can't resolve next hop, send a PERR */ mesh_path_error_tx(ifmsh->mshcfg.element_ttl, fwd_hdr->addr3, mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, 0, reason, fwd_hdr->addr2, sdata); fwd_hdr->addr3, 0, reason, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); fwd_hdr->addr2, sdata); sdata->u.mesh.mshstats.dropped_frames_no_route++; return RX_DROP_MONITOR; return RX_DROP_MONITOR; } } IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); fwded_unicast); } IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, fwded_frames); ieee80211_add_pending_skb(local, fwd_skb); ieee80211_add_pending_skb(local, fwd_skb); } } out: out: if (is_multicast_ether_addr(hdr->addr1) || if (is_multicast_ether_addr(hdr->addr1) || sdata->dev->flags & IFF_PROMISC) sdata->dev->flags & IFF_PROMISC) Loading