[SK_BUFF]: Convert skb->tail to sk_buff_data_t
[linux-block.git] / net / ieee80211 / ieee80211_rx.c
index d9265195656da0c97aa6a8c3ac938e22cb992731..2b854941e06c5d1d5b079034f1d6975352efb017 100644 (file)
@@ -42,7 +42,7 @@ static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
        u16 fc = le16_to_cpu(hdr->frame_ctl);
 
        skb->dev = ieee->dev;
-       skb->mac.raw = skb->data;
+       skb_reset_mac_header(skb);
        skb_pull(skb, ieee80211_get_hdrlen(fc));
        skb->pkt_type = PACKET_OTHERHOST;
        skb->protocol = __constant_htons(ETH_P_80211_RAW);
@@ -478,6 +478,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                        goto rx_exit;
        }
 #endif
+       /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
+       if (sc == ieee->prev_seq_ctl)
+               goto rx_dropped;
+       else
+               ieee->prev_seq_ctl = sc;
 
        /* Data frame - extract src/dst addresses */
        if (skb->len < IEEE80211_3ADDR_LEN)
@@ -590,7 +595,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                if (frag != 0)
                        flen -= hdrlen;
 
-               if (frag_skb->tail + flen > frag_skb->end) {
+               if (skb_tail_pointer(frag_skb) + flen > frag_skb->end) {
                        printk(KERN_WARNING "%s: host decrypted and "
                               "reassembled frame did not fit skb\n",
                               dev->name);
@@ -658,7 +663,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
         * any security data (IV, ICV, etc) that was left behind */
        if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
            ieee->host_strip_iv_icv) {
-               int trimlen = 0;
+               int trimlen = 0;
 
                /* Top two-bits of byte 3 are the key index */
                if (skb->len >= hdrlen + 3)
@@ -784,10 +789,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
        if (skb2 != NULL) {
                /* send to wireless media */
-               skb2->protocol = __constant_htons(ETH_P_802_3);
-               skb2->mac.raw = skb2->nh.raw = skb2->data;
-               /* skb2->nh.raw = skb2->data + ETH_HLEN; */
                skb2->dev = dev;
+               skb2->protocol = __constant_htons(ETH_P_802_3);
+               skb_reset_mac_header(skb2);
+               skb_reset_network_header(skb2);
+               /* skb2->network_header += ETH_HLEN; */
                dev_queue_xmit(skb2);
        }
 #endif
@@ -795,7 +801,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (skb) {
                skb->protocol = eth_type_trans(skb, dev);
                memset(skb->cb, 0, sizeof(skb->cb));
-               skb->dev = dev;
                skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
                if (netif_rx(skb) == NET_RX_DROP) {
                        /* netif_rx always succeeds, but it might drop
@@ -847,7 +852,7 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
 
        if ((fc & IEEE80211_FCTL_VERS) != 0)
                goto drop_free;
-               
+
        switch (fc & IEEE80211_FCTL_FTYPE) {
        case IEEE80211_FTYPE_MGMT:
                if (skb->len < sizeof(struct ieee80211_hdr_3addr))
@@ -1299,12 +1304,11 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
                case MFIE_TYPE_IBSS_DFS:
                        if (network->ibss_dfs)
                                break;
-                       network->ibss_dfs =
-                           kmalloc(info_element->len, GFP_ATOMIC);
+                       network->ibss_dfs = kmemdup(info_element->data,
+                                                   info_element->len,
+                                                   GFP_ATOMIC);
                        if (!network->ibss_dfs)
                                return 1;
-                       memcpy(network->ibss_dfs, info_element->data,
-                              info_element->len);
                        network->flags |= NETWORK_HAS_IBSS_DFS;
                        break;
 
@@ -1485,7 +1489,7 @@ static void update_network(struct ieee80211_network *dst,
 
        /* We only update the statistics if they were created by receiving
         * the network information on the actual channel the network is on.
-        * 
+        *
         * This keeps beacons received on neighbor channels from bringing
         * down the signal level of an AP. */
        if (dst->channel == src->stats.received_channel)