included changes:
- some code cleanups and minor fixes (3 of them were reported by Coverity) - 'struct hard_iface' re-shaping to improve multi-protocol support - ECTP packets silent drop - transfer the WIFI flag on clients in case of roaming -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlCOQzIACgkQpGgxIkP9cwdjVgCgmTSMNhAOvIWG/8dV6iiAvDeP bwIAnjZb5QeF/d4L+lRuqw5hMVTEQnJo =SAxj -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge included changes: - some code cleanups and minor fixes (3 of them were reported by Coverity) - 'struct hard_iface' re-shaping to improve multi-protocol support - ECTP packets silent drop - transfer the WIFI flag on clients in case of roaming
This commit is contained in:
commit
157083811c
|
@ -57,20 +57,22 @@ out:
|
||||||
static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
|
static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batadv_ogm_packet *batadv_ogm_packet;
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
unsigned char *ogm_buff;
|
||||||
uint32_t random_seqno;
|
uint32_t random_seqno;
|
||||||
int res = -ENOMEM;
|
int res = -ENOMEM;
|
||||||
|
|
||||||
/* randomize initial seqno to avoid collision */
|
/* randomize initial seqno to avoid collision */
|
||||||
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
get_random_bytes(&random_seqno, sizeof(random_seqno));
|
||||||
atomic_set(&hard_iface->seqno, random_seqno);
|
atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
|
||||||
|
|
||||||
hard_iface->packet_len = BATADV_OGM_HLEN;
|
hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
|
||||||
hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
|
ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
|
||||||
|
if (!ogm_buff)
|
||||||
if (!hard_iface->packet_buff)
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
|
hard_iface->bat_iv.ogm_buff = ogm_buff;
|
||||||
|
|
||||||
|
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
batadv_ogm_packet->header.packet_type = BATADV_IV_OGM;
|
batadv_ogm_packet->header.packet_type = BATADV_IV_OGM;
|
||||||
batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
|
batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
|
||||||
batadv_ogm_packet->header.ttl = 2;
|
batadv_ogm_packet->header.ttl = 2;
|
||||||
|
@ -87,15 +89,16 @@ out:
|
||||||
|
|
||||||
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
|
static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
kfree(hard_iface->packet_buff);
|
kfree(hard_iface->bat_iv.ogm_buff);
|
||||||
hard_iface->packet_buff = NULL;
|
hard_iface->bat_iv.ogm_buff = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
|
static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batadv_ogm_packet *batadv_ogm_packet;
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
|
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
memcpy(batadv_ogm_packet->orig,
|
memcpy(batadv_ogm_packet->orig,
|
||||||
hard_iface->net_dev->dev_addr, ETH_ALEN);
|
hard_iface->net_dev->dev_addr, ETH_ALEN);
|
||||||
memcpy(batadv_ogm_packet->prev_sender,
|
memcpy(batadv_ogm_packet->prev_sender,
|
||||||
|
@ -106,8 +109,9 @@ static void
|
||||||
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
|
batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batadv_ogm_packet *batadv_ogm_packet;
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
|
unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
|
||||||
|
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
|
batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
|
||||||
batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
|
batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
|
||||||
batadv_ogm_packet->header.ttl = BATADV_TTL;
|
batadv_ogm_packet->header.ttl = BATADV_TTL;
|
||||||
}
|
}
|
||||||
|
@ -590,8 +594,10 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
|
||||||
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
||||||
{
|
{
|
||||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||||
|
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
|
||||||
struct batadv_ogm_packet *batadv_ogm_packet;
|
struct batadv_ogm_packet *batadv_ogm_packet;
|
||||||
struct batadv_hard_iface *primary_if;
|
struct batadv_hard_iface *primary_if;
|
||||||
|
int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
|
||||||
int vis_server, tt_num_changes = 0;
|
int vis_server, tt_num_changes = 0;
|
||||||
uint32_t seqno;
|
uint32_t seqno;
|
||||||
uint8_t bandwidth;
|
uint8_t bandwidth;
|
||||||
|
@ -600,17 +606,16 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
|
|
||||||
if (hard_iface == primary_if)
|
if (hard_iface == primary_if)
|
||||||
tt_num_changes = batadv_tt_append_diff(bat_priv,
|
tt_num_changes = batadv_tt_append_diff(bat_priv, ogm_buff,
|
||||||
&hard_iface->packet_buff,
|
ogm_buff_len,
|
||||||
&hard_iface->packet_len,
|
|
||||||
BATADV_OGM_HLEN);
|
BATADV_OGM_HLEN);
|
||||||
|
|
||||||
batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
|
batadv_ogm_packet = (struct batadv_ogm_packet *)(*ogm_buff);
|
||||||
|
|
||||||
/* change sequence number to network order */
|
/* change sequence number to network order */
|
||||||
seqno = (uint32_t)atomic_read(&hard_iface->seqno);
|
seqno = (uint32_t)atomic_read(&hard_iface->bat_iv.ogm_seqno);
|
||||||
batadv_ogm_packet->seqno = htonl(seqno);
|
batadv_ogm_packet->seqno = htonl(seqno);
|
||||||
atomic_inc(&hard_iface->seqno);
|
atomic_inc(&hard_iface->bat_iv.ogm_seqno);
|
||||||
|
|
||||||
batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
|
batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
|
||||||
batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
|
batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
|
||||||
|
@ -631,8 +636,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_slide_own_bcast_window(hard_iface);
|
batadv_slide_own_bcast_window(hard_iface);
|
||||||
batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
|
batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
|
||||||
hard_iface->packet_len, hard_iface, 1,
|
hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
|
||||||
batadv_iv_ogm_emit_send_time(bat_priv));
|
batadv_iv_ogm_emit_send_time(bat_priv));
|
||||||
|
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
|
@ -1015,7 +1020,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* could be changed by schedule_own_packet() */
|
/* could be changed by schedule_own_packet() */
|
||||||
if_incoming_seqno = atomic_read(&if_incoming->seqno);
|
if_incoming_seqno = atomic_read(&if_incoming->bat_iv.ogm_seqno);
|
||||||
|
|
||||||
if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
|
if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
|
||||||
has_directlink_flag = 1;
|
has_directlink_flag = 1;
|
||||||
|
|
|
@ -79,20 +79,17 @@ int batadv_bit_get_packet(void *priv, unsigned long *seq_bits,
|
||||||
* or the old packet got delayed somewhere in the network. The
|
* or the old packet got delayed somewhere in the network. The
|
||||||
* packet should be dropped without calling this function if the
|
* packet should be dropped without calling this function if the
|
||||||
* seqno window is protected.
|
* seqno window is protected.
|
||||||
|
*
|
||||||
|
* seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE
|
||||||
|
* or
|
||||||
|
* seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE
|
||||||
*/
|
*/
|
||||||
if (seq_num_diff <= -BATADV_TQ_LOCAL_WINDOW_SIZE ||
|
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||||
seq_num_diff >= BATADV_EXPECTED_SEQNO_RANGE) {
|
"Other host probably restarted!\n");
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
|
||||||
"Other host probably restarted!\n");
|
if (set_mark)
|
||||||
|
batadv_set_bit(seq_bits, 0);
|
||||||
|
|
||||||
bitmap_zero(seq_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
|
return 1;
|
||||||
if (set_mark)
|
|
||||||
batadv_set_bit(seq_bits, 0);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* never reached */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1585,23 +1585,11 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
bool is_own;
|
bool is_own;
|
||||||
int ret = 0;
|
|
||||||
uint8_t *primary_addr;
|
uint8_t *primary_addr;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
if (!primary_if) {
|
if (!primary_if)
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
primary_addr = primary_if->net_dev->dev_addr;
|
primary_addr = primary_if->net_dev->dev_addr;
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
|
@ -1628,7 +1616,7 @@ int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
|
@ -1643,23 +1631,11 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
int secs, msecs;
|
int secs, msecs;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
bool is_own;
|
bool is_own;
|
||||||
int ret = 0;
|
|
||||||
uint8_t *primary_addr;
|
uint8_t *primary_addr;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
if (!primary_if) {
|
if (!primary_if)
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
primary_addr = primary_if->net_dev->dev_addr;
|
primary_addr = primary_if->net_dev->dev_addr;
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
|
@ -1693,5 +1669,5 @@ int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,15 +99,17 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
|
||||||
|
|
||||||
static int batadv_log_open(struct inode *inode, struct file *file)
|
static int batadv_log_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
if (!try_module_get(THIS_MODULE))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
nonseekable_open(inode, file);
|
nonseekable_open(inode, file);
|
||||||
file->private_data = inode->i_private;
|
file->private_data = inode->i_private;
|
||||||
batadv_inc_module_count();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int batadv_log_release(struct inode *inode, struct file *file)
|
static int batadv_log_release(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
batadv_dec_module_count();
|
module_put(THIS_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -477,22 +477,11 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
struct batadv_hard_iface *primary_if;
|
struct batadv_hard_iface *primary_if;
|
||||||
struct batadv_gw_node *gw_node;
|
struct batadv_gw_node *gw_node;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
int gw_count = 0, ret = 0;
|
int gw_count = 0;
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
if (!primary_if) {
|
if (!primary_if)
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
" %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
|
" %-12s (%s/%i) %17s [%10s]: gw_class ... [B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
|
||||||
|
@ -519,7 +508,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
|
static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
|
||||||
|
|
|
@ -450,8 +450,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
|
||||||
/* This can't be called via a bat_priv callback because
|
/* This can't be called via a bat_priv callback because
|
||||||
* we have no bat_priv yet.
|
* we have no bat_priv yet.
|
||||||
*/
|
*/
|
||||||
atomic_set(&hard_iface->seqno, 1);
|
atomic_set(&hard_iface->bat_iv.ogm_seqno, 1);
|
||||||
hard_iface->packet_buff = NULL;
|
hard_iface->bat_iv.ogm_buff = NULL;
|
||||||
|
|
||||||
return hard_iface;
|
return hard_iface;
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,16 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct batadv_socket_client *socket_client;
|
struct batadv_socket_client *socket_client;
|
||||||
|
|
||||||
|
if (!try_module_get(THIS_MODULE))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
nonseekable_open(inode, file);
|
nonseekable_open(inode, file);
|
||||||
|
|
||||||
socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
|
socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL);
|
||||||
|
if (!socket_client) {
|
||||||
if (!socket_client)
|
module_put(THIS_MODULE);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) {
|
for (i = 0; i < ARRAY_SIZE(batadv_socket_client_hash); i++) {
|
||||||
if (!batadv_socket_client_hash[i]) {
|
if (!batadv_socket_client_hash[i]) {
|
||||||
|
@ -59,6 +63,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
|
||||||
if (i == ARRAY_SIZE(batadv_socket_client_hash)) {
|
if (i == ARRAY_SIZE(batadv_socket_client_hash)) {
|
||||||
pr_err("Error - can't add another packet client: maximum number of clients reached\n");
|
pr_err("Error - can't add another packet client: maximum number of clients reached\n");
|
||||||
kfree(socket_client);
|
kfree(socket_client);
|
||||||
|
module_put(THIS_MODULE);
|
||||||
return -EXFULL;
|
return -EXFULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +76,6 @@ static int batadv_socket_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
file->private_data = socket_client;
|
file->private_data = socket_client;
|
||||||
|
|
||||||
batadv_inc_module_count();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +100,7 @@ static int batadv_socket_release(struct inode *inode, struct file *file)
|
||||||
spin_unlock_bh(&socket_client->lock);
|
spin_unlock_bh(&socket_client->lock);
|
||||||
|
|
||||||
kfree(socket_client);
|
kfree(socket_client);
|
||||||
batadv_dec_module_count();
|
module_put(THIS_MODULE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,16 +160,6 @@ void batadv_mesh_free(struct net_device *soft_iface)
|
||||||
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void batadv_inc_module_count(void)
|
|
||||||
{
|
|
||||||
try_module_get(THIS_MODULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void batadv_dec_module_count(void)
|
|
||||||
{
|
|
||||||
module_put(THIS_MODULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int batadv_is_my_mac(const uint8_t *addr)
|
int batadv_is_my_mac(const uint8_t *addr)
|
||||||
{
|
{
|
||||||
const struct batadv_hard_iface *hard_iface;
|
const struct batadv_hard_iface *hard_iface;
|
||||||
|
@ -188,6 +178,42 @@ int batadv_is_my_mac(const uint8_t *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_seq_print_text_primary_if_get - called from debugfs table printing
|
||||||
|
* function that requires the primary interface
|
||||||
|
* @seq: debugfs table seq_file struct
|
||||||
|
*
|
||||||
|
* Returns primary interface if found or NULL otherwise.
|
||||||
|
*/
|
||||||
|
struct batadv_hard_iface *
|
||||||
|
batadv_seq_print_text_primary_if_get(struct seq_file *seq)
|
||||||
|
{
|
||||||
|
struct net_device *net_dev = (struct net_device *)seq->private;
|
||||||
|
struct batadv_priv *bat_priv = netdev_priv(net_dev);
|
||||||
|
struct batadv_hard_iface *primary_if;
|
||||||
|
|
||||||
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
|
|
||||||
|
if (!primary_if) {
|
||||||
|
seq_printf(seq,
|
||||||
|
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
||||||
|
net_dev->name);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primary_if->if_status == BATADV_IF_ACTIVE)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
seq_printf(seq,
|
||||||
|
"BATMAN mesh %s disabled - primary interface not active\n",
|
||||||
|
net_dev->name);
|
||||||
|
batadv_hardif_free_ref(primary_if);
|
||||||
|
primary_if = NULL;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return primary_if;
|
||||||
|
}
|
||||||
|
|
||||||
static int batadv_recv_unhandled_packet(struct sk_buff *skb,
|
static int batadv_recv_unhandled_packet(struct sk_buff *skb,
|
||||||
struct batadv_hard_iface *recv_if)
|
struct batadv_hard_iface *recv_if)
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,9 +150,9 @@ extern struct workqueue_struct *batadv_event_workqueue;
|
||||||
|
|
||||||
int batadv_mesh_init(struct net_device *soft_iface);
|
int batadv_mesh_init(struct net_device *soft_iface);
|
||||||
void batadv_mesh_free(struct net_device *soft_iface);
|
void batadv_mesh_free(struct net_device *soft_iface);
|
||||||
void batadv_inc_module_count(void);
|
|
||||||
void batadv_dec_module_count(void);
|
|
||||||
int batadv_is_my_mac(const uint8_t *addr);
|
int batadv_is_my_mac(const uint8_t *addr);
|
||||||
|
struct batadv_hard_iface *
|
||||||
|
batadv_seq_print_text_primary_if_get(struct seq_file *seq);
|
||||||
int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
|
||||||
struct packet_type *ptype,
|
struct packet_type *ptype,
|
||||||
struct net_device *orig_dev);
|
struct net_device *orig_dev);
|
||||||
|
@ -165,12 +165,19 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
|
||||||
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
|
int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
|
||||||
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
|
||||||
/* all messages related to routing / flooding / broadcasting / etc */
|
/**
|
||||||
|
* enum batadv_dbg_level - available log levels
|
||||||
|
* @BATADV_DBG_BATMAN: OGM and TQ computations related messages
|
||||||
|
* @BATADV_DBG_ROUTES: route added / changed / deleted
|
||||||
|
* @BATADV_DBG_TT: translation table messages
|
||||||
|
* @BATADV_DBG_BLA: bridge loop avoidance messages
|
||||||
|
* @BATADV_DBG_ALL: the union of all the above log levels
|
||||||
|
*/
|
||||||
enum batadv_dbg_level {
|
enum batadv_dbg_level {
|
||||||
BATADV_DBG_BATMAN = BIT(0),
|
BATADV_DBG_BATMAN = BIT(0),
|
||||||
BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */
|
BATADV_DBG_ROUTES = BIT(1),
|
||||||
BATADV_DBG_TT = BIT(2), /* translation table operations */
|
BATADV_DBG_TT = BIT(2),
|
||||||
BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */
|
BATADV_DBG_BLA = BIT(3),
|
||||||
BATADV_DBG_ALL = 15,
|
BATADV_DBG_ALL = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -415,23 +415,10 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
int last_seen_msecs;
|
int last_seen_msecs;
|
||||||
unsigned long last_seen_jiffies;
|
unsigned long last_seen_jiffies;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
|
if (!primary_if)
|
||||||
if (!primary_if) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
|
seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n",
|
||||||
BATADV_SOURCE_VERSION, primary_if->net_dev->name,
|
BATADV_SOURCE_VERSION, primary_if->net_dev->name,
|
||||||
|
@ -485,7 +472,7 @@ next:
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node,
|
static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node,
|
||||||
|
|
|
@ -549,25 +549,18 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
|
||||||
if (tmp_neigh_node->if_incoming == recv_if)
|
if (tmp_neigh_node->if_incoming == recv_if)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (router && tmp_neigh_node->tq_avg <= router->tq_avg)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
|
if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* if we don't have a router yet
|
/* decrement refcount of previously selected router */
|
||||||
* or this one is better, choose it.
|
if (router)
|
||||||
*/
|
batadv_neigh_node_free_ref(router);
|
||||||
if ((!router) ||
|
|
||||||
(tmp_neigh_node->tq_avg > router->tq_avg)) {
|
|
||||||
/* decrement refcount of
|
|
||||||
* previously selected router
|
|
||||||
*/
|
|
||||||
if (router)
|
|
||||||
batadv_neigh_node_free_ref(router);
|
|
||||||
|
|
||||||
router = tmp_neigh_node;
|
/* we found a better router (or at least one valid router) */
|
||||||
atomic_inc_not_zero(&router->refcount);
|
router = tmp_neigh_node;
|
||||||
}
|
|
||||||
|
|
||||||
batadv_neigh_node_free_ref(tmp_neigh_node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use the first candidate if nothing was found. */
|
/* use the first candidate if nothing was found. */
|
||||||
|
@ -687,21 +680,8 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
|
||||||
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
||||||
struct batadv_roam_adv_packet *roam_adv_packet;
|
struct batadv_roam_adv_packet *roam_adv_packet;
|
||||||
struct batadv_orig_node *orig_node;
|
struct batadv_orig_node *orig_node;
|
||||||
struct ethhdr *ethhdr;
|
|
||||||
|
|
||||||
/* drop packet if it has not necessary minimum size */
|
if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0)
|
||||||
if (unlikely(!pskb_may_pull(skb,
|
|
||||||
sizeof(struct batadv_roam_adv_packet))))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ethhdr = (struct ethhdr *)skb_mac_header(skb);
|
|
||||||
|
|
||||||
/* packet with unicast indication but broadcast recipient */
|
|
||||||
if (is_broadcast_ether_addr(ethhdr->h_dest))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* packet with broadcast sender address */
|
|
||||||
if (is_broadcast_ether_addr(ethhdr->h_source))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
|
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
|
||||||
|
@ -928,8 +908,12 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||||
bool tt_poss_change;
|
bool tt_poss_change;
|
||||||
int is_old_ttvn;
|
int is_old_ttvn;
|
||||||
|
|
||||||
/* I could need to modify it */
|
/* check if there is enough data before accessing it */
|
||||||
if (skb_cow(skb, sizeof(struct batadv_unicast_packet)) < 0)
|
if (pskb_may_pull(skb, sizeof(*unicast_packet) + ETH_HLEN) < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* create a copy of the skb (in case of for re-routing) to modify it. */
|
||||||
|
if (skb_cow(skb, sizeof(*unicast_packet)) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||||
|
@ -985,10 +969,10 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||||
batadv_orig_node_free_ref(orig_node);
|
batadv_orig_node_free_ref(orig_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
batadv_dbg(BATADV_DBG_ROUTES, bat_priv,
|
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
|
||||||
"TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n",
|
"TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n",
|
||||||
unicast_packet->ttvn, curr_ttvn, ethhdr->h_dest,
|
unicast_packet->ttvn, curr_ttvn,
|
||||||
unicast_packet->dest);
|
ethhdr->h_dest, unicast_packet->dest);
|
||||||
|
|
||||||
unicast_packet->ttvn = curr_ttvn;
|
unicast_packet->ttvn = curr_ttvn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,10 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
struct batadv_bcast_packet *bcast_packet;
|
struct batadv_bcast_packet *bcast_packet;
|
||||||
struct vlan_ethhdr *vhdr;
|
struct vlan_ethhdr *vhdr;
|
||||||
__be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN);
|
__be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN);
|
||||||
static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00,
|
static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
|
||||||
0x00};
|
0x00, 0x00};
|
||||||
|
static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00};
|
||||||
unsigned int header_len = 0;
|
unsigned int header_len = 0;
|
||||||
int data_len = skb->len, ret;
|
int data_len = skb->len, ret;
|
||||||
short vid __maybe_unused = -1;
|
short vid __maybe_unused = -1;
|
||||||
|
@ -180,10 +182,16 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||||
|
|
||||||
/* don't accept stp packets. STP does not help in meshes.
|
/* don't accept stp packets. STP does not help in meshes.
|
||||||
* better use the bridge loop avoidance ...
|
* better use the bridge loop avoidance ...
|
||||||
|
*
|
||||||
|
* The same goes for ECTP sent at least by some Cisco Switches,
|
||||||
|
* it might confuse the mesh when used with bridge loop avoidance.
|
||||||
*/
|
*/
|
||||||
if (batadv_compare_eth(ethhdr->h_dest, stp_addr))
|
if (batadv_compare_eth(ethhdr->h_dest, stp_addr))
|
||||||
goto dropped;
|
goto dropped;
|
||||||
|
|
||||||
|
if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
|
||||||
|
goto dropped;
|
||||||
|
|
||||||
if (is_multicast_ether_addr(ethhdr->h_dest)) {
|
if (is_multicast_ether_addr(ethhdr->h_dest)) {
|
||||||
do_bcast = true;
|
do_bcast = true;
|
||||||
|
|
||||||
|
@ -347,7 +355,51 @@ out:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* batman-adv network devices have devices nesting below it and are a special
|
||||||
|
* "super class" of normal network devices; split their locks off into a
|
||||||
|
* separate class since they always nest.
|
||||||
|
*/
|
||||||
|
static struct lock_class_key batadv_netdev_xmit_lock_key;
|
||||||
|
static struct lock_class_key batadv_netdev_addr_lock_key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_set_lockdep_class_one - Set lockdep class for a single tx queue
|
||||||
|
* @dev: device which owns the tx queue
|
||||||
|
* @txq: tx queue to modify
|
||||||
|
* @_unused: always NULL
|
||||||
|
*/
|
||||||
|
static void batadv_set_lockdep_class_one(struct net_device *dev,
|
||||||
|
struct netdev_queue *txq,
|
||||||
|
void *_unused)
|
||||||
|
{
|
||||||
|
lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_set_lockdep_class - Set txq and addr_list lockdep class
|
||||||
|
* @dev: network device to modify
|
||||||
|
*/
|
||||||
|
static void batadv_set_lockdep_class(struct net_device *dev)
|
||||||
|
{
|
||||||
|
lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key);
|
||||||
|
netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_softif_init - Late stage initialization of soft interface
|
||||||
|
* @dev: registered network device to modify
|
||||||
|
*
|
||||||
|
* Returns error code on failures
|
||||||
|
*/
|
||||||
|
static int batadv_softif_init(struct net_device *dev)
|
||||||
|
{
|
||||||
|
batadv_set_lockdep_class(dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct net_device_ops batadv_netdev_ops = {
|
static const struct net_device_ops batadv_netdev_ops = {
|
||||||
|
.ndo_init = batadv_softif_init,
|
||||||
.ndo_open = batadv_interface_open,
|
.ndo_open = batadv_interface_open,
|
||||||
.ndo_stop = batadv_interface_release,
|
.ndo_stop = batadv_interface_release,
|
||||||
.ndo_get_stats = batadv_interface_stats,
|
.ndo_get_stats = batadv_interface_stats,
|
||||||
|
|
|
@ -122,55 +122,6 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
|
||||||
batadv_store_##_name)
|
batadv_store_##_name)
|
||||||
|
|
||||||
|
|
||||||
#define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \
|
|
||||||
ssize_t batadv_store_##_name(struct kobject *kobj, \
|
|
||||||
struct attribute *attr, char *buff, \
|
|
||||||
size_t count) \
|
|
||||||
{ \
|
|
||||||
struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
|
|
||||||
struct batadv_hard_iface *hard_iface; \
|
|
||||||
ssize_t length; \
|
|
||||||
\
|
|
||||||
hard_iface = batadv_hardif_get_by_netdev(net_dev); \
|
|
||||||
if (!hard_iface) \
|
|
||||||
return 0; \
|
|
||||||
\
|
|
||||||
length = __batadv_store_uint_attr(buff, count, _min, _max, \
|
|
||||||
_post_func, attr, \
|
|
||||||
&hard_iface->_name, net_dev); \
|
|
||||||
\
|
|
||||||
batadv_hardif_free_ref(hard_iface); \
|
|
||||||
return length; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BATADV_ATTR_HIF_SHOW_UINT(_name) \
|
|
||||||
ssize_t batadv_show_##_name(struct kobject *kobj, \
|
|
||||||
struct attribute *attr, char *buff) \
|
|
||||||
{ \
|
|
||||||
struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
|
|
||||||
struct batadv_hard_iface *hard_iface; \
|
|
||||||
ssize_t length; \
|
|
||||||
\
|
|
||||||
hard_iface = batadv_hardif_get_by_netdev(net_dev); \
|
|
||||||
if (!hard_iface) \
|
|
||||||
return 0; \
|
|
||||||
\
|
|
||||||
length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\
|
|
||||||
\
|
|
||||||
batadv_hardif_free_ref(hard_iface); \
|
|
||||||
return length; \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use this, if you are going to set [name] in hard_iface to an
|
|
||||||
* unsigned integer value
|
|
||||||
*/
|
|
||||||
#define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \
|
|
||||||
static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\
|
|
||||||
static BATADV_ATTR_HIF_SHOW_UINT(_name) \
|
|
||||||
static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
|
|
||||||
batadv_store_##_name)
|
|
||||||
|
|
||||||
|
|
||||||
static int batadv_store_bool_attr(char *buff, size_t count,
|
static int batadv_store_bool_attr(char *buff, size_t count,
|
||||||
struct net_device *net_dev,
|
struct net_device *net_dev,
|
||||||
const char *attr_name, atomic_t *attr)
|
const char *attr_name, atomic_t *attr)
|
||||||
|
|
|
@ -434,22 +434,10 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
if (!primary_if) {
|
if (!primary_if)
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
|
"Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
|
||||||
|
@ -479,7 +467,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -501,24 +489,39 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
|
||||||
tt_local_entry->common.addr, message);
|
tt_local_entry->common.addr, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr,
|
/**
|
||||||
const char *message, bool roaming)
|
* batadv_tt_local_remove - logically remove an entry from the local table
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @addr: the MAC address of the client to remove
|
||||||
|
* @message: message to append to the log on deletion
|
||||||
|
* @roaming: true if the deletion is due to a roaming event
|
||||||
|
*
|
||||||
|
* Returns the flags assigned to the local entry before being deleted
|
||||||
|
*/
|
||||||
|
uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
||||||
|
const uint8_t *addr, const char *message,
|
||||||
|
bool roaming)
|
||||||
{
|
{
|
||||||
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
||||||
uint16_t flags;
|
uint16_t flags, curr_flags = BATADV_NO_FLAGS;
|
||||||
|
|
||||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
||||||
if (!tt_local_entry)
|
if (!tt_local_entry)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
curr_flags = tt_local_entry->common.flags;
|
||||||
|
|
||||||
flags = BATADV_TT_CLIENT_DEL;
|
flags = BATADV_TT_CLIENT_DEL;
|
||||||
if (roaming)
|
if (roaming)
|
||||||
flags |= BATADV_TT_CLIENT_ROAM;
|
flags |= BATADV_TT_CLIENT_ROAM;
|
||||||
|
|
||||||
batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
|
batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (tt_local_entry)
|
if (tt_local_entry)
|
||||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||||
|
|
||||||
|
return curr_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
|
static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
|
||||||
|
@ -725,6 +728,7 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int hash_added;
|
int hash_added;
|
||||||
struct batadv_tt_common_entry *common;
|
struct batadv_tt_common_entry *common;
|
||||||
|
uint16_t local_flags;
|
||||||
|
|
||||||
tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
|
tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
|
||||||
|
|
||||||
|
@ -738,6 +742,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||||
|
|
||||||
common->flags = flags;
|
common->flags = flags;
|
||||||
tt_global_entry->roam_at = 0;
|
tt_global_entry->roam_at = 0;
|
||||||
|
/* node must store current time in case of roaming. This is
|
||||||
|
* needed to purge this entry out on timeout (if nobody claims
|
||||||
|
* it)
|
||||||
|
*/
|
||||||
|
if (flags & BATADV_TT_CLIENT_ROAM)
|
||||||
|
tt_global_entry->roam_at = jiffies;
|
||||||
atomic_set(&common->refcount, 2);
|
atomic_set(&common->refcount, 2);
|
||||||
common->added_at = jiffies;
|
common->added_at = jiffies;
|
||||||
|
|
||||||
|
@ -788,13 +798,16 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||||
"Creating new global tt entry: %pM (via %pM)\n",
|
"Creating new global tt entry: %pM (via %pM)\n",
|
||||||
tt_global_entry->common.addr, orig_node->orig);
|
tt_global_entry->common.addr, orig_node->orig);
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
out_remove:
|
out_remove:
|
||||||
|
|
||||||
/* remove address from local hash if present */
|
/* remove address from local hash if present */
|
||||||
batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr,
|
local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
|
||||||
"global tt received",
|
"global tt received",
|
||||||
flags & BATADV_TT_CLIENT_ROAM);
|
flags & BATADV_TT_CLIENT_ROAM);
|
||||||
ret = 1;
|
tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (tt_global_entry)
|
if (tt_global_entry)
|
||||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||||
|
@ -842,22 +855,10 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
primary_if = batadv_seq_print_text_primary_if_get(seq);
|
||||||
if (!primary_if) {
|
if (!primary_if)
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - please specify interfaces to enable it\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (primary_if->if_status != BATADV_IF_ACTIVE) {
|
|
||||||
ret = seq_printf(seq,
|
|
||||||
"BATMAN mesh %s disabled - primary interface not active\n",
|
|
||||||
net_dev->name);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(seq,
|
seq_printf(seq,
|
||||||
"Globally announced TT entries received via the mesh %s\n",
|
"Globally announced TT entries received via the mesh %s\n",
|
||||||
|
@ -881,7 +882,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
out:
|
out:
|
||||||
if (primary_if)
|
if (primary_if)
|
||||||
batadv_hardif_free_ref(primary_if);
|
batadv_hardif_free_ref(primary_if);
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* deletes the orig list of a tt_global_entry */
|
/* deletes the orig list of a tt_global_entry */
|
||||||
|
@ -2438,7 +2439,7 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
|
||||||
if (!tt_global_entry)
|
if (!tt_global_entry)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
|
ret = !!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM);
|
||||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -24,9 +24,9 @@ int batadv_tt_len(int changes_num);
|
||||||
int batadv_tt_init(struct batadv_priv *bat_priv);
|
int batadv_tt_init(struct batadv_priv *bat_priv);
|
||||||
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
||||||
int ifindex);
|
int ifindex);
|
||||||
void batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
||||||
const uint8_t *addr, const char *message,
|
const uint8_t *addr, const char *message,
|
||||||
bool roaming);
|
bool roaming);
|
||||||
int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
|
void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
|
||||||
struct batadv_orig_node *orig_node,
|
struct batadv_orig_node *orig_node,
|
||||||
|
|
|
@ -28,20 +28,30 @@
|
||||||
(ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
|
(ETH_HLEN + max(sizeof(struct batadv_unicast_packet), \
|
||||||
sizeof(struct batadv_bcast_packet)))
|
sizeof(struct batadv_bcast_packet)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct batadv_hard_iface_bat_iv - per hard interface B.A.T.M.A.N. IV data
|
||||||
|
* @ogm_buff: buffer holding the OGM packet
|
||||||
|
* @ogm_buff_len: length of the OGM packet buffer
|
||||||
|
* @ogm_seqno: OGM sequence number - used to identify each OGM
|
||||||
|
*/
|
||||||
|
struct batadv_hard_iface_bat_iv {
|
||||||
|
unsigned char *ogm_buff;
|
||||||
|
int ogm_buff_len;
|
||||||
|
atomic_t ogm_seqno;
|
||||||
|
};
|
||||||
|
|
||||||
struct batadv_hard_iface {
|
struct batadv_hard_iface {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
int16_t if_num;
|
int16_t if_num;
|
||||||
char if_status;
|
char if_status;
|
||||||
struct net_device *net_dev;
|
struct net_device *net_dev;
|
||||||
atomic_t seqno;
|
|
||||||
atomic_t frag_seqno;
|
atomic_t frag_seqno;
|
||||||
unsigned char *packet_buff;
|
|
||||||
int packet_len;
|
|
||||||
struct kobject *hardif_obj;
|
struct kobject *hardif_obj;
|
||||||
atomic_t refcount;
|
atomic_t refcount;
|
||||||
struct packet_type batman_adv_ptype;
|
struct packet_type batman_adv_ptype;
|
||||||
struct net_device *soft_iface;
|
struct net_device *soft_iface;
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
|
struct batadv_hard_iface_bat_iv bat_iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue