Commit e6e94e39 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge

Antonio Quartulli says:

====================
Included changes:
- a set of codestyle rearrangements/fixes
- new feature to early detect new joining (mesh-unaware) clients
- a minor fix for the gw-feature
- substitution of shift operations with the BIT() macro
- reorganization of the main batman-adv structure (struct batadv_priv)
- some more (very) minor cleanups and fixes
===================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f63c45e0 fa4f0afc
......@@ -75,9 +75,10 @@ folder:
There is a special folder for debugging information:
# ls /sys/kernel/debug/batman_adv/bat0/
# bla_claim_table log socket transtable_local
# gateways originators transtable_global vis_data
# ls /sys/kernel/debug/batman_adv/bat0/
# bla_backbone_table log transtable_global
# bla_claim_table originators transtable_local
# gateways socket vis_data
Some of the files contain all sort of status information regard-
ing the mesh network. For example, you can view the table of
......
......@@ -166,13 +166,15 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
int16_t buff_pos;
struct batadv_ogm_packet *batadv_ogm_packet;
struct sk_buff *skb;
uint8_t *packet_pos;
if (hard_iface->if_status != BATADV_IF_ACTIVE)
return;
packet_num = 0;
buff_pos = 0;
batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
packet_pos = forw_packet->skb->data;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
/* adjust all flags and log packets */
while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
......@@ -181,15 +183,17 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
/* we might have aggregated direct link packets with an
* ordinary base packet
*/
if ((forw_packet->direct_link_flags & (1 << packet_num)) &&
(forw_packet->if_incoming == hard_iface))
if (forw_packet->direct_link_flags & BIT(packet_num) &&
forw_packet->if_incoming == hard_iface)
batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
else
batadv_ogm_packet->flags &= ~BATADV_DIRECTLINK;
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
"Sending own" :
"Forwarding"));
if (packet_num > 0 || !forw_packet->own)
fwd_str = "Forwarding";
else
fwd_str = "Sending own";
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"%s %spacket (originator %pM, seqno %u, TQ %d, TTL %d, IDF %s, ttvn %d) on interface %s [%pM]\n",
fwd_str, (packet_num > 0 ? "aggregated " : ""),
......@@ -204,8 +208,8 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
buff_pos += BATADV_OGM_HLEN;
buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
packet_num++;
batadv_ogm_packet = (struct batadv_ogm_packet *)
(forw_packet->skb->data + buff_pos);
packet_pos = forw_packet->skb->data + buff_pos;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
}
/* create clone because function is called more than once */
......@@ -227,9 +231,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
struct batadv_hard_iface *primary_if = NULL;
struct batadv_ogm_packet *batadv_ogm_packet;
unsigned char directlink;
uint8_t *packet_pos;
batadv_ogm_packet = (struct batadv_ogm_packet *)
(forw_packet->skb->data);
packet_pos = forw_packet->skb->data;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
directlink = (batadv_ogm_packet->flags & BATADV_DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
......@@ -454,6 +459,7 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
int packet_len, bool direct_link)
{
unsigned char *skb_buff;
unsigned long new_direct_link_flag;
skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
memcpy(skb_buff, packet_buff, packet_len);
......@@ -461,9 +467,10 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
forw_packet_aggr->num_packets++;
/* save packet direct link flag status */
if (direct_link)
forw_packet_aggr->direct_link_flags |=
(1 << forw_packet_aggr->num_packets);
if (direct_link) {
new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
}
}
static void batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
......@@ -586,6 +593,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
struct batadv_ogm_packet *batadv_ogm_packet;
struct batadv_hard_iface *primary_if;
int vis_server, tt_num_changes = 0;
uint32_t seqno;
uint8_t bandwidth;
vis_server = atomic_read(&bat_priv->vis_mode);
primary_if = batadv_primary_if_get_selected(bat_priv);
......@@ -599,12 +608,12 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet = (struct batadv_ogm_packet *)hard_iface->packet_buff;
/* change sequence number to network order */
batadv_ogm_packet->seqno =
htonl((uint32_t)atomic_read(&hard_iface->seqno));
seqno = (uint32_t)atomic_read(&hard_iface->seqno);
batadv_ogm_packet->seqno = htonl(seqno);
atomic_inc(&hard_iface->seqno);
batadv_ogm_packet->ttvn = atomic_read(&bat_priv->ttvn);
batadv_ogm_packet->tt_crc = htons(bat_priv->tt_crc);
batadv_ogm_packet->ttvn = atomic_read(&bat_priv->tt.vn);
batadv_ogm_packet->tt_crc = htons(bat_priv->tt.local_crc);
if (tt_num_changes >= 0)
batadv_ogm_packet->tt_num_changes = tt_num_changes;
......@@ -613,12 +622,13 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
else
batadv_ogm_packet->flags &= ~BATADV_VIS_SERVER;
if ((hard_iface == primary_if) &&
(atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER))
batadv_ogm_packet->gw_flags =
(uint8_t)atomic_read(&bat_priv->gw_bandwidth);
else
if (hard_iface == primary_if &&
atomic_read(&bat_priv->gw_mode) == BATADV_GW_MODE_SERVER) {
bandwidth = (uint8_t)atomic_read(&bat_priv->gw_bandwidth);
batadv_ogm_packet->gw_flags = bandwidth;
} else {
batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
}
batadv_slide_own_bcast_window(hard_iface);
batadv_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
......@@ -642,8 +652,9 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
struct batadv_neigh_node *router = NULL;
struct batadv_orig_node *orig_node_tmp;
struct hlist_node *node;
uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
uint8_t sum_orig, sum_neigh;
uint8_t *neigh_addr;
uint8_t tq_avg;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"update_originator(): Searching and updating originator entry of received packet\n");
......@@ -667,8 +678,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
spin_lock_bh(&tmp_neigh_node->lq_update_lock);
batadv_ring_buffer_set(tmp_neigh_node->tq_recv,
&tmp_neigh_node->tq_index, 0);
tmp_neigh_node->tq_avg =
batadv_ring_buffer_avg(tmp_neigh_node->tq_recv);
tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv);
tmp_neigh_node->tq_avg = tq_avg;
spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
}
......@@ -727,17 +738,15 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
if (router && (neigh_node->tq_avg == router->tq_avg)) {
orig_node_tmp = router->orig_node;
spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
bcast_own_sum_orig =
orig_node_tmp->bcast_own_sum[if_incoming->if_num];
sum_orig = orig_node_tmp->bcast_own_sum[if_incoming->if_num];
spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
orig_node_tmp = neigh_node->orig_node;
spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
bcast_own_sum_neigh =
orig_node_tmp->bcast_own_sum[if_incoming->if_num];
sum_neigh = orig_node_tmp->bcast_own_sum[if_incoming->if_num];
spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
if (bcast_own_sum_orig >= bcast_own_sum_neigh)
if (sum_orig >= sum_neigh)
goto update_tt;
}
......@@ -835,8 +844,10 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
spin_unlock_bh(&orig_node->ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */
total_count = (orig_eq_count > neigh_rq_count ?
neigh_rq_count : orig_eq_count);
if (orig_eq_count > neigh_rq_count)
total_count = neigh_rq_count;
else
total_count = orig_eq_count;
/* if we have too few packets (too less data) we set tq_own to zero
* if we receive too few packets it is not considered bidirectional
......@@ -910,6 +921,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
int set_mark, ret = -1;
uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
uint8_t *neigh_addr;
uint8_t packet_count;
orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
if (!orig_node)
......@@ -944,9 +956,9 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
tmp_neigh_node->real_bits,
seq_diff, set_mark);
tmp_neigh_node->real_packet_count =
bitmap_weight(tmp_neigh_node->real_bits,
BATADV_TQ_LOCAL_WINDOW_SIZE);
packet_count = bitmap_weight(tmp_neigh_node->real_bits,
BATADV_TQ_LOCAL_WINDOW_SIZE);
tmp_neigh_node->real_packet_count = packet_count;
}
rcu_read_unlock();
......@@ -1163,9 +1175,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
/* if sender is a direct neighbor the sender mac equals
* originator mac
*/
orig_neigh_node = (is_single_hop_neigh ?
orig_node :
batadv_get_orig_node(bat_priv, ethhdr->h_source));
if (is_single_hop_neigh)
orig_neigh_node = orig_node;
else
orig_neigh_node = batadv_get_orig_node(bat_priv,
ethhdr->h_source);
if (!orig_neigh_node)
goto out;
......@@ -1251,6 +1266,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
int buff_pos = 0, packet_len;
unsigned char *tt_buff, *packet_buff;
bool ret;
uint8_t *packet_pos;
ret = batadv_check_management_packet(skb, if_incoming, BATADV_OGM_HLEN);
if (!ret)
......@@ -1281,8 +1297,8 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
buff_pos += BATADV_OGM_HLEN;
buff_pos += batadv_tt_len(batadv_ogm_packet->tt_num_changes);
batadv_ogm_packet = (struct batadv_ogm_packet *)
(packet_buff + buff_pos);
packet_pos = packet_buff + buff_pos;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_pos;
} while (batadv_iv_ogm_aggr_packet(buff_pos, packet_len,
batadv_ogm_packet->tt_num_changes));
......
This diff is collapsed.
......@@ -27,6 +27,8 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid);
int batadv_bla_is_backbone_gw(struct sk_buff *skb,
struct batadv_orig_node *orig_node, int hdr_size);
int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
void *offset);
int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t *orig);
int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
struct batadv_bcast_packet *bcast_packet,
......@@ -41,8 +43,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv);
#else /* ifdef CONFIG_BATMAN_ADV_BLA */
static inline int batadv_bla_rx(struct batadv_priv *bat_priv,
struct sk_buff *skb, short vid,
bool is_bcast)
struct sk_buff *skb, short vid, bool is_bcast)
{
return 0;
}
......@@ -66,6 +67,12 @@ static inline int batadv_bla_claim_table_seq_print_text(struct seq_file *seq,
return 0;
}
static inline int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
void *offset)
{
return 0;
}
static inline int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv,
uint8_t *orig)
{
......
......@@ -267,6 +267,15 @@ static int batadv_bla_claim_table_open(struct inode *inode, struct file *file)
return single_open(file, batadv_bla_claim_table_seq_print_text,
net_dev);
}
static int batadv_bla_backbone_table_open(struct inode *inode,
struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, batadv_bla_backbone_table_seq_print_text,
net_dev);
}
#endif
static int batadv_transtable_local_open(struct inode *inode, struct file *file)
......@@ -305,6 +314,8 @@ static BATADV_DEBUGINFO(transtable_global, S_IRUGO,
batadv_transtable_global_open);
#ifdef CONFIG_BATMAN_ADV_BLA
static BATADV_DEBUGINFO(bla_claim_table, S_IRUGO, batadv_bla_claim_table_open);
static BATADV_DEBUGINFO(bla_backbone_table, S_IRUGO,
batadv_bla_backbone_table_open);
#endif
static BATADV_DEBUGINFO(transtable_local, S_IRUGO,
batadv_transtable_local_open);
......@@ -316,6 +327,7 @@ static struct batadv_debuginfo *batadv_mesh_debuginfos[] = {
&batadv_debuginfo_transtable_global,
#ifdef CONFIG_BATMAN_ADV_BLA
&batadv_debuginfo_bla_claim_table,
&batadv_debuginfo_bla_backbone_table,
#endif
&batadv_debuginfo_transtable_local,
&batadv_debuginfo_vis_data,
......
......@@ -48,7 +48,7 @@ batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
struct batadv_gw_node *gw_node;
rcu_read_lock();
gw_node = rcu_dereference(bat_priv->curr_gw);
gw_node = rcu_dereference(bat_priv->gw.curr_gw);
if (!gw_node)
goto out;
......@@ -91,23 +91,23 @@ static void batadv_gw_select(struct batadv_priv *bat_priv,
{
struct batadv_gw_node *curr_gw_node;
spin_lock_bh(&bat_priv->gw_list_lock);
spin_lock_bh(&bat_priv->gw.list_lock);
if (new_gw_node && !atomic_inc_not_zero(&new_gw_node->refcount))
new_gw_node = NULL;
curr_gw_node = rcu_dereference_protected(bat_priv->curr_gw, 1);
rcu_assign_pointer(bat_priv->curr_gw, new_gw_node);
curr_gw_node = rcu_dereference_protected(bat_priv->gw.curr_gw, 1);
rcu_assign_pointer(bat_priv->gw.curr_gw, new_gw_node);
if (curr_gw_node)
batadv_gw_node_free_ref(curr_gw_node);
spin_unlock_bh(&bat_priv->gw_list_lock);
spin_unlock_bh(&bat_priv->gw.list_lock);
}
void batadv_gw_deselect(struct batadv_priv *bat_priv)
{
atomic_set(&bat_priv->gw_reselect, 1);
atomic_set(&bat_priv->gw.reselect, 1);
}
static struct batadv_gw_node *
......@@ -117,12 +117,17 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
struct hlist_node *node;
struct batadv_gw_node *gw_node, *curr_gw = NULL;
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
uint32_t gw_divisor;
uint8_t max_tq = 0;
int down, up;
uint8_t tq_avg;
struct batadv_orig_node *orig_node;
gw_divisor = BATADV_TQ_LOCAL_WINDOW_SIZE * BATADV_TQ_LOCAL_WINDOW_SIZE;
gw_divisor *= 64;
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
if (gw_node->deleted)
continue;
......@@ -134,19 +139,19 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
if (!atomic_inc_not_zero(&gw_node->refcount))
goto next;
tq_avg = router->tq_avg;
switch (atomic_read(&bat_priv->gw_sel_class)) {
case 1: /* fast connection */
batadv_gw_bandwidth_to_kbit(orig_node->gw_flags,
&down, &up);
tmp_gw_factor = (router->tq_avg * router->tq_avg *
down * 100 * 100) /
(BATADV_TQ_LOCAL_WINDOW_SIZE *
BATADV_TQ_LOCAL_WINDOW_SIZE * 64);
tmp_gw_factor = tq_avg * tq_avg * down * 100 * 100;
tmp_gw_factor /= gw_divisor;
if ((tmp_gw_factor > max_gw_factor) ||
((tmp_gw_factor == max_gw_factor) &&
(router->tq_avg > max_tq))) {
(tq_avg > max_tq))) {
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);
curr_gw = gw_node;
......@@ -161,7 +166,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
* soon as a better gateway appears which has
* $routing_class more tq points)
*/
if (router->tq_avg > max_tq) {
if (tq_avg > max_tq) {
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);
curr_gw = gw_node;
......@@ -170,8 +175,8 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
break;
}
if (router->tq_avg > max_tq)
max_tq = router->tq_avg;
if (tq_avg > max_tq)
max_tq = tq_avg;
if (tmp_gw_factor > max_gw_factor)
max_gw_factor = tmp_gw_factor;
......@@ -202,7 +207,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw)
if (!batadv_atomic_dec_not_zero(&bat_priv->gw.reselect) && curr_gw)
goto out;
next_gw = batadv_gw_get_best_gw_node(bat_priv);
......@@ -321,9 +326,9 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
gw_node->orig_node = orig_node;
atomic_set(&gw_node->refcount, 1);
spin_lock_bh(&bat_priv->gw_list_lock);
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list);
spin_unlock_bh(&bat_priv->gw_list_lock);
spin_lock_bh(&bat_priv->gw.list_lock);
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
spin_unlock_bh(&bat_priv->gw.list_lock);
batadv_gw_bandwidth_to_kbit(new_gwflags, &down, &up);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
......@@ -350,7 +355,7 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
if (gw_node->orig_node != orig_node)
continue;
......@@ -404,10 +409,10 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
spin_lock_bh(&bat_priv->gw_list_lock);
spin_lock_bh(&bat_priv->gw.list_lock);
hlist_for_each_entry_safe(gw_node, node, node_tmp,
&bat_priv->gw_list, list) {
&bat_priv->gw.list, list) {
if (((!gw_node->deleted) ||
(time_before(jiffies, gw_node->deleted + timeout))) &&
atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE)
......@@ -420,7 +425,7 @@ void batadv_gw_node_purge(struct batadv_priv *bat_priv)
batadv_gw_node_free_ref(gw_node);
}
spin_unlock_bh(&bat_priv->gw_list_lock);
spin_unlock_bh(&bat_priv->gw.list_lock);
/* gw_deselect() needs to acquire the gw_list_lock */
if (do_deselect)
......@@ -496,7 +501,7 @@ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset)
primary_if->net_dev->dev_addr, net_dev->name);
rcu_read_lock();
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) {
hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw.list, list) {
if (gw_node->deleted)
continue;
......
......@@ -103,13 +103,14 @@ static void batadv_primary_if_update_addr(struct batadv_priv *bat_priv,
{
struct batadv_vis_packet *vis_packet;
struct batadv_hard_iface *primary_if;
struct sk_buff *skb;
primary_if = batadv_primary_if_get_selected(bat_priv);
if (!primary_if)
goto out;
vis_packet = (struct batadv_vis_packet *)
bat_priv->my_vis_info->skb_packet->data;
skb = bat_priv->vis.my_info->skb_packet;
vis_packet = (struct batadv_vis_packet *)skb->data;
memcpy(vis_packet->vis_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
memcpy(vis_packet->sender_orig,
primary_if->net_dev->dev_addr, ETH_ALEN);
......@@ -313,7 +314,13 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
hard_iface->if_num = bat_priv->num_ifaces;
bat_priv->num_ifaces++;
hard_iface->if_status = BATADV_IF_INACTIVE;
batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
ret = batadv_orig_hash_add_if(hard_iface, bat_priv->num_ifaces);
if (ret < 0) {
bat_priv->bat_algo_ops->bat_iface_disable(hard_iface);
bat_priv->num_ifaces--;
hard_iface->if_status = BATADV_IF_NOT_IN_USE;
goto err_dev;
}
hard_iface->batman_adv_ptype.type = ethertype;
hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
......
......@@ -58,9 +58,6 @@ static int __init batadv_init(void)
batadv_iv_init();
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/
*/
batadv_event_workqueue = create_singlethread_workqueue("bat_events");
if (!batadv_event_workqueue)
......@@ -97,20 +94,20 @@ int batadv_mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->forw_bat_list_lock);
spin_lock_init(&bat_priv->forw_bcast_list_lock);
spin_lock_init(&bat_priv->tt_changes_list_lock);
spin_lock_init(&bat_priv->tt_req_list_lock);
spin_lock_init(&bat_priv->tt_roam_list_lock);
spin_lock_init(&bat_priv->tt_buff_lock);
spin_lock_init(&bat_priv->gw_list_lock);
spin_lock_init(&bat_priv->vis_hash_lock);
spin_lock_init(&bat_priv->vis_list_lock);
spin_lock_init(&bat_priv->tt.changes_list_lock);
spin_lock_init(&bat_priv->tt.req_list_lock);
spin_lock_init(&bat_priv->tt.roam_list_lock);
spin_lock_init(&bat_priv->tt.last_changeset_lock);
spin_lock_init(&bat_priv->gw.list_lock);
spin_lock_init(&bat_priv->vis.hash_lock);
spin_lock_init(&bat_priv->vis.list_lock);
INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
INIT_HLIST_HEAD(&bat_priv->gw_list);
INIT_LIST_HEAD(&bat_priv->tt_changes_list);
INIT_LIST_HEAD(&bat_priv->tt_req_list);
INIT_LIST_HEAD(&bat_priv->tt_roam_list);
INIT_HLIST_HEAD(&bat_priv->gw.list);
INIT_LIST_HEAD(&bat_priv->tt.changes_list);
INIT_LIST_HEAD(&bat_priv->tt.req_list);
INIT_LIST_HEAD(&bat_priv->tt.roam_list);
ret = batadv_originator_init(bat_priv);
if (ret < 0)
......@@ -131,7 +128,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
if (ret < 0)
goto err;
atomic_set(&bat_priv->gw_reselect, 0);
atomic_set(&bat_priv->gw.reselect, 0);
atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
return 0;
......
......@@ -26,7 +26,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2012.3.0"
#define BATADV_SOURCE_VERSION "2012.4.0"
#endif
/* B.A.T.M.A.N. parameters */
......@@ -41,13 +41,14 @@
* -> TODO: check influence on BATADV_TQ_LOCAL_WINDOW_SIZE
*/
#define BATADV_PURGE_TIMEOUT 200000 /* 200 seconds */
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in miliseconds */
#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in miliseconds */
#define BATADV_TT_LOCAL_TIMEOUT 3600000 /* in milliseconds */
#define BATADV_TT_CLIENT_ROAM_TIMEOUT 600000 /* in milliseconds */
#define BATADV_TT_CLIENT_TEMP_TIMEOUT 600000 /* in milliseconds */
/* sliding packet range of received originator messages in sequence numbers
* (should be a multiple of our word size)
*/
#define BATADV_TQ_LOCAL_WINDOW_SIZE 64
/* miliseconds we have to keep pending tt_req */
/* milliseconds we have to keep pending tt_req */
#define BATADV_TT_REQUEST_TIMEOUT 3000
#define BATADV_TQ_GLOBAL_WINDOW_SIZE 5
......@@ -59,7 +60,7 @@
#define BATADV_TT_OGM_APPEND_MAX 3
/* Time in which a client can roam at most ROAMING_MAX_COUNT times in
* miliseconds
* milliseconds
*/
#define BATADV_ROAMING_MAX_TIME 20000
#define BATADV_ROAMING_MAX_COUNT 5
......@@ -123,15 +124,6 @@ enum batadv_uev_type {
/* Append 'batman-adv: ' before kernel messages */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
/* all messages related to routing / flooding / broadcasting / etc */
enum batadv_dbg_level {
BATADV_DBG_BATMAN = 1 << 0,
BATADV_DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
BATADV_DBG_TT = 1 << 2, /* translation table operations */
BATADV_DBG_BLA = 1 << 3, /* bridge loop avoidance */
BATADV_DBG_ALL = 15,
};
/* Kernel headers */
#include <linux/mutex.h> /* mutex */
......@@ -173,6 +165,15 @@ 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_seq_print_text(struct seq_file *seq, void *offset);
/* all messages related to routing / flooding / broadcasting / etc */
enum batadv_dbg_level {
BATADV_DBG_BATMAN = BIT(0),
BATADV_DBG_ROUTES = BIT(1), /* route added / changed / deleted */
BATADV_DBG_TT = BIT(2), /* translation table operations */
BATADV_DBG_BLA = BIT(3), /* bridge loop avoidance */
BATADV_DBG_ALL = 15,
};
#ifdef CONFIG_BATMAN_ADV_DEBUG
int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
__printf(2, 3);
......
......@@ -37,10 +37,10 @@ enum batadv_packettype {
#define BATADV_COMPAT_VERSION 14
enum batadv_iv_flags {
BATADV_NOT_BEST_NEXT_HOP = 1 << 3,
BATADV_PRIMARIES_FIRST_HOP = 1 << 4,
BATADV_VIS_SERVER = 1 << 5,
BATADV_DIRECTLINK = 1 << 6,
BATADV_NOT_BEST_NEXT_HOP = BIT(3),
BATADV_PRIMARIES_FIRST_HOP = BIT(4),
BATADV_VIS_SERVER = BIT(5),
BATADV_DIRECTLINK = BIT(6),
};
/* ICMP message types */
......@@ -60,8 +60,8 @@ enum batadv_vis_packettype {
/* fragmentation defines */
enum batadv_unicast_frag_flags {
BATADV_UNI_FRAG_HEAD = 1 << 0,
BATADV_UNI_FRAG_LARGETAIL = 1 << 1,
BATADV_UNI_FRAG_HEAD = BIT(0),
BATADV_UNI_FRAG_LARGETAIL = BIT(1),
};
/* TT_QUERY subtypes */
......@@ -74,26 +74,27 @@ enum batadv_tt_query_packettype {
/* TT_QUERY flags */
enum batadv_tt_query_flags {
BATADV_TT_FULL_TABLE = 1 << 2,
BATADV_TT_FULL_TABLE = BIT(2),
};
/* BATADV_TT_CLIENT flags.
* Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to
* 1 << 15 are used for local computation only
* Flags from BIT(0) to BIT(7) are sent on the wire, while flags from BIT(8) to
* BIT(15) are used for local computation only
*/
enum batadv_tt_client_flags {
BATADV_TT_CLIENT_DEL = 1 << 0,
BATADV_TT_CLIENT_ROAM = 1 << 1,
BATADV_TT_CLIENT_WIFI = 1 << 2,
BATADV_TT_CLIENT_NOPURGE = 1 << 8,
BATADV_TT_CLIENT_NEW = 1 << 9,
BATADV_TT_CLIENT_PENDING = 1 << 10,
BATADV_TT_CLIENT_DEL = BIT(0),
BATADV_TT_CLIENT_ROAM = BIT(1),
BATADV_TT_CLIENT_WIFI = BIT(2),
BATADV_TT_CLIENT_TEMP = BIT(3),
BATADV_TT_CLIENT_NOPURGE = BIT(8),
BATADV_TT_CLIENT_NEW = BIT(9),
BATADV_TT_CLIENT_PENDING = BIT(10),
};
/* claim frame types for the bridge loop avoidance */
enum batadv_bla_claimframe {
BATADV_CLAIM_TYPE_ADD = 0x00,
BATADV_CLAIM_TYPE_DEL = 0x01,
BATADV_CLAIM_TYPE_CLAIM = 0x00,
BATADV_CLAIM_TYPE_UNCLAIM = 0x01,
BATADV_CLAIM_TYPE_ANNOUNCE = 0x02,
BATADV_CLAIM_TYPE_REQUEST = 0x03,
};
......
......@@ -579,32 +579,45 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
return router;
}
int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_tt_query_packet *tt_query;
uint16_t tt_size;
struct ethhdr *ethhdr;
char tt_flag;
size_t packet_size;
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb,
sizeof(struct batadv_tt_query_packet))))
goto out;
/* I could need to modify it */
if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
goto out;
if (unlikely(!pskb_may_pull(skb, hdr_size)))
return -1;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* packet with unicast indication but broadcast recipient */
if (is_broadcast_ether_addr(ethhdr->h_dest))
goto out;
return -1;
/* packet with broadcast sender address */
if (is_broadcast_ether_addr(ethhdr->h_source))
return -1;
/* not for me */
if (!batadv_is_my_mac(ethhdr->h_dest))
return -1;
return 0;
}
int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_tt_query_packet *tt_query;
uint16_t tt_size;
int hdr_size = sizeof(*tt_query);
char tt_flag;
size_t packet_size;
if (batadv_check_unicast_packet(skb, hdr_size) < 0)
return NET_RX_DROP;
/* I could need to modify it */
if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
goto out;
tt_query = (struct batadv_tt_query_packet *)skb->data;
......@@ -721,7 +734,7 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
* been incremented yet. This flag will make me check all the incoming
* packets for the correct destination.
*/
bat_priv->tt_poss_change = true;
bat_priv->tt.poss_change = true;
batadv_orig_node_free_ref(orig_node);
out:
......@@ -819,31 +832,6 @@ batadv_find_router(struct batadv_priv *bat_priv,
return NULL;
}
static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size)
{
struct ethhdr *ethhdr;
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb, hdr_size)))
return -1;
ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* packet with unicast indication but broadcast recipient */
if (is_broadcast_ether_addr(ethhdr->h_dest))
return -1;
/* packet with broadcast sender address */
if (is_broadcast_ether_addr(ethhdr->h_source))
return -1;
/* not for me */
if (!batadv_is_my_mac(ethhdr->h_dest))
return -1;
return 0;
}
static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if)
{
......@@ -947,8 +935,8 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
unicast_packet = (struct batadv_unicast_packet *)skb->data;
if (batadv_is_my_mac(unicast_packet->dest)) {
tt_poss_change = bat_priv->tt_poss_change;
curr_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn);
tt_poss_change = bat_priv->tt.poss_change;
curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
} else {
orig_node = batadv_orig_hash_find(bat_priv,
unicast_packet->dest);
......@@ -993,8 +981,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
} else {
memcpy(unicast_packet->dest, orig_node->orig,
ETH_ALEN);
curr_ttvn = (uint8_t)
atomic_read(&orig_node->last_ttvn);
curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
batadv_orig_node_free_ref(orig_node);
}
......@@ -1025,8 +1012,9 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
/* packet for me */
if (batadv_is_my_mac(unicast_packet->dest)) {
batadv_interface_rx(recv_if->soft_iface, skb, recv_if,
hdr_size);
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
NULL);
return NET_RX_SUCCESS;
}
......@@ -1063,7 +1051,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
return NET_RX_SUCCESS;
batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
sizeof(struct batadv_unicast_packet));
sizeof(struct batadv_unicast_packet), NULL);
return NET_RX_SUCCESS;
}
......@@ -1150,7 +1138,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
goto out;
/* broadcast for me */
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
orig_node);
ret = NET_RX_SUCCESS;
goto out;
......
......@@ -190,13 +190,13 @@ int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
{
struct batadv_hard_iface *hard_iface;
struct delayed_work *delayed_work =
container_of(work, struct delayed_work, work);
struct delayed_work *delayed_work;
struct batadv_forw_packet *forw_packet;
struct sk_buff *skb1;
struct net_device *soft_iface;
struct batadv_priv *bat_priv;
delayed_work = container_of(work, struct delayed_work, work);
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work);
soft_iface = forw_packet->if_incoming->soft_iface;
......@@ -239,11 +239,11 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work)
{
struct delayed_work *delayed_work =
container_of(work, struct delayed_work, work);
struct delayed_work *delayed_work;
struct batadv_forw_packet *forw_packet;
struct batadv_priv *bat_priv;
delayed_work = container_of(work, struct delayed_work, work);
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work);
bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
......
......@@ -93,7 +93,14 @@ static int batadv_interface_release(struct net_device *dev)
static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
{
struct batadv_priv *bat_priv = netdev_priv(dev);
return &bat_priv->stats;
struct net_device_stats *stats = &bat_priv->stats;
stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX);
stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES);
stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED);
stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX);
stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES);
return stats;
}
static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
......@@ -142,6 +149,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
int data_len = skb->len, ret;
short vid __maybe_unused = -1;
bool do_bcast = false;
uint32_t seqno;
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
goto dropped;
......@@ -223,8 +231,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
primary_if->net_dev->dev_addr, ETH_ALEN);
/* set broadcast sequence number */
bcast_packet->seqno =
htonl(atomic_inc_return(&bat_priv->bcast_seqno));
seqno = atomic_inc_return(&bat_priv->bcast_seqno);
bcast_packet->seqno = htonl(seqno);
batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
......@@ -246,14 +254,14 @@ static int batadv_interface_tx(struct sk_buff *skb,
goto dropped_freed;
}
bat_priv->stats.tx_packets++;
bat_priv->stats.tx_bytes += data_len;
batadv_inc_counter(bat_priv, BATADV_CNT_TX);
batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len);
goto end;
dropped:
kfree_skb(skb);
dropped_freed:
bat_priv->stats.tx_dropped++;
batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
end:
if (primary_if)
batadv_hardif_free_ref(primary_if);
......@@ -262,7 +270,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
void batadv_interface_rx(struct net_device *soft_iface,
struct sk_buff *skb, struct batadv_hard_iface *recv_if,
int hdr_size)
int hdr_size, struct batadv_orig_node *orig_node)
{
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
struct ethhdr *ethhdr;
......@@ -308,11 +316,16 @@ void batadv_interface_rx(struct net_device *soft_iface,
/* skb->ip_summed = CHECKSUM_UNNECESSARY; */
bat_priv->stats.rx_packets++;
bat_priv->stats.rx_bytes += skb->len + ETH_HLEN;
batadv_inc_counter(bat_priv, BATADV_CNT_RX);
batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
skb->len + ETH_HLEN);
soft_iface->last_rx = jiffies;
if (orig_node)
batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
ethhdr->h_source);
if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
goto dropped;
......@@ -379,15 +392,22 @@ struct net_device *batadv_softif_create(const char *name)
if (!soft_iface)
goto out;
bat_priv = netdev_priv(soft_iface);
/* batadv_interface_stats() needs to be available as soon as
* register_netdevice() has been called
*/
bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
if (!bat_priv->bat_counters)
goto free_soft_iface;
ret = register_netdevice(soft_iface);
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
goto free_soft_iface;
goto free_bat_counters;
}
bat_priv = netdev_priv(soft_iface);
atomic_set(&bat_priv->aggregated_ogms, 1);
atomic_set(&bat_priv->bonding, 0);
atomic_set(&bat_priv->bridge_loop_avoidance, 0);
......@@ -405,29 +425,26 @@ struct net_device *batadv_softif_create(const char *name)
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
atomic_set(&bat_priv->bcast_seqno, 1);
atomic_set(&bat_priv->ttvn, 0);
atomic_set(&bat_priv->tt_local_changes, 0);
atomic_set(&bat_priv->tt_ogm_append_cnt, 0);
atomic_set(&bat_priv->bla_num_requests, 0);
bat_priv->tt_buff = NULL;
bat_priv->tt_buff_len = 0;
bat_priv->tt_poss_change = false;
atomic_set(&bat_priv->tt.vn, 0);
atomic_set(&bat_priv->tt.local_changes, 0);
atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
#ifdef CONFIG_BATMAN_ADV_BLA
atomic_set(&bat_priv->bla.num_requests, 0);
#endif
bat_priv->tt.last_changeset = NULL;
bat_priv->tt.last_changeset_len = 0;
bat_priv->tt.poss_change = false;
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
if (!bat_priv->bat_counters)
goto unreg_soft_iface;
ret = batadv_algo_select(bat_priv, batadv_routing_algo);
if (ret < 0)
goto free_bat_counters;
goto unreg_soft_iface;
ret = batadv_sysfs_add_meshif(soft_iface);
if (ret < 0)
goto free_bat_counters;
goto unreg_soft_iface;
ret = batadv_debugfs_add_meshif(soft_iface);
if (ret < 0)
......@@ -443,12 +460,13 @@ struct net_device *batadv_softif_create(const char *name)
batadv_debugfs_del_meshif(soft_iface);
unreg_sysfs:
batadv_sysfs_del_meshif(soft_iface);
free_bat_counters:
free_percpu(bat_priv->bat_counters);
unreg_soft_iface:
free_percpu(bat_priv->bat_counters);
unregister_netdevice(soft_iface);
return NULL;
free_bat_counters:
free_percpu(bat_priv->bat_counters);
free_soft_iface:
free_netdev(soft_iface);
out:
......@@ -518,6 +536,11 @@ static u32 batadv_get_link(struct net_device *dev)
static const struct {
const char name[ETH_GSTRING_LEN];
} batadv_counters_strings[] = {
{ "tx" },
{ "tx_bytes" },
{ "tx_dropped" },
{ "rx" },
{ "rx_bytes" },
{ "forward" },
{ "forward_bytes" },
{ "mgmt_tx" },
......
......@@ -21,8 +21,9 @@
#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len);
void batadv_interface_rx(struct net_device *soft_iface, struct sk_buff *skb,
struct batadv_hard_iface *recv_if, int hdr_size);
void batadv_interface_rx(struct net_device *soft_iface,
struct sk_buff *skb, struct batadv_hard_iface *recv_if,
int hdr_size, struct batadv_orig_node *orig_node);
struct net_device *batadv_softif_create(const char *name);
void batadv_softif_destroy(struct net_device *soft_iface);
int batadv_softif_is_valid(const struct net_device *net_dev);
......
This diff is collapsed.
......@@ -59,6 +59,8 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
int packet_min_len);
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
uint8_t *addr);
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
const unsigned char *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
......@@ -145,6 +145,11 @@ struct batadv_bcast_duplist_entry {
#endif
enum batadv_counters {
BATADV_CNT_TX,
BATADV_CNT_TX_BYTES,
BATADV_CNT_TX_DROPPED,
BATADV_CNT_RX,
BATADV_CNT_RX_BYTES,
BATADV_CNT_FORWARD,
BATADV_CNT_FORWARD_BYTES,
BATADV_CNT_MGMT_TX,
......@@ -160,6 +165,67 @@ enum batadv_counters {
BATADV_CNT_NUM,
};
/**
* struct batadv_priv_tt - per mesh interface translation table data
* @vn: translation table version number
* @local_changes: changes registered in an originator interval
* @poss_change: Detect an ongoing roaming phase. If true, then this node
* received a roaming_adv and has to inspect every packet directed to it to
* check whether it still is the true destination or not. This flag will be
* reset to false as soon as the this node's ttvn is increased
* @changes_list: tracks tt local changes within an originator interval
* @req_list: list of pending tt_requests
* @local_crc: Checksum of the local table, recomputed before sending a new OGM
*/
struct batadv_priv_tt {
atomic_t vn;
atomic_t ogm_append_cnt;
atomic_t local_changes;
bool poss_change;
struct list_head changes_list;
struct batadv_hashtable *local_hash;
struct batadv_hashtable *global_hash;
struct list_head req_list;
struct list_head roam_list;
spinlock_t changes_list_lock; /* protects changes */
spinlock_t req_list_lock; /* protects req_list */
spinlock_t roam_list_lock; /* protects roam_list */
atomic_t local_entry_num;
uint16_t local_crc;
unsigned char *last_changeset;
int16_t last_changeset_len;
spinlock_t last_changeset_lock; /* protects last_changeset */
struct delayed_work work;
};
#ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_priv_bla {
atomic_t num_requests; /* number of bla requests in flight */
struct batadv_hashtable *claim_hash;
struct batadv_hashtable *backbone_hash;
struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE];
int bcast_duplist_curr;
struct batadv_bla_claim_dst claim_dest;
struct delayed_work work;
};
#endif
struct batadv_priv_gw {
struct hlist_head list;
spinlock_t list_lock; /* protects gw_list and curr_gw */
struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
atomic_t reselect;
};
struct batadv_priv_vis {
struct list_head send_list;
struct batadv_hashtable *hash;
spinlock_t hash_lock; /* protects hash */
spinlock_t list_lock; /* protects info::recv_list */
struct delayed_work work;
struct batadv_vis_info *my_info;
};
struct batadv_priv {
atomic_t mesh_state;
struct net_device_stats stats;
......@@ -179,64 +245,24 @@ struct batadv_priv {
atomic_t bcast_seqno;
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
atomic_t ttvn; /* translation table version number */
atomic_t tt_ogm_append_cnt;
atomic_t tt_local_changes; /* changes registered in a OGM interval */
atomic_t bla_num_requests; /* number of bla requests in flight */
/* The tt_poss_change flag is used to detect an ongoing roaming phase.
* If true, then I received a Roaming_adv and I have to inspect every
* packet directed to me to check whether I am still the true
* destination or not. This flag will be reset to false as soon as I
* increase my TTVN
*/
bool tt_poss_change;
char num_ifaces;
struct batadv_debug_log *debug_log;
struct kobject *mesh_obj;
struct dentry *debug_dir;
struct hlist_head forw_bat_list;
struct hlist_head forw_bcast_list;
struct hlist_head gw_list;
struct list_head tt_changes_list; /* tracks changes in a OGM int */
struct list_head vis_send_list;
struct batadv_hashtable *orig_hash;
struct batadv_hashtable *tt_local_hash;
struct batadv_hashtable *tt_global_hash;
#ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_hashtable *claim_hash;
struct batadv_hashtable *backbone_hash;
#endif
struct list_head tt_req_list; /* list of pending tt_requests */
struct list_head tt_roam_list;
struct batadv_hashtable *vis_hash;
#ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE];
int bcast_duplist_curr;
struct batadv_bla_claim_dst claim_dest;
#endif
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
spinlock_t forw_bcast_list_lock; /* protects */
spinlock_t tt_changes_list_lock; /* protects tt_changes */
spinlock_t tt_req_list_lock; /* protects tt_req_list */
spinlock_t tt_roam_list_lock; /* protects tt_roam_list */
spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
spinlock_t vis_hash_lock; /* protects vis_hash */
spinlock_t vis_list_lock; /* protects vis_info::recv_list */
atomic_t num_local_tt;
/* Checksum of the local table, recomputed before sending a new OGM */
uint16_t tt_crc;
unsigned char *tt_buff;
int16_t tt_buff_len;
spinlock_t tt_buff_lock; /* protects tt_buff */
struct delayed_work tt_work;
struct delayed_work orig_work;
struct delayed_work vis_work;
struct delayed_work bla_work;
struct batadv_gw_node __rcu *curr_gw; /* rcu protected pointer */
atomic_t gw_reselect;
struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */
struct batadv_vis_info *my_vis_info;
struct batadv_algo_ops *bat_algo_ops;
#ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_priv_bla bla;
#endif
struct batadv_priv_gw gw;
struct batadv_priv_tt tt;
struct batadv_priv_vis vis;
};
struct batadv_socket_client {
......@@ -258,6 +284,7 @@ struct batadv_tt_common_entry {
uint8_t addr[ETH_ALEN];
struct hlist_node hash_entry;
uint16_t flags;
unsigned long added_at;
atomic_t refcount;
struct rcu_head rcu;
};
......@@ -277,6 +304,7 @@ struct batadv_tt_global_entry {
struct batadv_tt_orig_list_entry {
struct batadv_orig_node *orig_node;
uint8_t ttvn;
atomic_t refcount;
struct rcu_head rcu;
struct hlist_node list;
};
......
......@@ -39,6 +39,7 @@ batadv_frag_merge_packet(struct list_head *head,
struct batadv_unicast_packet *unicast_packet;
int hdr_len = sizeof(*unicast_packet);
int uni_diff = sizeof(*up) - hdr_len;
uint8_t *packet_pos;
up = (struct batadv_unicast_frag_packet *)skb->data;
/* set skb to the first part and tmp_skb to the second part */
......@@ -65,8 +66,8 @@ batadv_frag_merge_packet(struct list_head *head,
kfree_skb(tmp_skb);
memmove(skb->data + uni_diff, skb->data, hdr_len);
unicast_packet = (struct batadv_unicast_packet *)skb_pull(skb,
uni_diff);
packet_pos = skb_pull(skb, uni_diff);
unicast_packet = (struct batadv_unicast_packet *)packet_pos;
unicast_packet->header.packet_type = BATADV_UNICAST;
return skb;
......@@ -121,6 +122,7 @@ batadv_frag_search_packet(struct list_head *head,
{
struct batadv_frag_packet_list_entry *tfp;
struct batadv_unicast_frag_packet *tmp_up = NULL;
int is_head_tmp, is_head;
uint16_t search_seqno;
if (up->flags & BATADV_UNI_FRAG_HEAD)
......@@ -128,6 +130,8 @@ batadv_frag_search_packet(struct list_head *head,
else
search_seqno = ntohs(up->seqno)-1;
is_head = !!(up->flags & BATADV_UNI_FRAG_HEAD);
list_for_each_entry(tfp, head, list) {
if (!tfp->skb)
......@@ -139,9 +143,8 @@ batadv_frag_search_packet(struct list_head *head,
tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
if (tfp->seqno == search_seqno) {
if ((tmp_up->flags & BATADV_UNI_FRAG_HEAD) !=
(up->flags & BATADV_UNI_FRAG_HEAD))
is_head_tmp = !!(tmp_up->flags & BATADV_UNI_FRAG_HEAD);
if (is_head_tmp != is_head)
return tfp;
else
goto mov_tail;
......@@ -334,8 +337,7 @@ int batadv_unicast_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv)
/* copy the destination for faster routing */
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
/* set the destination tt version number */
unicast_packet->ttvn =
(uint8_t)atomic_read(&orig_node->last_ttvn);
unicast_packet->ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
/* inform the destination node that we are still missing a correct route
* for this client. The destination will receive this packet and will
......
This diff is collapsed.
......@@ -20,7 +20,7 @@
#ifndef _NET_BATMAN_ADV_VIS_H_
#define _NET_BATMAN_ADV_VIS_H_
/* timeout of vis packets in miliseconds */
/* timeout of vis packets in milliseconds */
#define BATADV_VIS_TIMEOUT 200000
int batadv_vis_seq_print_text(struct seq_file *seq, void *offset);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment