2016-01-01 02:01:03 +03:00
/* Copyright (C) 2006-2016 B.A.T.M.A.N. contributors:
2010-12-13 14:19:28 +03:00
*
* Simon Wunderlich , Marek Lindner
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2013-11-03 23:40:48 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2010-12-13 14:19:28 +03:00
*/
# include "bitarray.h"
2015-04-17 20:40:28 +03:00
# include "main.h"
2010-12-13 14:19:28 +03:00
2015-04-17 20:40:28 +03:00
# include <linux/bitmap.h>
2010-12-13 14:19:28 +03:00
2016-05-16 00:48:31 +03:00
# include "log.h"
2010-12-13 14:19:28 +03:00
/* shift the packet array by n places. */
2015-05-26 19:34:26 +03:00
static void batadv_bitmap_shift_left ( unsigned long * seq_bits , s32 n )
2010-12-13 14:19:28 +03:00
{
2012-06-04 00:19:17 +04:00
if ( n < = 0 | | n > = BATADV_TQ_LOCAL_WINDOW_SIZE )
2010-12-13 14:19:28 +03:00
return ;
2012-06-04 00:19:17 +04:00
bitmap_shift_left ( seq_bits , seq_bits , n , BATADV_TQ_LOCAL_WINDOW_SIZE ) ;
2010-12-13 14:19:28 +03:00
}
2015-10-31 14:29:29 +03:00
/**
* batadv_bit_get_packet - receive and process one packet within the sequence
* number window
* @ priv : the bat priv with all the soft interface information
* @ seq_bits : pointer to the sequence number receive packet
* @ seq_num_diff : difference between the current / received sequence number and
* the last sequence number
* @ set_mark : whether this packet should be marked in seq_bits
2010-12-13 14:19:28 +03:00
*
2016-02-22 23:02:39 +03:00
* Return : true if the window was moved ( either new or very old ) ,
* false if the window was not moved / shifted .
2010-12-13 14:19:28 +03:00
*/
2016-02-22 23:02:39 +03:00
bool batadv_bit_get_packet ( void * priv , unsigned long * seq_bits ,
s32 seq_num_diff , int set_mark )
2010-12-13 14:19:28 +03:00
{
2012-06-06 00:31:31 +04:00
struct batadv_priv * bat_priv = priv ;
2010-12-13 14:19:28 +03:00
/* sequence number is slightly older. We already got a sequence number
2012-05-12 04:09:43 +04:00
* higher than this one , so we just mark it .
*/
2012-06-04 00:19:17 +04:00
if ( seq_num_diff < = 0 & & seq_num_diff > - BATADV_TQ_LOCAL_WINDOW_SIZE ) {
2010-12-13 14:19:28 +03:00
if ( set_mark )
2012-05-12 15:48:53 +04:00
batadv_set_bit ( seq_bits , - seq_num_diff ) ;
2016-02-22 23:02:39 +03:00
return false ;
2010-12-13 14:19:28 +03:00
}
/* sequence number is slightly newer, so we shift the window and
2012-05-12 04:09:43 +04:00
* set the mark if required
*/
2012-06-04 00:19:17 +04:00
if ( seq_num_diff > 0 & & seq_num_diff < BATADV_TQ_LOCAL_WINDOW_SIZE ) {
2012-05-12 04:09:25 +04:00
batadv_bitmap_shift_left ( seq_bits , seq_num_diff ) ;
2010-12-13 14:19:28 +03:00
if ( set_mark )
2012-05-12 15:48:53 +04:00
batadv_set_bit ( seq_bits , 0 ) ;
2016-02-22 23:02:39 +03:00
return true ;
2010-12-13 14:19:28 +03:00
}
/* sequence number is much newer, probably missed a lot of packets */
2012-06-04 00:19:17 +04:00
if ( seq_num_diff > = BATADV_TQ_LOCAL_WINDOW_SIZE & &
seq_num_diff < BATADV_EXPECTED_SEQNO_RANGE ) {
2012-06-04 00:19:22 +04:00
batadv_dbg ( BATADV_DBG_BATMAN , bat_priv ,
2012-05-12 15:48:58 +04:00
" We missed a lot of packets (%i) ! \n " ,
seq_num_diff - 1 ) ;
2012-06-04 00:19:17 +04:00
bitmap_zero ( seq_bits , BATADV_TQ_LOCAL_WINDOW_SIZE ) ;
2010-12-13 14:19:28 +03:00
if ( set_mark )
2012-05-12 15:48:53 +04:00
batadv_set_bit ( seq_bits , 0 ) ;
2016-02-22 23:02:39 +03:00
return true ;
2010-12-13 14:19:28 +03:00
}
/* received a much older packet. The other host either restarted
* or the old packet got delayed somewhere in the network . The
* packet should be dropped without calling this function if the
2012-05-12 04:09:43 +04:00
* seqno window is protected .
2012-08-20 12:26:47 +04:00
*
* seq_num_diff < = - BATADV_TQ_LOCAL_WINDOW_SIZE
* or
* seq_num_diff > = BATADV_EXPECTED_SEQNO_RANGE
2012-05-12 04:09:43 +04:00
*/
2012-08-20 12:26:47 +04:00
batadv_dbg ( BATADV_DBG_BATMAN , bat_priv ,
" Other host probably restarted! \n " ) ;
2010-12-13 14:19:28 +03:00
2012-08-20 12:26:47 +04:00
bitmap_zero ( seq_bits , BATADV_TQ_LOCAL_WINDOW_SIZE ) ;
if ( set_mark )
batadv_set_bit ( seq_bits , 0 ) ;
2010-12-13 14:19:28 +03:00
2016-02-22 23:02:39 +03:00
return true ;
2010-12-13 14:19:28 +03:00
}