Skip to content

Commit a73105b

Browse files
Antonio Quartulliecsv
authored andcommitted
batman-adv: improved client announcement mechanism
The client announcement mechanism informs every mesh node in the network of any connected non-mesh client, in order to find the path towards that client from any given point in the mesh. The old implementation was based on the simple idea of appending a data buffer to each OGM containing all the client MAC addresses the node is serving. All other nodes can populate their global translation tables (table which links client MAC addresses to node addresses) using this MAC address buffer and linking it to the node's address contained in the OGM. A node that wants to contact a client has to lookup the node the client is connected to and its address in the global translation table. It is easy to understand that this implementation suffers from several issues: - big overhead (each and every OGM contains the entire list of connected clients) - high latencies for client route updates due to long OGM trip time and OGM losses The new implementation addresses these issues by appending client changes (new client joined or a client left) to the OGM instead of filling it with all the client addresses each time. In this way nodes can modify their global tables by means of "updates", thus reducing the overhead within the OGMs. To keep the entire network in sync each node maintains a translation table version number (ttvn) and a translation table checksum. These values are spread with the OGM to allow all the network participants to determine whether or not they need to update their translation table information. When a translation table lookup is performed in order to send a packet to a client attached to another node, the destination's ttvn is added to the payload packet. Forwarding nodes can compare the packet's ttvn with their destination's ttvn (this node could have a fresher information than the source) and re-route the packet if necessary. This greatly reduces the packet loss of clients roaming from one AP to the next. Signed-off-by: Antonio Quartulli <ordex@autistici.org> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Sven Eckelmann <sven@narfation.org>
1 parent 3b27ffb commit a73105b

File tree

18 files changed

+1381
-305
lines changed

18 files changed

+1381
-305
lines changed

net/batman-adv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
config BATMAN_ADV
66
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
77
depends on NET
8+
select CRC16
89
default n
910
---help---
1011

net/batman-adv/aggregation.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,12 @@
2020
*/
2121

2222
#include "main.h"
23+
#include "translation-table.h"
2324
#include "aggregation.h"
2425
#include "send.h"
2526
#include "routing.h"
2627
#include "hard-interface.h"
2728

28-
/* calculate the size of the tt information for a given packet */
29-
static int tt_len(const struct batman_packet *batman_packet)
30-
{
31-
return batman_packet->num_tt * ETH_ALEN;
32-
}
33-
3429
/* return true if new_packet can be aggregated with forw_packet */
3530
static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
3631
int packet_len,
@@ -264,18 +259,20 @@ void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
264259
batman_packet = (struct batman_packet *)packet_buff;
265260

266261
do {
267-
/* network to host order for our 32bit seqno, and the
268-
orig_interval. */
262+
/* network to host order for our 32bit seqno and the
263+
orig_interval */
269264
batman_packet->seqno = ntohl(batman_packet->seqno);
265+
batman_packet->tt_crc = ntohs(batman_packet->tt_crc);
270266

271267
tt_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
272-
receive_bat_packet(ethhdr, batman_packet,
273-
tt_buff, tt_len(batman_packet),
274-
if_incoming);
275268

276-
buff_pos += BAT_PACKET_LEN + tt_len(batman_packet);
269+
receive_bat_packet(ethhdr, batman_packet, tt_buff, if_incoming);
270+
271+
buff_pos += BAT_PACKET_LEN +
272+
tt_len(batman_packet->tt_num_changes);
273+
277274
batman_packet = (struct batman_packet *)
278275
(packet_buff + buff_pos);
279276
} while (aggregated_packet(buff_pos, packet_len,
280-
batman_packet->num_tt));
277+
batman_packet->tt_num_changes));
281278
}

net/batman-adv/aggregation.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
#include "main.h"
2626

2727
/* is there another aggregated packet here? */
28-
static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
28+
static inline int aggregated_packet(int buff_pos, int packet_len,
29+
int tt_num_changes)
2930
{
30-
int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_tt * ETH_ALEN);
31+
int next_buff_pos = buff_pos + BAT_PACKET_LEN + (tt_num_changes *
32+
sizeof(struct tt_change));
3133

3234
return (next_buff_pos <= packet_len) &&
3335
(next_buff_pos <= MAX_AGGREGATION_BYTES);

net/batman-adv/bat_sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
375375
static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
376376
store_gw_bwidth);
377377
#ifdef CONFIG_BATMAN_ADV_DEBUG
378-
BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL);
378+
BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 7, NULL);
379379
#endif
380380

