lkml.org 
[lkml]   [2014]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.14 15/39] batman-adv: Fix out-of-order fragmentation support
    Date
    3.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Sven Eckelmann <sven@narfation.org>

    [ Upstream commit d9124268d84a836f14a6ead54ff9d8eee4c43be5 ]

    batadv_frag_insert_packet was unable to handle out-of-order packets because it
    dropped them directly. This is caused by the way the fragmentation lists is
    checked for the correct place to insert a fragmentation entry.

    The fragmentation code keeps the fragments in lists. The fragmentation entries
    are kept in descending order of sequence number. The list is traversed and each
    entry is compared with the new fragment. If the current entry has a smaller
    sequence number than the new fragment then the new one has to be inserted
    before the current entry. This ensures that the list is still in descending
    order.

    An out-of-order packet with a smaller sequence number than all entries in the
    list still has to be added to the end of the list. The used hlist has no
    information about the last entry in the list inside hlist_head and thus the
    last entry has to be calculated differently. Currently the code assumes that
    the iterator variable of hlist_for_each_entry can be used for this purpose
    after the hlist_for_each_entry finished. This is obviously wrong because the
    iterator variable is always NULL when the list was completely traversed.

    Instead the information about the last entry has to be stored in a different
    variable.

    This problem was introduced in 610bfc6bc99bc83680d190ebc69359a05fc7f605
    ("batman-adv: Receive fragmented packets and merge").

    Signed-off-by: Sven Eckelmann <sven@narfation.org>
    Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
    Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/batman-adv/fragmentation.c | 10 +++++++---
    1 file changed, 7 insertions(+), 3 deletions(-)

    --- a/net/batman-adv/fragmentation.c
    +++ b/net/batman-adv/fragmentation.c
    @@ -128,6 +128,7 @@ static bool batadv_frag_insert_packet(st
    {
    struct batadv_frag_table_entry *chain;
    struct batadv_frag_list_entry *frag_entry_new = NULL, *frag_entry_curr;
    + struct batadv_frag_list_entry *frag_entry_last = NULL;
    struct batadv_frag_packet *frag_packet;
    uint8_t bucket;
    uint16_t seqno, hdr_size = sizeof(struct batadv_frag_packet);
    @@ -180,11 +181,14 @@ static bool batadv_frag_insert_packet(st
    ret = true;
    goto out;
    }
    +
    + /* store current entry because it could be the last in list */
    + frag_entry_last = frag_entry_curr;
    }

    - /* Reached the end of the list, so insert after 'frag_entry_curr'. */
    - if (likely(frag_entry_curr)) {
    - hlist_add_after(&frag_entry_curr->list, &frag_entry_new->list);
    + /* Reached the end of the list, so insert after 'frag_entry_last'. */
    + if (likely(frag_entry_last)) {
    + hlist_add_after(&frag_entry_last->list, &frag_entry_new->list);
    chain->size += skb->len - hdr_size;
    chain->timestamp = jiffies;
    ret = true;



    \
     
     \ /
      Last update: 2014-08-09 00:21    [W:4.183 / U:0.820 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site