@ -2189,11 +2189,12 @@ unlock:
static void batadv_send_roam_adv ( struct batadv_priv * bat_priv , uint8_t * client ,
struct batadv_orig_node * orig_node )
{
struct sk_buff * skb = NULL ;
struct batadv_roam_adv_packet * roam_adv_packet ;
int ret = 1 ;
struct batadv_hard_iface * primary_if ;
size_t len = sizeof ( * roam_adv_packet ) ;
struct batadv_tvlv_roam_adv tvlv_roam ;
primary_if = batadv_primary_if_get_selected ( bat_priv ) ;
if ( ! primary_if )
goto out ;
/* before going on we have to check whether the client has
* already roamed to us too many times
@ -2201,40 +2202,22 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
if ( ! batadv_tt_check_roam_count ( bat_priv , client ) )
goto out ;
skb = netdev_alloc_skb_ip_align ( NULL , len + ETH_HLEN ) ;
if ( ! skb )
goto out ;
skb - > priority = TC_PRIO_CONTROL ;
skb_reserve ( skb , ETH_HLEN ) ;
roam_adv_packet = ( struct batadv_roam_adv_packet * ) skb_put ( skb , len ) ;
roam_adv_packet - > header . packet_type = BATADV_ROAM_ADV ;
roam_adv_packet - > header . version = BATADV_COMPAT_VERSION ;
roam_adv_packet - > header . ttl = BATADV_TTL ;
roam_adv_packet - > reserved = 0 ;
primary_if = batadv_primary_if_get_selected ( bat_priv ) ;
if ( ! primary_if )
goto out ;
memcpy ( roam_adv_packet - > src , primary_if - > net_dev - > dev_addr , ETH_ALEN ) ;
batadv_hardif_free_ref ( primary_if ) ;
memcpy ( roam_adv_packet - > dst , orig_node - > orig , ETH_ALEN ) ;
memcpy ( roam_adv_packet - > client , client , ETH_ALEN ) ;
batadv_dbg ( BATADV_DBG_TT , bat_priv ,
" Sending ROAMING_ADV to %pM (client %pM) \n " ,
orig_node - > orig , client ) ;
batadv_inc_counter ( bat_priv , BATADV_CNT_TT_ROAM_ADV_TX ) ;
if ( batadv_send_skb_to_orig ( skb , orig_node , NULL ) ! = NET_XMIT_DROP )
ret = 0 ;
memcpy ( tvlv_roam . client , client , sizeof ( tvlv_roam . client ) ) ;
tvlv_roam . reserved = 0 ;
batadv_tvlv_unicast_send ( bat_priv , primary_if - > net_dev - > dev_addr ,
orig_node - > orig , BATADV_TVLV_ROAM , 1 ,
& tvlv_roam , sizeof ( tvlv_roam ) ) ;
out :
if ( ret & & skb )
kfree_skb ( skb ) ;
return ;
if ( primary_if )
batadv_hardif_free_ref ( primary_if ) ;
}
static void batadv_tt_purge ( struct work_struct * work )
@ -2667,6 +2650,63 @@ static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
return NET_RX_SUCCESS ;
}
/**
* batadv_roam_tvlv_unicast_handler_v1 - process incoming tt roam tvlv container
* @ bat_priv : the bat priv with all the soft interface information
* @ src : mac address of tt tvlv sender
* @ dst : mac address of tt tvlv recipient
* @ tvlv_value : tvlv buffer containing the tt data
* @ tvlv_value_len : tvlv buffer length
*
* Returns NET_RX_DROP if the tt roam tvlv is to be re - routed , NET_RX_SUCCESS
* otherwise .
*/
static int batadv_roam_tvlv_unicast_handler_v1 ( struct batadv_priv * bat_priv ,
uint8_t * src , uint8_t * dst ,
void * tvlv_value ,
uint16_t tvlv_value_len )
{
struct batadv_tvlv_roam_adv * roaming_adv ;
struct batadv_orig_node * orig_node = NULL ;
/* If this node is not the intended recipient of the
* roaming advertisement the packet is forwarded
* ( the tvlv API will re - route the packet ) .
*/
if ( ! batadv_is_my_mac ( bat_priv , dst ) )
return NET_RX_DROP ;
/* check if it is a backbone gateway. we don't accept
* roaming advertisement from it , as it has the same
* entries as we have .
*/
if ( batadv_bla_is_backbone_gw_orig ( bat_priv , src ) )
goto out ;
if ( tvlv_value_len < sizeof ( * roaming_adv ) )
goto out ;
orig_node = batadv_orig_hash_find ( bat_priv , src ) ;
if ( ! orig_node )
goto out ;
batadv_inc_counter ( bat_priv , BATADV_CNT_TT_ROAM_ADV_RX ) ;
roaming_adv = ( struct batadv_tvlv_roam_adv * ) tvlv_value ;
batadv_dbg ( BATADV_DBG_TT , bat_priv ,
" Received ROAMING_ADV from %pM (client %pM) \n " ,
src , roaming_adv - > client ) ;
batadv_tt_global_add ( bat_priv , orig_node , roaming_adv - > client ,
BATADV_TT_CLIENT_ROAM ,
atomic_read ( & orig_node - > last_ttvn ) + 1 ) ;
out :
if ( orig_node )
batadv_orig_node_free_ref ( orig_node ) ;
return NET_RX_SUCCESS ;
}
/**
* batadv_tt_init - initialise the translation table internals
* @ bat_priv : the bat priv with all the soft interface information
@ -2689,6 +2729,10 @@ int batadv_tt_init(struct batadv_priv *bat_priv)
batadv_tt_tvlv_unicast_handler_v1 ,
BATADV_TVLV_TT , 1 , BATADV_NO_FLAGS ) ;
batadv_tvlv_handler_register ( bat_priv , NULL ,
batadv_roam_tvlv_unicast_handler_v1 ,
BATADV_TVLV_ROAM , 1 , BATADV_NO_FLAGS ) ;
INIT_DELAYED_WORK ( & bat_priv - > tt . work , batadv_tt_purge ) ;
queue_delayed_work ( batadv_event_workqueue , & bat_priv - > tt . work ,
msecs_to_jiffies ( BATADV_TT_WORK_PERIOD ) ) ;