381381
static struct bat_attribute *mesh_attrs[] = {

net/batman-adv/hard-interface.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
152152
batman_packet->ttl = TTL;
153153

154154
primary_if_update_addr(bat_priv);
155-
156-
/***
157-
* hacky trick to make sure that we send the TT information via
158-
* our new primary interface
159-
*/
160-
atomic_set(&bat_priv->tt_local_changed, 1);
161155
}
162156

163157
static bool hardif_is_iface_up(const struct hard_iface *hard_iface)
@@ -340,7 +334,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
340334
batman_packet->flags = NO_FLAGS;
341335
batman_packet->ttl = 2;
342336
batman_packet->tq = TQ_MAX_VALUE;
343-
batman_packet->num_tt = 0;
337+
batman_packet->tt_num_changes = 0;
338+
batman_packet->ttvn = 0;
344339

345340
hard_iface->if_num = bat_priv->num_ifaces;
346341
bat_priv->num_ifaces++;
@@ -659,6 +654,10 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
659654
case BAT_VIS:
660655
ret = recv_vis_packet(skb, hard_iface);
661656
break;
657+
/* Translation table query (request or response) */
658+
case BAT_TT_QUERY:
659+
ret = recv_tt_query(skb, hard_iface);
660+
break;
662661
default:
663662
ret = NET_RX_DROP;
664663
}

net/batman-adv/main.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ int mesh_init(struct net_device *soft_iface)
8686
spin_lock_init(&bat_priv->forw_bcast_list_lock);
8787
spin_lock_init(&bat_priv->tt_lhash_lock);
8888
spin_lock_init(&bat_priv->tt_ghash_lock);
89+
spin_lock_init(&bat_priv->tt_changes_list_lock);
90+
spin_lock_init(&bat_priv->tt_req_list_lock);
91+
spin_lock_init(&bat_priv->tt_buff_lock);
8992
spin_lock_init(&bat_priv->gw_list_lock);
9093
spin_lock_init(&bat_priv->vis_hash_lock);
9194
spin_lock_init(&bat_priv->vis_list_lock);
@@ -96,14 +99,13 @@ int mesh_init(struct net_device *soft_iface)
9699
INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
97100
INIT_HLIST_HEAD(&bat_priv->gw_list);
98101
INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids);
102+
INIT_LIST_HEAD(&bat_priv->tt_changes_list);
103+
INIT_LIST_HEAD(&bat_priv->tt_req_list);
99104

100105
if (originator_init(bat_priv) < 1)
101106
goto err;
102107

103-
if (tt_local_init(bat_priv) < 1)
104-
goto err;
105-
106-
if (tt_global_init(bat_priv) < 1)
108+
if (tt_init(bat_priv) < 1)
107109
goto err;
108110

109111
tt_local_add(soft_iface, soft_iface->dev_addr);
@@ -137,8 +139,7 @@ void mesh_free(struct net_device *soft_iface)
137139
gw_node_purge(bat_priv);
138140
originator_free(bat_priv);
139141

140-
tt_local_free(bat_priv);
141-
tt_global_free(bat_priv);
142+
tt_free(bat_priv);
142143

143144
softif_neigh_purge(bat_priv);
144145

net/batman-adv/main.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,15 @@
4646
/* sliding packet range of received originator messages in squence numbers
4747
* (should be a multiple of our word size) */
4848
#define TQ_LOCAL_WINDOW_SIZE 64
49+
#define TT_REQUEST_TIMEOUT 3 /* seconds we have to keep pending tt_req */
50+
4951
#define TQ_GLOBAL_WINDOW_SIZE 5
5052
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
5153
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
5254
#define TQ_TOTAL_BIDRECT_LIMIT 1
5355

56+
#define TT_OGM_APPEND_MAX 3 /* number of OGMs sent with the last tt diff */
57+
5458
#define NO_FLAGS 0
5559

5660
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
@@ -96,7 +100,8 @@ enum mesh_state {
96100
enum dbg_level {
97101
DBG_BATMAN = 1 << 0,
98102
DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
99-
DBG_ALL = 3
103+
DBG_TT = 1 << 2, /* translation table operations */
104+
DBG_ALL = 7
100105
};
101106

102107

net/batman-adv/originator.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
145145
tt_global_del_orig(orig_node->bat_priv, orig_node,
146146
"originator timed out");
147147

148+
kfree(orig_node->tt_buff);
148149
kfree(orig_node->bcast_own);
149150
kfree(orig_node->bcast_own_sum);
150151
kfree(orig_node);
@@ -213,6 +214,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
213214
spin_lock_init(&orig_node->ogm_cnt_lock);
214215
spin_lock_init(&orig_node->bcast_seqno_lock);
215216
spin_lock_init(&orig_node->neigh_list_lock);
217+
spin_lock_init(&orig_node->tt_buff_lock);
216218

217219
/* extra reference for return */
218220
atomic_set(&orig_node->refcount, 2);
@@ -221,6 +223,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
221223
memcpy(orig_node->orig, addr, ETH_ALEN);
222224
orig_node->router = NULL;
223225
orig_node->tt_buff = NULL;
226+
orig_node->tt_buff_len = 0;
227+
atomic_set(&orig_node->tt_size, 0);
224228
orig_node->bcast_seqno_reset = jiffies - 1
225229
- msecs_to_jiffies(RESET_PROTECTION_MS);
226230
orig_node->batman_seqno_reset = jiffies - 1
@@ -330,9 +334,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
330334
if (purge_orig_neighbors(bat_priv, orig_node,
331335
&best_neigh_node)) {
332336
update_routes(bat_priv, orig_node,
333-
best_neigh_node,
334-
orig_node->tt_buff,
335-
orig_node->tt_buff_len);
337+
best_neigh_node);
336338
}
337339
}
338340

