2012-05-12 02:09:43 +02:00
/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
2010-12-13 11:19:28 +00:00
*
* Marek Lindner , Simon Wunderlich
*
* 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
*/
# ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
# define _NET_BATMAN_ADV_ORIGINATOR_H_
2011-02-18 12:28:09 +00:00
# include "hash.h"
2012-06-05 22:31:31 +02:00
int batadv_originator_init ( struct batadv_priv * bat_priv ) ;
void batadv_originator_free ( struct batadv_priv * bat_priv ) ;
void batadv_purge_orig_ref ( struct batadv_priv * bat_priv ) ;
void batadv_orig_node_free_ref ( struct batadv_orig_node * orig_node ) ;
struct batadv_orig_node * batadv_get_orig_node ( struct batadv_priv * bat_priv ,
const uint8_t * addr ) ;
struct batadv_neigh_node *
batadv_neigh_node_new ( struct batadv_hard_iface * hard_iface ,
const uint8_t * neigh_addr , uint32_t seqno ) ;
void batadv_neigh_node_free_ref ( struct batadv_neigh_node * neigh_node ) ;
struct batadv_neigh_node *
batadv_orig_node_get_router ( struct batadv_orig_node * orig_node ) ;
2012-05-12 02:09:34 +02:00
int batadv_orig_seq_print_text ( struct seq_file * seq , void * offset ) ;
2012-06-05 22:31:31 +02:00
int batadv_orig_hash_add_if ( struct batadv_hard_iface * hard_iface ,
int max_if_num ) ;
int batadv_orig_hash_del_if ( struct batadv_hard_iface * hard_iface ,
int max_if_num ) ;
2010-12-13 11:19:28 +00:00
2012-05-12 02:09:43 +02:00
/* hashfunction to choose an entry in a hash table of given size
* hash algorithm from http : //en.wikipedia.org/wiki/Hash_table
*/
2012-05-12 13:48:56 +02:00
static inline uint32_t batadv_choose_orig ( const void * data , uint32_t size )
2010-12-13 11:19:28 +00:00
{
2011-05-14 23:14:50 +02:00
const unsigned char * key = data ;
2010-12-13 11:19:28 +00:00
uint32_t hash = 0 ;
size_t i ;
for ( i = 0 ; i < 6 ; i + + ) {
hash + = key [ i ] ;
hash + = ( hash < < 10 ) ;
hash ^ = ( hash > > 6 ) ;
}
hash + = ( hash < < 3 ) ;
hash ^ = ( hash > > 11 ) ;
hash + = ( hash < < 15 ) ;
return hash % size ;
}
2012-06-05 22:31:31 +02:00
static inline struct batadv_orig_node *
batadv_orig_hash_find ( struct batadv_priv * bat_priv , const void * data )
2011-02-18 12:28:09 +00:00
{
2012-06-05 22:31:28 +02:00
struct batadv_hashtable * hash = bat_priv - > orig_hash ;
2011-02-18 12:28:09 +00:00
struct hlist_head * head ;
struct hlist_node * node ;
2012-06-05 22:31:31 +02:00
struct batadv_orig_node * orig_node , * orig_node_tmp = NULL ;
2011-02-18 12:28:09 +00:00
int index ;
if ( ! hash )
return NULL ;
2012-05-12 13:48:56 +02:00
index = batadv_choose_orig ( data , hash - > size ) ;
2011-02-18 12:28:09 +00:00
head = & hash - > table [ index ] ;
rcu_read_lock ( ) ;
hlist_for_each_entry_rcu ( orig_node , node , head , hash_entry ) {
2012-05-12 13:48:58 +02:00
if ( ! batadv_compare_eth ( orig_node , data ) )
2011-02-18 12:28:09 +00:00
continue ;
2011-02-18 12:28:10 +00:00
if ( ! atomic_inc_not_zero ( & orig_node - > refcount ) )
continue ;
2011-02-18 12:28:09 +00:00
orig_node_tmp = orig_node ;
break ;
}
rcu_read_unlock ( ) ;
return orig_node_tmp ;
}
2010-12-13 11:19:28 +00:00
# endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */