2013-01-04 06:05:31 +04:00
/* Copyright (C) 2006-2013 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
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA
* 02110 - 1301 , USA
*/
# include "main.h"
# include "bitarray.h"
# include <linux/bitops.h>
/* shift the packet array by n places. */
2012-05-12 04:09:25 +04:00
static void batadv_bitmap_shift_left ( unsigned long * seq_bits , int32_t 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
}
/* receive and process one packet within the sequence number window.
*
* returns :
* 1 if the window was moved ( either new or very old )
* 0 if the window was not moved / shifted .
*/
2012-05-12 04:09:25 +04:00
int batadv_bit_get_packet ( void * priv , unsigned long * seq_bits ,
int32_t 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 ) ;
2010-12-13 14:19:28 +03:00
return 0 ;
}
/* 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 ) ;
2010-12-13 14:19:28 +03:00
return 1 ;
}
/* 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 ) ;
2010-12-13 14:19:28 +03:00
return 1 ;
}
/* 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
2012-08-20 12:26:47 +04:00
return 1 ;
2010-12-13 14:19:28 +03:00
}