net/batman-adv/packet.h

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ enum bat_packettype {
3030
BAT_UNICAST = 0x03,
3131
BAT_BCAST = 0x04,
3232
BAT_VIS = 0x05,
33-
BAT_UNICAST_FRAG = 0x06
33+
BAT_UNICAST_FRAG = 0x06,
34+
BAT_TT_QUERY = 0x07
3435
};
3536

3637
/* this file is included by batctl which needs these defines */
@@ -63,6 +64,25 @@ enum unicast_frag_flags {
6364
UNI_FRAG_LARGETAIL = 1 << 1
6465
};
6566

67+
/* TT_QUERY subtypes */
68+
#define TT_QUERY_TYPE_MASK 0x3
69+
70+
enum tt_query_packettype {
71+
TT_REQUEST = 0,
72+
TT_RESPONSE = 1
73+
};
74+
75+
/* TT_QUERY flags */
76+
enum tt_query_flags {
77+
TT_FULL_TABLE = 1 << 2
78+
};
79+
80+
/* TT_CHANGE flags */
81+
enum tt_change_flags {
82+
TT_CHANGE_DEL = 0x01,
83+
TT_CLIENT_ROAM = 0x02
84+
};
85+
6686
struct batman_packet {
6787
uint8_t packet_type;
6888
uint8_t version; /* batman version field */
@@ -73,8 +93,9 @@ struct batman_packet {
7393
uint8_t prev_sender[6];
7494
uint8_t gw_flags; /* flags related to gateway class */
7595
uint8_t tq;
76-
uint8_t num_tt;
77-
uint8_t reserved;
96+
uint8_t tt_num_changes;
97+
uint8_t ttvn; /* translation table version number */
98+
uint16_t tt_crc;
7899
} __packed;
79100

80101
#define BAT_PACKET_LEN sizeof(struct batman_packet)
@@ -112,15 +133,15 @@ struct unicast_packet {
112133
uint8_t packet_type;
113134
uint8_t version; /* batman version field */
114135
uint8_t ttl;
115-
uint8_t reserved;
136+
uint8_t ttvn; /* destination translation table version number */
116137
uint8_t dest[6];
117138
} __packed;
118139

119140
struct unicast_frag_packet {
120141
uint8_t packet_type;
121142
uint8_t version; /* batman version field */
122143
uint8_t ttl;
123-
uint8_t reserved;
144+
uint8_t ttvn; /* destination translation table version number */
124145
uint8_t dest[6];
125146
uint8_t flags;
126147
uint8_t align;
@@ -150,4 +171,32 @@ struct vis_packet {
150171
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
151172
} __packed;
152173

174+
struct tt_query_packet {
175+
uint8_t packet_type;
176+
uint8_t version; /* batman version field */
177+
uint8_t ttl;
178+
/* the flag field is a combination of:
179+
* - TT_REQUEST or TT_RESPONSE
180+
* - TT_FULL_TABLE */
181+
uint8_t flags;
182+
uint8_t dst[ETH_ALEN];
183+
uint8_t src[ETH_ALEN];
184+
/* the ttvn field is:
185+
* if TT_REQUEST: ttvn that triggered the
186+
* request
187+
* if TT_RESPONSE: new ttvn for the src
188+
* orig_node */
189+
uint8_t ttvn;
190+
/* tt_data field is:
191+
* if TT_REQUEST: crc associated with the
192+
* ttvn
193+
* if TT_RESPONSE: table_size */
194+
uint16_t tt_data;
195+
} __packed;
196+
197+
struct tt_change {
198+
uint8_t flags;
199+
uint8_t addr[ETH_ALEN];
200+
} __packed;
201+
153202
#endif /* _NET_BATMAN_ADV_PACKET_H_ */

0 commit comments

Comments
 (0)