Hi,
Marek and I have been chatting a little about the buggy vis raw
output yesterday. And there was either the option to sort the
mixed list on the receiving vis server or on the sender already.
For the second option there was also the idea of changing the vis
packet format accordingly to also save some more overhead.
Currently, we're sending a mixed list of (src,dest,quality) with
the struct vis_info_entry. Instead, the idea for a new format was
the following:
vis_packet.entries = number of source interfaces of this originator
followed by tuples
{src,num_neighbours,num_neighbours x {dest,quality}}
for each source interface of a node.
Additionally, the first entry shall be the one of the primary
interface already.
I've made a little prototype patch, see the attachment for this
(it applies on top of Simon's last vis_refcount additions patch).
I haven't done the more difficult part yet, the sorting and
structuring that has to be done in the generate_vis_packet()
instead now.
If you think this kind of format is ok, then I'd like to have some
more opinions of how to deal with the structuring in the
generate_vis_packet(). My idea so far is, to create num_if lists
and malloc and copy the information for every neighbour of an
originator during the locked orig_hash iteration and freeing as
well as packing those list after realeasing the lock. Or, if the
mallocs might take too much time for being used so often during
the lock, to allocate num_ifs buffers with the maximum
vis_packet size (currently 1000B) for each interface batman is
using before entering the spinlock. And I guess, that anyway
num_ifs would have to be made an atomic_t, right?
Cheers, Linus
PS: Could someone explain, why the recv_list_add() is being done
with a sender_orig instead of vis_orig? Because if using vis_orig,
then we could get rid of the sender_orig as well because of having
this information in the ethernet header already.
@@ -92,5 +92,4 @@
uint8_t vis_orig[6]; /* originator that informs about its
* neighbors */
uint8_t target_orig[6]; /* who should receive this packet */
- uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __attribute__((packed));
@@ -368,10 +368,6 @@
{
HASHIT(hashit);
struct vis_info *info;
- struct vis_info_entry *entries;
- HLIST_HEAD(vis_if_list);
- int i;
- char tmp_addr_str[ETH_STR_LEN];
unsigned long flags;
int vis_server = atomic_read(&vis_mode);
@@ -386,19 +382,7 @@
spin_lock_irqsave(&vis_hash_lock, flags);
while (hash_iterate(vis_hash, &hashit)) {
info = hashit.bucket->data;
- entries = (struct vis_info_entry *)
- ((char *)info + sizeof(struct vis_info));
- addr_to_string(tmp_addr_str, info->packet.vis_orig);
- seq_printf(seq, "%s,", tmp_addr_str);
-
- for (i = 0; i < info->packet.entries; i++) {
- proc_vis_read_entry(seq, &entries[i], &vis_if_list,
- info->packet.vis_orig);
- }
-
- /* add primary/secondary records */
- proc_vis_read_prim_sec(seq, &vis_if_list);
- seq_printf(seq, "\n");
+ proc_vis_read_entry(seq, info);
}
spin_unlock_irqrestore(&vis_hash_lock, flags);
@@ -954,7 +954,7 @@
if (is_my_mac(vis_packet->vis_orig))
return NET_RX_DROP;
- if (is_my_mac(vis_packet->sender_orig))
+ if (is_my_mac(ethhdr->h_source))
return NET_RX_DROP;
switch (vis_packet->vis_type) {
@@ -85,65 +85,65 @@
return hash % size;
}
-/* insert interface to the list of interfaces of one originator, if it
- * does not already exist in the list */
-static void proc_vis_insert_interface(const uint8_t *interface,
- struct hlist_head *if_list,
- bool primary)
-{
- struct if_list_entry *entry;
- struct hlist_node *pos;
-
- hlist_for_each_entry(entry, pos, if_list, list) {
- if (compare_orig(entry->addr, (void *)interface))
- return;
- }
+void proc_vis_read_prim_sec(struct seq_file *seq, struct vis_info *info)
+{
+ int i;
+ char tmp_addr_str[ETH_STR_LEN];
- /* its a new address, add it to the list */
- entry = kmalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return;
- memcpy(entry->addr, interface, ETH_ALEN);
- entry->primary = primary;
- hlist_add_head(&entry->list, if_list);
+ struct vis_if_entry *if_entry = (struct vis_if_entry *)
+ ((char *)info + sizeof(struct vis_info));
+
+ seq_printf(seq, "PRIMARY, ");
+ for (i = 1; i < info->packet.entries; i++) {
+ addr_to_string(tmp_addr_str, if_entry->src);
+ seq_printf(seq, "SEC %s, ", tmp_addr_str);
+
+ if_entry = if_entry + sizeof(struct vis_if_entry) +
+ if_entry->num_neigh * sizeof(struct vis_neigh_entry);
+ }
}
-void proc_vis_read_prim_sec(struct seq_file *seq,
- struct hlist_head *if_list)
+/* read neighbor entries belonging to a source interface */
+void proc_vis_read_neigh(struct seq_file *seq, struct vis_if_entry *if_entry)
{
- struct if_list_entry *entry;
- struct hlist_node *pos, *n;
- char tmp_addr_str[ETH_STR_LEN];
+ int i;
+ char dest_addr_str[ETH_STR_LEN];
+ struct vis_neigh_entry *neigh_entry = (struct vis_neigh_entry*)
+ ((char*) if_entry + sizeof(struct vis_if_entry));
- hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
- if (entry->primary) {
- seq_printf(seq, "PRIMARY, ");
- } else {
- addr_to_string(tmp_addr_str, entry->addr);
- seq_printf(seq, "SEC %s, ", tmp_addr_str);
- }
+ for (i = 0; i < if_entry->num_neigh; i++) {
+ addr_to_string(dest_addr_str, neigh_entry->dest);
+ if (neigh_entry->quality == 0)
+ seq_printf(seq, "HNA %s, ", dest_addr_str);
+ else
+ seq_printf(seq, "TQ %s %d, ", dest_addr_str,
+ neigh_entry->quality);
- hlist_del(&entry->list);
- kfree(entry);
+ neigh_entry = neigh_entry + sizeof(struct vis_neigh_entry);
}
}
-/* read an entry */
-void proc_vis_read_entry(struct seq_file *seq,
- struct vis_info_entry *entry,
- struct hlist_head *if_list,
- uint8_t *vis_orig)
-{
- char to[40];
-
- addr_to_string(to, entry->dest);
- if (entry->quality == 0) {
- proc_vis_insert_interface(vis_orig, if_list, true);
- seq_printf(seq, "HNA %s, ", to);
- } else {
- proc_vis_insert_interface(entry->src, if_list,
- compare_orig(entry->src, vis_orig));
- seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+/* read source interface entries belonging to an originator */
+void proc_vis_read_entry(struct seq_file *seq, struct vis_info *info)
+{
+ int i;
+ char src_addr_str[ETH_STR_LEN];
+
+ struct vis_if_entry *if_entry = (struct vis_if_entry *)
+ ((char *)info + sizeof(struct vis_info));
+
+ for (i = 0; i < info->packet.entries; i++) {
+ addr_to_string(src_addr_str, if_entry->src);
+ seq_printf(seq, "%s,", src_addr_str);
+ proc_vis_read_neigh(seq, if_entry);
+
+ /* add primary/secondary records, if src-if = primary */
+ if (i == 0)
+ proc_vis_read_prim_sec(seq, info);
+
+ seq_printf(seq, "\n");
+ if_entry = if_entry + sizeof(struct vis_if_entry) +
+ if_entry->num_neigh * sizeof(struct vis_neigh_entry);
}
}
@@ -223,7 +223,7 @@
if (vis_packet->seqno - old_info->packet.seqno <= 0) {
if (old_info->packet.seqno == vis_packet->seqno) {
recv_list_add(&old_info->recv_list,
- vis_packet->sender_orig);
+ vis_packet->vis_orig);
return old_info;
} else {
/* newer packet is already in hash. */
@@ -259,7 +259,7 @@
info->packet.entries = vis_info_len /
sizeof(struct vis_info_entry);
- recv_list_add(&info->recv_list, info->packet.sender_orig);
+ recv_list_add(&info->recv_list, info->packet.vis_orig);
/* try to add it */
if (hash_add(vis_hash, info) < 0) {
@@ -542,7 +542,6 @@
return;
}
- memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
info->packet.ttl--;
packet_length = sizeof(struct vis_packet) +
@@ -622,7 +621,6 @@
INIT_LIST_HEAD(&send_list);
memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
- memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
if (hash_add(vis_hash, my_vis_info) < 0) {
printk(KERN_ERR
@@ -35,9 +35,13 @@
/* vis_info may follow here*/
} __attribute__((packed));
-struct vis_info_entry {
+struct vis_if_entry {
uint8_t src[ETH_ALEN];
- uint8_t dest[ETH_ALEN];
+ uint8_t num_neigh;
+} __attribute__((packed));
+
+struct vis_neigh_entry {
+ uint8_t dest[ETH_ALEN]; /* neighbor's interface mac */
uint8_t quality; /* quality = 0 means HNA */
} __attribute__((packed));
@@ -49,12 +53,10 @@
extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock;
-void proc_vis_read_entry(struct seq_file *seq,
- struct vis_info_entry *entry,
- struct hlist_head *if_list,
- uint8_t *vis_orig);
-void proc_vis_read_prim_sec(struct seq_file *seq,
- struct hlist_head *if_list);
+void proc_vis_read_prim_sec(struct seq_file *seq, struct vis_info *info);
+void proc_vis_read_neigh(struct seq_file *seq, struct vis_if_entry *if_entry);
+void proc_vis_read_entry(struct seq_file *seq, struct vis_info *info);
+
void receive_server_sync_packet(struct vis_packet *vis_packet,
int vis_info_len);
void receive_client_update_packet(struct vis_packet *vis_packet,