Search Linux Wireless

Re: Broken fragmentation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jun 19, 2008 at 2:46 PM, Tomas Winkler <tomasw@xxxxxxxxx> wrote:
> On Thu, Jun 19, 2008 at 12:56 PM, Johannes Berg
> <johannes@xxxxxxxxxxxxxxxx> wrote:
>> On Thu, 2008-06-19 at 12:20 +0300, Tomas Winkler wrote:
>>> Johannes
>>> Your patch bellow has broken the fragmentation. Can you please have a
>>> look at this.
>>
>>>           /* Setup duration field for the first fragment of the frame. Duration
>>>        * for remaining fragments will be updated when they are being sent
>>>        * to low-level driver in ieee80211_tx(). */
>>>       dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
>>>                                (tx->flags & IEEE80211_TX_FRAGMENTED) ?
>>>                                tx->extra_frag[0]->len : 0);                                 --
>>> NULL pointer
>>
>> Oops, you're right, I missed the part where it accesses the fragments,
>> the bulk of the function does txinfo updates which I didn't want to
>> apply to all fragments.
>>
>> There is another bug too, this must come after encryption since
>> encryption can add to the length of the frame. What do you think about
>> the patch below? Untested so far because I have to go and wanted to get
>> it out to you.
>>
>
> Now it crashes in the driver...maybe the txinfo to cb changes. Looking into it.
> Tomas
Looks like this is the second part keyconf is null
Tomas

>>
>> ---
>>  net/mac80211/tx.c |   66 ++++++++++++++++++++++++++++--------------------------
>>  1 file changed, 35 insertions(+), 31 deletions(-)
>>
>> --- everything.orig/net/mac80211/tx.c   2008-06-19 11:25:12.000000000 +0200
>> +++ everything/net/mac80211/tx.c        2008-06-19 11:53:08.000000000 +0200
>> @@ -87,8 +87,8 @@ static inline void ieee80211_dump_frame(
>>  }
>>  #endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */
>>
>> -static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
>> -                             int next_frag_len)
>> +static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
>> +                                int next_frag_len)
>>  {
>>        int rate, mrate, erp, dur, i;
>>        struct ieee80211_rate *txrate;
>> @@ -140,7 +140,7 @@ static u16 ieee80211_duration(struct iee
>>
>>        /* data/mgmt */
>>        if (0 /* FIX: data/mgmt during CFP */)
>> -               return 32768;
>> +               return cpu_to_le16(32768);
>>
>>        if (group_addr) /* Group address as the destination - no ACK */
>>                return 0;
>> @@ -210,7 +210,7 @@ static u16 ieee80211_duration(struct iee
>>                                tx->sdata->bss_conf.use_short_preamble);
>>        }
>>
>> -       return dur;
>> +       return cpu_to_le16(dur);
>>  }
>>
>>  static int inline is_ieee80211_device(struct net_device *dev,
>> @@ -544,7 +544,6 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
>>  {
>>        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
>>        u16 fc = le16_to_cpu(hdr->frame_control);
>> -       u16 dur;
>>        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
>>        struct ieee80211_supported_band *sband;
>>
>> @@ -602,14 +601,6 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
>>                info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
>>        }
>>
>> -       /* Setup duration field for the first fragment of the frame. Duration
>> -        * for remaining fragments will be updated when they are being sent
>> -        * to low-level driver in ieee80211_tx(). */
>> -       dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
>> -                                (tx->flags & IEEE80211_TX_FRAGMENTED) ?
>> -                                tx->extra_frag[0]->len : 0);
>> -       hdr->duration_id = cpu_to_le16(dur);
>> -
>>        if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
>>            (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
>>                struct ieee80211_rate *rate;
>> @@ -755,6 +746,36 @@ ieee80211_tx_h_encrypt(struct ieee80211_
>>  }
>>
>>  static ieee80211_tx_result
>> +ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
>> +{
>> +       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
>> +       int next_len, i;
>> +       int group_addr = is_multicast_ether_addr(hdr->addr1);
>> +
>> +       if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) {
>> +               hdr->duration_id = ieee80211_duration(tx, group_addr, 0);
>> +               return TX_CONTINUE;
>> +       }
>> +
>> +       hdr->duration_id = ieee80211_duration(tx, group_addr,
>> +                                             tx->extra_frag[0]->len);
>> +
>> +       for (i = 0; i < tx->num_extra_frag; i++) {
>> +               if (i + 1 < tx->num_extra_frag) {
>> +                       next_len = tx->extra_frag[i + 1]->len;
>> +               } else {
>> +                       next_len = 0;
>> +                       tx->rate_idx = tx->last_frag_rate_idx;
>> +               }
>> +
>> +               hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data;
>> +               hdr->duration_id = ieee80211_duration(tx, 0, next_len);
>> +       }
>> +
>> +       return TX_CONTINUE;
>> +}
>> +
>> +static ieee80211_tx_result
>>  ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
>>  {
>>        int i;
>> @@ -788,6 +809,7 @@ static ieee80211_tx_handler ieee80211_tx
>>        ieee80211_tx_h_fragment,
>>        /* handlers after fragment must be aware of tx info fragmentation! */
>>        ieee80211_tx_h_encrypt,
>> +       ieee80211_tx_h_calculate_duration,
>>        ieee80211_tx_h_stats,
>>        NULL
>>  };
>> @@ -1139,24 +1161,6 @@ static int ieee80211_tx(struct net_devic
>>                return 0;
>>        }
>>
>> -       if (tx.extra_frag) {
>> -               for (i = 0; i < tx.num_extra_frag; i++) {
>> -                       int next_len, dur;
>> -                       struct ieee80211_hdr *hdr =
>> -                               (struct ieee80211_hdr *)
>> -                               tx.extra_frag[i]->data;
>> -
>> -                       if (i + 1 < tx.num_extra_frag) {
>> -                               next_len = tx.extra_frag[i + 1]->len;
>> -                       } else {
>> -                               next_len = 0;
>> -                               tx.rate_idx = tx.last_frag_rate_idx;
>> -                       }
>> -                       dur = ieee80211_duration(&tx, 0, next_len);
>> -                       hdr->duration_id = cpu_to_le16(dur);
>> -               }
>> -       }
>> -
>>  retry:
>>        ret = __ieee80211_tx(local, skb, &tx);
>>        if (ret) {
>>
>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux