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