Hi Greg.
Here are the patches again, this time with the right authorship. Sorry we messed it up and caused you extra work.
Thanks Andrew
Signed-off-by: Andrew Lunn andrew@lunn.ch
Andrew Lunn (2): Staging: batman-adv: Update TODO file to reflect current state. Staging: batman-adv: updating README
Dan Carpenter (1): Staging: batman-adv: cleanup: change test for end of array
Linus L?ssing (4): Staging: batman-adv: only modify hna-table on active module Staging: batman-adv: Fix aggregation direct-link bug Staging: batman-adv: Remove dead max addr and obsolete VIS_FORMAT strings Staging: batman-adv: Update README about vis raw output
Luis de Bethencourt (1): Staging: batman-adv: fix whitespace style issues
Marek Lindner (6): Staging: batman-adv: fix aggregation timing bug Staging: batman-adv: convert multiple /proc files to use sysfs Staging: batman-adv: convert more files from /proc to /sys Staging: batman-adv: move originator interval setting from /proc to /sys Staging: batman-adv: remove redundant pointer to originator interface Staging: batman-adv: move /proc interface handling to /sys
Simon Wunderlich (7): Staging: batman-adv: Update copyright years Staging: batman-adv: remove the beta from main.h for release Staging: batman-adv: Add 0.2.1 changes to the CHANGELOG Staging: batman-adv: Changing version to 0.2.2-beta Staging: batman-adv: Reorganize sequence number handling Staging: batman-adv: Limit queue lengths for batman and broadcast packets Staging: batman-adv: kfree_skb() in interface_tx() in error case
Sven Eckelmann (5): Staging: batman-adv: Clone shared bat packets before modifying them Staging: batman-adv: fix whitespace style issues Staging: batman-adv: Update pointer to ethhdr after skb_copy Staging: batman-adv: Fix whitespace problems criticized by checkpatch.pl Staging: batman-adv: Reduce max characters on a line to 80
From: Linus Lüssing linus.luessing@web.de
If we haven't set the module to MODULE_ACTIVE state before (in general, no interface has yet been added to batman-adv) then the hna table is not initialised yet. If the kernel changes the mac address of the bat0 interface at this moment then an hna_local_add() called by interface_set_mac_addr() then resulted in a null pointer derefernce. With this patch we are now explicitly checking before if the state is MODULE_ACTIVE right now so that we can assume having an initialised hna table.
Signed-off-by: Linus Lüssing linus.luessing@web.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/soft-interface.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 0e2307f..a42b21f 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -152,9 +152,13 @@ int interface_set_mac_addr(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL;
- hna_local_remove(dev->dev_addr, "mac address changed"); + /* only modify hna-table if it has been initialised before */ + if (atomic_read(&module_state) == MODULE_ACTIVE) { + hna_local_remove(dev->dev_addr, "mac address changed"); + hna_local_add(addr->sa_data); + } + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - hna_local_add(dev->dev_addr);
return 0; }
From: Sven Eckelmann sven.eckelmann@gmx.de
"tcpdump" and "batctl td" will receive packets with a wrong sequence number on systems with a different endianess than network byte order. This happens due to the reordering of bytes in the function which handles aggregated bat packets. The function which receives the bat packets must ensure that these buffers aren't shared with anything else before that function tries to write into it. Otherwise it has to copy the buffers so it is save again to change them.
Reported-by: Kevin Steen batman@kevinsteen.net Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/routing.c | 16 ++++++++++++---- 1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index d89048b..39dd093 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -549,6 +549,7 @@ int recv_bat_packet(struct sk_buff *skb, { struct ethhdr *ethhdr; unsigned long flags; + struct sk_buff *skb_old;
/* drop packet if it has not necessary minimum size */ if (skb_headlen(skb) < sizeof(struct batman_packet)) @@ -564,12 +565,19 @@ int recv_bat_packet(struct sk_buff *skb, if (is_bcast(ethhdr->h_source)) return NET_RX_DROP;
- spin_lock_irqsave(&orig_hash_lock, flags); /* TODO: we use headlen instead of "length", because * only this data is paged in. */ - /* TODO: is another skb_copy needed here? there will be - * written on the data, but nobody (?) should further use - * this data */ + + /* create a copy of the skb, if needed, to modify it. */ + if (!skb_clone_writable(skb, skb_headlen(skb))) { + skb_old = skb; + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) + return NET_RX_DROP; + kfree_skb(skb_old); + } + + spin_lock_irqsave(&orig_hash_lock, flags); receive_aggr_bat_packet(ethhdr, skb->data, skb_headlen(skb),
From: Marek Lindner lindner_marek@yahoo.de
batman-adv aggregates routing packets to reduce the number of packets in the air. Every outgoing packet is compared with other packets in the buffer to determine whether it can be aggregated or not. Packets sent at a lower interval can be held back longer to maximize the aggregation. Due to insufficient checking batman-adv held back all packets for a certain time depending on its own lowest interval rate which slowed down all other nodes.
Reported-by: Linus Lüssing linus.luessing@web.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/aggregation.c | 12 ++++++++++++ drivers/staging/batman-adv/send.c | 10 +--------- 2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index 7917322..d25e5a8 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -52,6 +52,8 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, */
if (time_before(send_time, forw_packet->send_time) && + time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), + forw_packet->send_time) && (aggregated_bytes <= MAX_AGGREGATION_BYTES)) {
/** @@ -195,6 +197,16 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, if (forw_packet_aggr == NULL) { /* the following section can run without the lock */ spin_unlock_irqrestore(&forw_bat_list_lock, flags); + + /** + * if we could not aggregate this packet with one of the others + * we hold it back for a while, so that it might be aggregated + * later on + */ + if ((!own_packet) && + (atomic_read(&bat_priv->aggregation_enabled))) + send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); + new_aggregated_packet(packet_buff, packet_len, send_time, direct_link, if_incoming, own_packet); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index ff7b1f1..d356ce7 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -46,15 +46,7 @@ static unsigned long own_send_time(void) /* when do we schedule a forwarded packet to be sent */ static unsigned long forward_send_time(void) { - unsigned long send_time = jiffies; /* Starting now plus... */ - - if (atomic_read(&aggregation_enabled)) - send_time += (((MAX_AGGREGATION_MS - (JITTER/2) + - (random32() % JITTER)) * HZ) / 1000); - else - send_time += (((random32() % (JITTER/2)) * HZ) / 1000); - - return send_time; + return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000); }
/* send out an already prepared packet to the given address via the
From: Linus Lüssing linus.luessing@web.de
So far, neighbour's secondary interface OGMs can involuntarily piggyback on primary interface OGMs that arrived on the same secondary interface before. Secondary interface OGMs should NEVER leave their direct neighbour broadcast domain! This patch ensures that secondary interface OGMs can only be aggregated to other secondary interface OGMs.
Signed-off-by: Linus Lüssing linus.luessing@web.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/aggregation.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index d25e5a8..e1bd321 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -81,9 +81,15 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, * interface only - we still can aggregate */ if ((directlink) && (new_batman_packet->ttl == 1) && - (forw_packet->if_incoming == if_incoming)) + (forw_packet->if_incoming == if_incoming) && + + /* packets from direct neighbors or + * own secondary interface packets + * (= secondary interface packets in general) */ + (batman_packet->flags & DIRECTLINK || + (forw_packet->own && + forw_packet->if_incoming->if_num != 0))) return true; - }
return false; @@ -204,7 +210,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, * later on */ if ((!own_packet) && - (atomic_read(&bat_priv->aggregation_enabled))) + (atomic_read(&aggregation_enabled))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
new_aggregated_packet(packet_buff, packet_len,
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/aggregation.c | 2 +- drivers/staging/batman-adv/aggregation.h | 2 +- drivers/staging/batman-adv/bitarray.c | 2 +- drivers/staging/batman-adv/bitarray.h | 2 +- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/device.h | 2 +- drivers/staging/batman-adv/hard-interface.c | 2 +- drivers/staging/batman-adv/hard-interface.h | 2 +- drivers/staging/batman-adv/hash.c | 2 +- drivers/staging/batman-adv/hash.h | 2 +- drivers/staging/batman-adv/main.c | 2 +- drivers/staging/batman-adv/main.h | 2 +- drivers/staging/batman-adv/originator.c | 2 +- drivers/staging/batman-adv/originator.h | 2 +- drivers/staging/batman-adv/packet.h | 2 +- drivers/staging/batman-adv/proc.c | 2 +- drivers/staging/batman-adv/proc.h | 2 +- drivers/staging/batman-adv/ring_buffer.c | 2 +- drivers/staging/batman-adv/ring_buffer.h | 2 +- drivers/staging/batman-adv/routing.c | 2 +- drivers/staging/batman-adv/routing.h | 2 +- drivers/staging/batman-adv/send.c | 2 +- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/soft-interface.h | 2 +- drivers/staging/batman-adv/translation-table.c | 2 +- drivers/staging/batman-adv/translation-table.h | 2 +- drivers/staging/batman-adv/types.h | 2 +- drivers/staging/batman-adv/vis.c | 2 +- drivers/staging/batman-adv/vis.h | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 42b4e63..cf2915d 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: +# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: # # Marek Lindner, Simon Wunderlich # diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index e1bd321..b8338ce 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index 6da8df9..bcd32c1 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c index 212eef9..7848305 100644 --- a/drivers/staging/batman-adv/bitarray.c +++ b/drivers/staging/batman-adv/bitarray.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h index ec72dd7..76ad24c 100644 --- a/drivers/staging/batman-adv/bitarray.h +++ b/drivers/staging/batman-adv/bitarray.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 2f61500..c82a5af 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/device.h b/drivers/staging/batman-adv/device.h index 46c0f44..eb14b37 100644 --- a/drivers/staging/batman-adv/device.h +++ b/drivers/staging/batman-adv/device.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index befd488..cb9e927 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 97c6ecb..4100a27 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 5a2018d..d4a4adc 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index a70d6d6..ea6d21e 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner * diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2e0b482..a051568 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 2e9bb89..c943e89 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 29c2411..2ce1349 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 6ef7a05..8acebc1 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h index ad006ce..152f57b 100644 --- a/drivers/staging/batman-adv/packet.h +++ b/drivers/staging/batman-adv/packet.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index c9366bc..dfa85c4 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index cd690e0..cf71264 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/ring_buffer.c b/drivers/staging/batman-adv/ring_buffer.c index 751c899..defd37c 100644 --- a/drivers/staging/batman-adv/ring_buffer.c +++ b/drivers/staging/batman-adv/ring_buffer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/ring_buffer.h b/drivers/staging/batman-adv/ring_buffer.h index 6839ba9..b8c9456 100644 --- a/drivers/staging/batman-adv/ring_buffer.h +++ b/drivers/staging/batman-adv/ring_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 39dd093..b83e5cb 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h index 939b8d4..8288dec 100644 --- a/drivers/staging/batman-adv/routing.h +++ b/drivers/staging/batman-adv/routing.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index d356ce7..88ecb5c 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index 5fc6f34..b2ddf63 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index a42b21f..0dff959 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h index c0cad81..e7f59af 100644 --- a/drivers/staging/batman-adv/soft-interface.h +++ b/drivers/staging/batman-adv/soft-interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner * diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index d56f665..e446d90 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h index 281125b..8568d80 100644 --- a/drivers/staging/batman-adv/translation-table.h +++ b/drivers/staging/batman-adv/translation-table.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index dec1b54..4e77141 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich * diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 28eac7e..0bfc083 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich * diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index a1f92a4..98d8972 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 B.A.T.M.A.N. contributors: + * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner *
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/main.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index c943e89..5fdf5af 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -26,7 +26,7 @@ #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv"
-#define SOURCE_VERSION "0.2.1-beta" +#define SOURCE_VERSION "0.2.1"
/* B.A.T.M.A.N. parameters */
From: Linus Lüssing linus.luessing@web.de
Max address is not being used anywhere and just misleading, therefore removing it. VIS_FORMAT string is now obsolete, so also remove it.
Signed-off-by: Linus Lüssing linus.luessing@web.de Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/main.h | 2 -- drivers/staging/batman-adv/vis.h | 2 -- 2 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 5fdf5af..2494f5a 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -34,8 +34,6 @@ #define TQ_MAX_VALUE 255 #define JITTER 20 #define TTL 50 /* Time To Live of broadcast messages */ -#define MAX_ADDR 16 /* number of interfaces which can be added to - * batman. */
#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no * valid packet comes in -> TODO: check diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 98d8972..4e417fb 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -20,8 +20,6 @@ */
#define VIS_TIMEOUT 200000 -#define VIS_FORMAT_DD_NAME "dot_draw" -#define VIS_FORMAT_JSON_NAME "json"
struct vis_info { unsigned long first_seen;
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/CHANGELOG | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/batman-adv/CHANGELOG b/drivers/staging/batman-adv/CHANGELOG index 8a18163..c8f9d9e 100644 --- a/drivers/staging/batman-adv/CHANGELOG +++ b/drivers/staging/batman-adv/CHANGELOG @@ -1,3 +1,17 @@ +batman-adv 0.2.1: + +* support latest kernels (2.6.20 - 2.6.33) +* receive packets directly using skbs, remove old sockets and threads +* fix various regressions in the vis server +* don't disable interrupts while sending +* replace internal logging mechanism with standard kernel logging +* move vis formats into userland, one general format remains in the kernel +* allow MAC address to be set, correctly initialize them +* code refactoring and cleaning for coding style +* many bugs (null pointers, locking, hash iterators) squashed + + -- Sun, 21 Mar 2010 20:46:47 +0100 + batman-adv 0.2:
* support latest kernels (2.6.20 - 2.6.31)
From: Linus Lüssing linus.luessing@web.de
We are now having a newer, more neutral vis output so that we won't have to change the kernelmodule for adding support of new vis output formats. This patch adds an explanation about this in the README file of batman-adv and removes the description about the dot/json format (they will be added to the README of batctl).
Signed-off-by: Linus Lüssing linus.luessing@web.de Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/README | 36 ++++++++++++++++++++++++++++-------- 1 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index 7d666ad..e2a7271 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,4 +1,4 @@ -[state: 06-01-2010] +[state: 22-03-2010]
BATMAN-ADV ---------- @@ -44,10 +44,11 @@ regular interface: # ping 192.168.0.2 ...
+--- If you want topology visualization, your meshnode must be configured as VIS-server:
-# echo "server" > /proc/net/batman-adv/vis +# echo "server" > /proc/net/batman-adv/vis_server
Each node is either configured as "server" or as "client" (default: "client"). Clients send their topology data to the server next to them, @@ -58,12 +59,31 @@ more vis servers sharing the same (or at least very similar) data.
When configured as server, you can get a topology snapshot of your mesh:
-# cat /proc/net/batman-adv/vis - -The output is in a generic raw format. Use the batctl tool (See below) -to convert this to other formats more suitable for graphing, eg -graphviz dot, or JSON data-interchange format. - +# cat /proc/net/batman-adv/vis_data + +This raw output is intended to be easily parsable and convertable with +other tools. Have a look at the batctl README if you want a vis output +in dot or json format for instance and how those outputs could then be +visualised in an image. + +The raw format consists of comma seperated values per entry where each +entry is giving information about a certain source interface. Each entry +can/has to have the following values: +-> "mac" -> mac address of an originator's source interface + (each line begins with it) +-> "TQ mac value" -> src mac's link quality towards mac address of a neighbor + originator's interface which is being used for routing +-> "HNA mac" -> HNA announced by source mac +-> "PRIMARY" -> this is a primary interface +-> "SEC mac" -> secondary mac address of source (requires preceeding +-> PRIMARY) + +The TQ value has a range from 4 to 255 with 255 being the best. +The HNA entries are showing which hosts are connected to the mesh via bat0 +or being bridged into the mesh network. +The PRIMARY/SEC values are only applied on primary interfaces + +--- In very mobile scenarios, you might want to adjust the originator interval to a lower value. This will make the mesh more responsive to topology changes, but will also increase the overhead. Please make sure
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/main.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 2494f5a..6221b85 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -26,7 +26,7 @@ #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv"
-#define SOURCE_VERSION "0.2.1" +#define SOURCE_VERSION "0.2.2-beta"
/* B.A.T.M.A.N. parameters */
From: Dan Carpenter error27@gmail.com
The code here is testing to see if "i" is passed the end of the array. The original code works probably, but it's not the cleanest way.
Andrew Lunn suggested that I also remove all the hard coded references to 256 so I have done that as well.
Signed-off-by: Dan Carpenter error27@gmail.com Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/device.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index c82a5af..fbfe234 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -44,10 +44,7 @@ static struct device_client *device_client_hash[256];
void bat_device_init(void) { - int i; - - for (i = 0; i < 256; i++) - device_client_hash[i] = NULL; + memset(device_client_hash, 0, sizeof(device_client_hash)); }
int bat_device_setup(void) @@ -103,15 +100,15 @@ int bat_device_open(struct inode *inode, struct file *file) if (!device_client) return -ENOMEM;
- for (i = 0; i < 256; i++) { + for (i = 0; i < ARRAY_SIZE(device_client_hash); i++) { if (!device_client_hash[i]) { device_client_hash[i] = device_client; break; } }
- if (device_client_hash[i] != device_client) { - printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n"); + if (i == ARRAY_SIZE(device_client_hash)) { + printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached\n"); kfree(device_client); return -EXFULL; }
From: Luis de Bethencourt luisbg@ubuntu.com
This patch fixes the 31 unnecessary whitespaces before a quoted newline that the batman-adv files had.
Signed-off-by: Luis de Bethencourt luisbg@ubuntu.com [sven.eckelmann@gmx.de: Redone to apply against current version] Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/main.c | 2 +- drivers/staging/batman-adv/originator.c | 4 ++-- drivers/staging/batman-adv/routing.c | 18 +++++++++--------- drivers/staging/batman-adv/send.c | 4 ++-- drivers/staging/batman-adv/translation-table.c | 14 +++++++------- 6 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index fbfe234..9887f05 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -65,7 +65,7 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv");
if (IS_ERR(batman_class)) { - printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n"); + printk(KERN_ERR "batman-adv:Could not register class 'batman-adv'\n"); return 0; }
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index a051568..881aaa9 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -119,7 +119,7 @@ int init_module(void) register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type);
- printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n", + printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
return 0; diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 2ce1349..f3d8cc3 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -126,7 +126,7 @@ struct orig_node *get_orig_node(uint8_t *addr) if (orig_node != NULL) return orig_node;
- bat_dbg(DBG_BATMAN, "Creating new originator: %pM \n", addr); + bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr);
orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); if (!orig_node) @@ -158,7 +158,7 @@ struct orig_node *get_orig_node(uint8_t *addr)
if (swaphash == NULL) printk(KERN_ERR - "batman-adv:Couldn't resize orig hash table \n"); + "batman-adv:Couldn't resize orig hash table\n"); else orig_hash = swaphash; } diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index b83e5cb..a78ae5c 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -212,7 +212,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE));
- bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i \n", + bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); @@ -234,7 +234,7 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; int tmp_hna_buff_len;
- bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet \n"); + bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet\n");
list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && @@ -341,7 +341,7 @@ static char count_real_packets(struct ethhdr *ethhdr, }
if (!is_duplicate) { - bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d \n", + bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n", orig_node->last_real_seqno, batman_packet->seqno); orig_node->last_real_seqno = batman_packet->seqno; } @@ -385,7 +385,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0);
- bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d) \n", + bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, batman_packet->orig, batman_packet->prev_sender, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, @@ -426,7 +426,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, }
if (is_broadcast) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", ethhdr->h_source); return; }
@@ -454,19 +454,19 @@ void receive_bat_packet(struct ethhdr *ethhdr, bit_packet_count(word); }
- bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor) \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor)\n"); return; }
if (batman_packet->tq == 0) { count_real_packets(ethhdr, batman_packet, if_incoming);
- bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0 \n"); + bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); return; }
if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); return; }
@@ -484,7 +484,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM) \n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", ethhdr->h_source); return; }
diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 88ecb5c..29b684b 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -290,7 +290,7 @@ void schedule_forward_packet(struct orig_node *orig_node, unsigned long send_time;
if (batman_packet->ttl <= 1) { - bat_dbg(DBG_BATMAN, "ttl exceeded \n"); + bat_dbg(DBG_BATMAN, "ttl exceeded\n"); return; }
@@ -318,7 +318,7 @@ void schedule_forward_packet(struct orig_node *orig_node, /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq);
- bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i \n", + bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", in_tq, tq_avg, batman_packet->tq, in_ttl - 1, batman_packet->ttl);
diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index e446d90..5537846 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -77,11 +77,11 @@ void hna_local_add(uint8_t *addr) MAC-flooding. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size \n", addr); + bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size\n", addr); return; }
- bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM \n", + bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n", addr);
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); @@ -108,7 +108,7 @@ void hna_local_add(uint8_t *addr) hna_local_hash->size * 2);
if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table\n"); else hna_local_hash = swaphash; } @@ -197,7 +197,7 @@ static void _hna_local_del(void *data) static void hna_local_del(struct hna_local_entry *hna_local_entry, char *message) { - bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s \n", + bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n", hna_local_entry->addr, message);
hash_remove(hna_local_hash, hna_local_entry->addr); @@ -340,7 +340,7 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_global_hash->size * 2);
if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table \n"); + printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table\n"); else hna_global_hash = swaphash; } @@ -365,7 +365,7 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len)
bytes_written += snprintf(buff + bytes_written, (2 * ETH_STR_LEN) + 10, - " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x \n", + " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", hna_global_entry->addr[0], hna_global_entry->addr[1], hna_global_entry->addr[2], @@ -388,7 +388,7 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, char *message) { - bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s \n", + bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n", hna_global_entry->addr, hna_global_entry->orig_node->orig, message);
From: Marek Lindner lindner_marek@yahoo.de
This is the first patch in a series of patches which aim to convert all batman-adv /proc files to sysfs. To keep the changes in a digestable size it has been split up into smaller chunks. During the transition period batman-adv will use /proc as well as sysfs.
As a first step the following files have been converted: aggregate_ogm, originators, transtable_global, transtable_local
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/aggregation.c | 7 +- drivers/staging/batman-adv/aggregation.h | 3 +- drivers/staging/batman-adv/bat_sysfs.c | 272 +++++++++++++++++++++++ drivers/staging/batman-adv/bat_sysfs.h | 26 +++ drivers/staging/batman-adv/main.c | 11 +- drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 73 ++++++ drivers/staging/batman-adv/originator.h | 2 +- drivers/staging/batman-adv/proc.c | 279 +----------------------- drivers/staging/batman-adv/proc.h | 4 - drivers/staging/batman-adv/send.c | 15 +- drivers/staging/batman-adv/translation-table.c | 42 +++- drivers/staging/batman-adv/translation-table.h | 6 +- drivers/staging/batman-adv/types.h | 2 + 15 files changed, 439 insertions(+), 306 deletions(-) create mode 100644 drivers/staging/batman-adv/bat_sysfs.c create mode 100644 drivers/staging/batman-adv/bat_sysfs.h
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index cf2915d..9ad0429 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,4 @@ #
obj-m += batman-adv.o -batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o +batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index b8338ce..c946839 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -167,7 +167,8 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming, char own_packet, - unsigned long send_time) + unsigned long send_time, + struct bat_priv *bat_priv) { /** * _aggr -> pointer to the packet we want to aggregate with @@ -183,7 +184,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, /* find position for the packet in the forward queue */ spin_lock_irqsave(&forw_bat_list_lock, flags); /* own packets are not to be aggregated */ - if ((atomic_read(&aggregation_enabled)) && (!own_packet)) { + if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &forw_bat_list, list) { if (can_aggregate_with(batman_packet, @@ -210,7 +211,7 @@ void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, * later on */ if ((!own_packet) && - (atomic_read(&aggregation_enabled))) + (atomic_read(&bat_priv->aggregation_enabled))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
new_aggregated_packet(packet_buff, packet_len, diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index bcd32c1..29e1ffc 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -32,6 +32,7 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna)
void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, struct batman_if *if_outgoing, char own_packet, - unsigned long send_time); + unsigned long send_time, + struct bat_priv *bat_priv); void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c new file mode 100644 index 0000000..6293118 --- /dev/null +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "bat_sysfs.h" +#include "translation-table.h" +#include "originator.h" +#include "hard-interface.h" + +#define to_dev(obj) container_of(obj, struct device, kobj) + +struct bat_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + char *buf, size_t count); +}; + +#define BAT_ATTR(_name, _mode, _show, _store) \ +struct bat_attribute bat_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + +#define BAT_BIN_ATTR(_name, _mode, _read, _write) \ +struct bin_attribute bat_attr_##_name = { \ + .attr = { .name = __stringify(_name), \ + .mode = _mode, }, \ + .read = _read, \ + .write = _write, \ +}; + +static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + int aggr_status = atomic_read(&bat_priv->aggregation_enabled); + + return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1 \n", + aggr_status == 0 ? "disabled" : "enabled"); +} + +static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + int aggr_tmp = -1; + + if (((count == 2) && (buff[0] == '1')) || + (strncmp(buff, "enable", 6) == 0)) + aggr_tmp = 1; + + if (((count == 2) && (buff[0] == '0')) || + (strncmp(buff, "disable", 7) == 0)) + aggr_tmp = 0; + + if (aggr_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_INFO "batman-adv:Invalid parameter for 'aggregate OGM' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing aggregation from: %s to: %s on mesh: %s\n", + atomic_read(&bat_priv->aggregation_enabled) == 1 ? + "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled", + net_dev->name); + + atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp); + return count; +} + +static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, + show_aggr_ogm, store_aggr_ogm); + +static struct bat_attribute *mesh_attrs[] = { + &bat_attr_aggregate_ogm, + NULL, +}; + +static ssize_t transtable_local_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return hna_local_fill_buffer_text(net_dev, buff, count, off); +} + +static ssize_t transtable_global_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return hna_global_fill_buffer_text(net_dev, buff, count, off); +} + +static ssize_t originators_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + /* FIXME: orig table should exist per batif */ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + + rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + + if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - primary interface not active\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + + return orig_fill_buffer_text(buff, count, off); +} + +static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL); +static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL); +static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL); + +static struct bin_attribute *mesh_bin_attrs[] = { + &bat_attr_transtable_local, + &bat_attr_transtable_global, + &bat_attr_originators, + NULL, +}; + +int sysfs_add_meshif(struct net_device *dev) +{ + struct kobject *batif_kobject = &dev->dev.kobj; + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + struct bin_attribute **bin_attr; + int err; + + /* FIXME: should be done in the general mesh setup + routine as soon as we have it */ + atomic_set(&bat_priv->aggregation_enabled, 1); + + bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, + batif_kobject); + if (!bat_priv->mesh_obj) { + printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR); + goto out; + } + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { + err = sysfs_create_file(bat_priv->mesh_obj, + &((*bat_attr)->attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bat_attr)->attr).name); + goto rem_attr; + } + } + + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) { + err = sysfs_create_bin_file(bat_priv->mesh_obj, (*bin_attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_MESH_SUBDIR, + ((*bin_attr)->attr).name); + goto rem_bin_attr; + } + } + + return 0; + +rem_bin_attr: + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) + sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); +rem_attr: + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +out: + return -ENOMEM; +} + +void sysfs_del_meshif(struct net_device *dev) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct bat_attribute **bat_attr; + struct bin_attribute **bin_attr; + + for (bin_attr = mesh_bin_attrs; *bin_attr; ++bin_attr) + sysfs_remove_bin_file(bat_priv->mesh_obj, (*bin_attr)); + + for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) + sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); + + kobject_put(bat_priv->mesh_obj); + bat_priv->mesh_obj = NULL; +} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h new file mode 100644 index 0000000..671ebd1 --- /dev/null +++ b/drivers/staging/batman-adv/bat_sysfs.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + +#define SYSFS_IF_MESH_SUBDIR "mesh" + +int sysfs_add_meshif(struct net_device *dev); +void sysfs_del_meshif(struct net_device *dev); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 881aaa9..b5f8b80 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -21,6 +21,7 @@
#include "main.h" #include "proc.h" +#include "bat_sysfs.h" #include "routing.h" #include "send.h" #include "originator.h" @@ -44,7 +45,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock); atomic_t originator_interval; atomic_t vis_interval; atomic_t vis_mode; -atomic_t aggregation_enabled; int16_t num_hna; int16_t num_ifs;
@@ -85,7 +85,6 @@ int init_module(void) atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); - atomic_set(&aggregation_enabled, 1);
/* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ @@ -116,6 +115,11 @@ int init_module(void) goto free_soft_device; }
+ retval = sysfs_add_meshif(soft_device); + + if (retval < 0) + goto unreg_soft_device; + register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type);
@@ -124,6 +128,8 @@ int init_module(void)
return 0;
+unreg_soft_device: + unregister_netdevice(soft_device); free_soft_device: free_netdev(soft_device); soft_device = NULL; @@ -136,6 +142,7 @@ void cleanup_module(void) shutdown_module();
if (soft_device) { + sysfs_del_meshif(soft_device); unregister_netdev(soft_device); soft_device = NULL; } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 6221b85..3e28e9e 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -130,7 +130,6 @@ extern spinlock_t forw_bcast_list_lock; extern atomic_t originator_interval; extern atomic_t vis_interval; extern atomic_t vis_mode; -extern atomic_t aggregation_enabled; extern int16_t num_hna; extern int16_t num_ifs;
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index f3d8cc3..818f56e 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -249,4 +249,77 @@ void purge_orig(struct work_struct *work) start_purge_timer(); }
+ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) +{ + HASHIT(hashit); + struct orig_node *orig_node; + struct neigh_node *neigh_node; + size_t hdr_len, tmp_len; + int batman_count = 0, bytes_written = 0; + unsigned long flags; + char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; + + rcu_read_lock(); + hdr_len = sprintf(buff, + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", + "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", + "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, + ((struct batman_if *)if_list.next)->dev, + ((struct batman_if *)if_list.next)->addr_str); + rcu_read_unlock(); + + if (off < hdr_len) + bytes_written = hdr_len; + + spin_lock_irqsave(&orig_hash_lock, flags); + + while (hash_iterate(orig_hash, &hashit)) { + + orig_node = hashit.bucket->data; + + if (!orig_node->router) + continue; + + if (orig_node->router->tq_avg == 0) + continue; + + /* estimated line length */ + if (count < bytes_written + 200) + break; + + addr_to_string(orig_str, orig_node->orig); + addr_to_string(router_str, orig_node->router->addr); + + tmp_len = sprintf(buff + bytes_written, + "%-17s (%3i) %17s [%10s]:", + orig_str, orig_node->router->tq_avg, + router_str, + orig_node->router->if_incoming->dev); + + list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { + addr_to_string(orig_str, neigh_node->addr); + tmp_len += sprintf(buff + bytes_written + tmp_len, + " %17s (%3i)", orig_str, + neigh_node->tq_avg); + } + + tmp_len += sprintf(buff + bytes_written + tmp_len, "\n"); + + batman_count++; + hdr_len += tmp_len; + + if (off >= hdr_len) + continue; + + bytes_written += tmp_len; + } + + spin_unlock_irqrestore(&orig_hash_lock, flags); + + if ((batman_count == 0) && (off == 0)) + bytes_written += sprintf(buff + bytes_written, + "No batman nodes in range ... \n"); + + return bytes_written; +}
diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 8acebc1..8289a85 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -28,4 +28,4 @@ struct orig_node *get_orig_node(uint8_t *addr); struct neigh_node * create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); - +ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index dfa85c4..059b2d9 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -29,11 +29,8 @@ #include "vis.h"
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; -static struct proc_dir_entry *proc_orig_interval_file, *proc_originators_file; -static struct proc_dir_entry *proc_transt_local_file; -static struct proc_dir_entry *proc_transt_global_file; +static struct proc_dir_entry *proc_orig_interval_file; static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file; -static struct proc_dir_entry *proc_aggr_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -176,145 +173,6 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file) return single_open(file, proc_orig_interval_read, NULL); }
-static int proc_originators_read(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - struct orig_node *orig_node; - struct neigh_node *neigh_node; - int batman_count = 0; - char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN]; - unsigned long flags; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - - if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - primary interface not active\n"); - goto end; - } - - seq_printf(seq, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n", - "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", - "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, - ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str); - - rcu_read_unlock(); - spin_lock_irqsave(&orig_hash_lock, flags); - - while (hash_iterate(orig_hash, &hashit)) { - - orig_node = hashit.bucket->data; - - if (!orig_node->router) - continue; - - if (orig_node->router->tq_avg == 0) - continue; - - batman_count++; - - addr_to_string(orig_str, orig_node->orig); - addr_to_string(router_str, orig_node->router->addr); - - seq_printf(seq, "%-17s (%3i) %17s [%10s]:", - orig_str, orig_node->router->tq_avg, - router_str, orig_node->router->if_incoming->dev); - - list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { - addr_to_string(orig_str, neigh_node->addr); - seq_printf(seq, " %17s (%3i)", - orig_str, neigh_node->tq_avg); - } - - seq_printf(seq, "\n"); - - } - - spin_unlock_irqrestore(&orig_hash_lock, flags); - - if (batman_count == 0) - seq_printf(seq, "No batman nodes in range ...\n"); - -end: - return 0; -} - -static int proc_originators_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_originators_read, NULL); -} - -static int proc_transt_local_read(struct seq_file *seq, void *offset) -{ - char *buf; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) - return 0; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - - rcu_read_unlock(); - - seq_printf(seq, "Locally retrieved addresses (from %s) announced via HNA:\n", soft_device->name); - - hna_local_fill_buffer_text(buf, 4096); - seq_printf(seq, "%s", buf); - -end: - kfree(buf); - return 0; -} - -static int proc_transt_local_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_transt_local_read, NULL); -} - -static int proc_transt_global_read(struct seq_file *seq, void *offset) -{ - char *buf; - - buf = kmalloc(4096, GFP_KERNEL); - if (!buf) - return 0; - - rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n"); - goto end; - } - rcu_read_unlock(); - - - seq_printf(seq, "Globally announced HNAs received via the mesh (translation table):\n"); - - hna_global_fill_buffer_text(buf, 4096); - seq_printf(seq, "%s", buf); - -end: - kfree(buf); - return 0; -} - -static int proc_transt_global_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_transt_global_read, NULL); -} - /* setting the mode of the vis server by the user */ static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, size_t count, loff_t *ppos) @@ -429,53 +287,6 @@ static int proc_vis_data_open(struct inode *inode, struct file *file) return single_open(file, proc_vis_data_read, NULL); }
-static int proc_aggr_read(struct seq_file *seq, void *offset) -{ - seq_printf(seq, "%i\n", atomic_read(&aggregation_enabled)); - - return 0; -} - -static ssize_t proc_aggr_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *aggr_string; - int not_copied = 0; - unsigned long aggregation_enabled_tmp; - int retval; - - aggr_string = kmalloc(count, GFP_KERNEL); - - if (!aggr_string) - return -ENOMEM; - - not_copied = copy_from_user(aggr_string, buffer, count); - aggr_string[count - not_copied - 1] = 0; - - retval = strict_strtoul(aggr_string, 10, &aggregation_enabled_tmp); - - if (retval || aggregation_enabled_tmp > 1) { - printk(KERN_ERR "batman-adv:Aggregation can only be enabled (1) or disabled (0), given value: %li\n", aggregation_enabled_tmp); - } else { - printk(KERN_INFO "batman-adv:Changing aggregation from: %s (%i) to: %s (%li)\n", - (atomic_read(&aggregation_enabled) == 1 ? - "enabled" : "disabled"), - atomic_read(&aggregation_enabled), - (aggregation_enabled_tmp == 1 ? "enabled" : "disabled"), - aggregation_enabled_tmp); - atomic_set(&aggregation_enabled, - (unsigned)aggregation_enabled_tmp); - } - - kfree(aggr_string); - return count; -} - -static int proc_aggr_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_aggr_read, NULL); -} - /* satisfying different prototypes ... */ static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) @@ -483,15 +294,6 @@ static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, return count; }
-static const struct file_operations proc_aggr_fops = { - .owner = THIS_MODULE, - .open = proc_aggr_open, - .read = seq_read, - .write = proc_aggr_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_vis_srv_fops = { .owner = THIS_MODULE, .open = proc_vis_srv_open, @@ -510,33 +312,6 @@ static const struct file_operations proc_vis_data_fops = { .release = single_release, };
-static const struct file_operations proc_originators_fops = { - .owner = THIS_MODULE, - .open = proc_originators_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_transt_local_fops = { - .owner = THIS_MODULE, - .open = proc_transt_local_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_transt_global_fops = { - .owner = THIS_MODULE, - .open = proc_transt_global_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -557,15 +332,6 @@ static const struct file_operations proc_orig_interval_fops = {
void cleanup_procfs(void) { - if (proc_transt_global_file) - remove_proc_entry(PROC_FILE_TRANST_GLOBAL, proc_batman_dir); - - if (proc_transt_local_file) - remove_proc_entry(PROC_FILE_TRANST_LOCAL, proc_batman_dir); - - if (proc_originators_file) - remove_proc_entry(PROC_FILE_ORIGINATORS, proc_batman_dir); - if (proc_orig_interval_file) remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir);
@@ -578,9 +344,6 @@ void cleanup_procfs(void) if (proc_vis_srv_file) remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir);
- if (proc_aggr_file) - remove_proc_entry(PROC_FILE_AGGR, proc_batman_dir); - if (proc_batman_dir) #ifdef __NET_NET_NAMESPACE_H remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); @@ -624,36 +387,6 @@ int setup_procfs(void) return -EFAULT; }
- proc_originators_file = create_proc_entry(PROC_FILE_ORIGINATORS, - S_IRUGO, proc_batman_dir); - if (proc_originators_file) { - proc_originators_file->proc_fops = &proc_originators_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIGINATORS); - cleanup_procfs(); - return -EFAULT; - } - - proc_transt_local_file = create_proc_entry(PROC_FILE_TRANST_LOCAL, - S_IRUGO, proc_batman_dir); - if (proc_transt_local_file) { - proc_transt_local_file->proc_fops = &proc_transt_local_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_LOCAL); - cleanup_procfs(); - return -EFAULT; - } - - proc_transt_global_file = create_proc_entry(PROC_FILE_TRANST_GLOBAL, - S_IRUGO, proc_batman_dir); - if (proc_transt_global_file) { - proc_transt_global_file->proc_fops = &proc_transt_global_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_TRANST_GLOBAL); - cleanup_procfs(); - return -EFAULT; - } - proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV, S_IWUSR | S_IRUGO, proc_batman_dir); @@ -675,15 +408,5 @@ int setup_procfs(void) return -EFAULT; }
- proc_aggr_file = create_proc_entry(PROC_FILE_AGGR, S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_aggr_file) { - proc_aggr_file->proc_fops = &proc_aggr_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_AGGR); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index cf71264..68a255a 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -25,15 +25,11 @@ #define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" #define PROC_FILE_ORIG_INTERVAL "orig_interval" -#define PROC_FILE_ORIGINATORS "originators" #define PROC_FILE_GATEWAYS "gateways" #define PROC_FILE_LOG "log" #define PROC_FILE_LOG_LEVEL "log_level" -#define PROC_FILE_TRANST_LOCAL "transtable_local" -#define PROC_FILE_TRANST_GLOBAL "transtable_global" #define PROC_FILE_VIS_SRV "vis_server" #define PROC_FILE_VIS_DATA "vis_data" -#define PROC_FILE_AGGR "aggregate_ogm"
void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 29b684b..32d1756 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -44,7 +44,7 @@ static unsigned long own_send_time(void) }
/* when do we schedule a forwarded packet to be sent */ -static unsigned long forward_send_time(void) +static unsigned long forward_send_time(struct bat_priv *bat_priv) { return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000); } @@ -239,6 +239,8 @@ static void rebuild_batman_packet(struct batman_if *batman_if)
void schedule_own_packet(struct batman_if *batman_if) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; int vis_server = atomic_read(&vis_mode); @@ -277,7 +279,9 @@ void schedule_own_packet(struct batman_if *batman_if) slide_own_bcast_window(batman_if); send_time = own_send_time(); add_bat_packet_to_list(batman_if->packet_buff, - batman_if->packet_len, batman_if, 1, send_time); + batman_if->packet_len, + batman_if, 1, send_time, + bat_priv); }
void schedule_forward_packet(struct orig_node *orig_node, @@ -286,6 +290,8 @@ void schedule_forward_packet(struct orig_node *orig_node, uint8_t directlink, int hna_buff_len, struct batman_if *if_incoming) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned char in_tq, in_ttl, tq_avg = 0; unsigned long send_time;
@@ -329,10 +335,11 @@ void schedule_forward_packet(struct orig_node *orig_node, else batman_packet->flags &= ~DIRECTLINK;
- send_time = forward_send_time(); + send_time = forward_send_time(bat_priv); add_bat_packet_to_list((unsigned char *)batman_packet, sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time); + if_incoming, 0, send_time, + bat_priv); }
static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 5537846..d43b1ad 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -156,23 +156,36 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len) return i; }
-int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) +int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { struct hna_local_entry *hna_local_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; + size_t hdr_len; + + hdr_len = sprintf(buff, + "Locally retrieved addresses (from %s) announced via HNA:\n", + net_dev->name); + + if (off < hdr_len) + bytes_written = hdr_len;
spin_lock_irqsave(&hna_local_hash_lock, flags);
while (hash_iterate(hna_local_hash, &hashit)) { + hdr_len += 21;
- if (buff_len < bytes_written + ETH_STR_LEN + 4) + if (count < bytes_written + 22) break;
+ if (off >= hdr_len) + continue; + hna_local_entry = hashit.bucket->data;
- bytes_written += snprintf(buff + bytes_written, ETH_STR_LEN + 4, + bytes_written += snprintf(buff + bytes_written, 22, " * %02x:%02x:%02x:%02x:%02x:%02x\n", hna_local_entry->addr[0], hna_local_entry->addr[1], @@ -183,7 +196,6 @@ int hna_local_fill_buffer_text(unsigned char *buff, int buff_len) }
spin_unlock_irqrestore(&hna_local_hash_lock, flags); - return bytes_written; }
@@ -348,23 +360,36 @@ void hna_global_add_orig(struct orig_node *orig_node, spin_unlock_irqrestore(&hna_global_hash_lock, flags); }
-int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) +int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { struct hna_global_entry *hna_global_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; + size_t hdr_len; + + hdr_len = sprintf(buff, + "Globally announced HNAs received via the mesh %s (translation table):\n", + net_dev->name); + + if (off < hdr_len) + bytes_written = hdr_len;
spin_lock_irqsave(&hna_global_hash_lock, flags);
while (hash_iterate(hna_global_hash, &hashit)) { - if (buff_len < bytes_written + (2 * ETH_STR_LEN) + 10) + hdr_len += 43; + + if (count < bytes_written + 44) break;
+ if (off >= hdr_len) + continue; + hna_global_entry = hashit.bucket->data;
- bytes_written += snprintf(buff + bytes_written, - (2 * ETH_STR_LEN) + 10, + bytes_written += snprintf(buff + bytes_written, 44, " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", hna_global_entry->addr[0], hna_global_entry->addr[1], @@ -381,7 +406,6 @@ int hna_global_fill_buffer_text(unsigned char *buff, int buff_len) }
spin_unlock_irqrestore(&hna_global_hash_lock, flags); - return bytes_written; }
diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h index 8568d80..8f412fc 100644 --- a/drivers/staging/batman-adv/translation-table.h +++ b/drivers/staging/batman-adv/translation-table.h @@ -25,13 +25,15 @@ int hna_local_init(void); void hna_local_add(uint8_t *addr); void hna_local_remove(uint8_t *addr, char *message); int hna_local_fill_buffer(unsigned char *buff, int buff_len); -int hna_local_fill_buffer_text(unsigned char *buff, int buff_len); +int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); void hna_local_purge(struct work_struct *work); void hna_local_free(void); int hna_global_init(void); void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff, int hna_buff_len); -int hna_global_fill_buffer_text(unsigned char *buff, int buff_len); +int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); void _hna_global_del_orig(struct hna_global_entry *hna_global_entry, char *orig_str); void hna_global_del_orig(struct orig_node *orig_node, char *message); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 4e77141..db1bb0b 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -82,6 +82,8 @@ struct neigh_node {
struct bat_priv { struct net_device_stats stats; + atomic_t aggregation_enabled; + struct kobject *mesh_obj; };
struct device_client {
From: Marek Lindner lindner_marek@yahoo.de
converted files: vis_mode, vis_data
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/aggregation.c | 6 +- drivers/staging/batman-adv/aggregation.h | 8 +- drivers/staging/batman-adv/bat_sysfs.c | 118 ++++++++++------- drivers/staging/batman-adv/main.c | 2 - drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 33 ++++- drivers/staging/batman-adv/originator.h | 3 +- drivers/staging/batman-adv/proc.c | 167 ------------------------ drivers/staging/batman-adv/proc.h | 5 - drivers/staging/batman-adv/routing.c | 10 +- drivers/staging/batman-adv/send.c | 16 +- drivers/staging/batman-adv/soft-interface.c | 4 + drivers/staging/batman-adv/translation-table.c | 26 ++++ drivers/staging/batman-adv/types.h | 1 + drivers/staging/batman-adv/vis.c | 124 +++++++++++++++--- drivers/staging/batman-adv/vis.h | 17 +-- 16 files changed, 265 insertions(+), 276 deletions(-)
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index c946839..a5818ff 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -165,10 +165,10 @@ static void aggregate(struct forw_packet *forw_packet_aggr, (1 << forw_packet_aggr->num_packets); }
-void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming, char own_packet, - unsigned long send_time, - struct bat_priv *bat_priv) + unsigned long send_time) { /** * _aggr -> pointer to the packet we want to aggregate with diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h index 29e1ffc..84401ca 100644 --- a/drivers/staging/batman-adv/aggregation.h +++ b/drivers/staging/batman-adv/aggregation.h @@ -30,9 +30,9 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) (next_buff_pos <= MAX_AGGREGATION_BYTES); }
-void add_bat_packet_to_list(unsigned char *packet_buff, int packet_len, - struct batman_if *if_outgoing, char own_packet, - unsigned long send_time, - struct bat_priv *bat_priv); +void add_bat_packet_to_list(struct bat_priv *bat_priv, + unsigned char *packet_buff, int packet_len, + struct batman_if *if_incoming, char own_packet, + unsigned long send_time); void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, int packet_len, struct batman_if *if_incoming); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 6293118..c14ab47 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -24,6 +24,7 @@ #include "translation-table.h" #include "originator.h" #include "hard-interface.h" +#include "vis.h"
#define to_dev(obj) container_of(obj, struct device, kobj)
@@ -99,11 +100,66 @@ static ssize_t store_aggr_ogm(struct kobject *kobj, struct attribute *attr, return count; }
+static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + int vis_mode = atomic_read(&bat_priv->vis_mode); + + return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n", + vis_mode == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", + VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE); +} + +static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + unsigned long val; + int ret, vis_mode_tmp = -1; + + ret = strict_strtoul(buff, 10, &val); + + if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || + (strncmp(buff, "client", 6) == 0)) + vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; + + if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || + (strncmp(buff, "server", 6) == 0)) + vis_mode_tmp = VIS_TYPE_SERVER_SYNC; + + if (vis_mode_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_INFO "batman-adv:Invalid parameter for 'vis mode' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing vis mode from: %s to: %s on mesh: %s\n", + atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? + "client" : "server", net_dev->name); + + atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); + return count; +} + static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, show_aggr_ogm, store_aggr_ogm); +static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static struct bat_attribute *mesh_attrs[] = { &bat_attr_aggregate_ogm, + &bat_attr_vis_mode, NULL, };
@@ -114,19 +170,6 @@ static ssize_t transtable_local_read(struct kobject *kobj, struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - rcu_read_unlock(); - return hna_local_fill_buffer_text(net_dev, buff, count, off); }
@@ -137,19 +180,6 @@ static ssize_t transtable_global_read(struct kobject *kobj, struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - rcu_read_unlock(); - return hna_global_fill_buffer_text(net_dev, buff, count, off); }
@@ -157,45 +187,32 @@ static ssize_t originators_read(struct kobject *kobj, struct bin_attribute *bin_attr, char *buff, loff_t off, size_t count) { - /* FIXME: orig table should exist per batif */ struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev);
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); - - return 0; - } - - if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - primary interface not active\n", - net_dev->name); + return orig_fill_buffer_text(net_dev, buff, count, off); +}
- return 0; - } - rcu_read_unlock(); +static ssize_t vis_data_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev);
- return orig_fill_buffer_text(buff, count, off); + return vis_fill_buffer_text(net_dev, buff, count, off); }
static BAT_BIN_ATTR(transtable_local, S_IRUGO, transtable_local_read, NULL); static BAT_BIN_ATTR(transtable_global, S_IRUGO, transtable_global_read, NULL); static BAT_BIN_ATTR(originators, S_IRUGO, originators_read, NULL); +static BAT_BIN_ATTR(vis_data, S_IRUGO, vis_data_read, NULL);
static struct bin_attribute *mesh_bin_attrs[] = { &bat_attr_transtable_local, &bat_attr_transtable_global, &bat_attr_originators, + &bat_attr_vis_data, NULL, };
@@ -210,6 +227,7 @@ int sysfs_add_meshif(struct net_device *dev) /* FIXME: should be done in the general mesh setup routine as soon as we have it */ atomic_set(&bat_priv->aggregation_enabled, 1); + atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index b5f8b80..54e8cd5 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -44,7 +44,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t originator_interval; atomic_t vis_interval; -atomic_t vis_mode; int16_t num_hna; int16_t num_ifs;
@@ -84,7 +83,6 @@ int init_module(void) atomic_set(&originator_interval, 1000); atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ - atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE);
/* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 3e28e9e..b2283a7 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -129,7 +129,6 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t originator_interval; extern atomic_t vis_interval; -extern atomic_t vis_mode; extern int16_t num_hna; extern int16_t num_ifs;
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 818f56e..684db75 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -26,6 +26,7 @@ #include "hash.h" #include "translation-table.h" #include "routing.h" +#include "hard-interface.h"
static DECLARE_DELAYED_WORK(purge_orig_wq, purge_orig);
@@ -205,7 +206,6 @@ static bool purge_orig_neighbors(struct orig_node *orig_node, return neigh_purged; }
- static bool purge_orig_node(struct orig_node *orig_node) { struct neigh_node *best_neigh_node; @@ -224,6 +224,7 @@ static bool purge_orig_node(struct orig_node *orig_node) orig_node->hna_buff, orig_node->hna_buff_len); } + return false; }
@@ -249,7 +250,8 @@ void purge_orig(struct work_struct *work) start_purge_timer(); }
-ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) +ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) { HASHIT(hashit); struct orig_node *orig_node; @@ -260,12 +262,35 @@ ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off) char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + + if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - primary interface not active\n", + net_dev->name); + + return 0; + } + hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n", + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str); + ((struct batman_if *)if_list.next)->addr_str, + net_dev->name); rcu_read_unlock();
if (off < hdr_len) diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 8289a85..745b4b0 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -28,4 +28,5 @@ struct orig_node *get_orig_node(uint8_t *addr); struct neigh_node * create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); -ssize_t orig_fill_buffer_text(char *buff, size_t count, loff_t off); +ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index 059b2d9..cbea642 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -30,7 +30,6 @@
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; static struct proc_dir_entry *proc_orig_interval_file; -static struct proc_dir_entry *proc_vis_srv_file, *proc_vis_data_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -173,145 +172,6 @@ static int proc_orig_interval_open(struct inode *inode, struct file *file) return single_open(file, proc_orig_interval_read, NULL); }
-/* setting the mode of the vis server by the user */ -static ssize_t proc_vis_srv_write(struct file *file, const char __user * buffer, - size_t count, loff_t *ppos) -{ - char *vis_mode_string; - int not_copied = 0; - - vis_mode_string = kmalloc(count, GFP_KERNEL); - - if (!vis_mode_string) - return -ENOMEM; - - not_copied = copy_from_user(vis_mode_string, buffer, count); - vis_mode_string[count - not_copied - 1] = 0; - - if ((strcmp(vis_mode_string, "client") == 0) || - (strcmp(vis_mode_string, "disabled") == 0)) { - printk(KERN_INFO "batman-adv:Setting VIS mode to client (disabling vis server)\n"); - atomic_set(&vis_mode, VIS_TYPE_CLIENT_UPDATE); - } else if ((strcmp(vis_mode_string, "server") == 0) || - (strcmp(vis_mode_string, "enabled") == 0)) { - printk(KERN_INFO "batman-adv:Setting VIS mode to server (enabling vis server)\n"); - atomic_set(&vis_mode, VIS_TYPE_SERVER_SYNC); - } else - printk(KERN_ERR "batman-adv:Unknown VIS mode: %s\n", - vis_mode_string); - - kfree(vis_mode_string); - return count; -} - -static int proc_vis_srv_read(struct seq_file *seq, void *offset) -{ - int vis_server = atomic_read(&vis_mode); - - seq_printf(seq, "[%c] client mode (server disabled)\n", - (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' '); - seq_printf(seq, "[%c] server mode (server enabled)\n", - (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' '); - - return 0; -} - -static int proc_vis_srv_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_vis_srv_read, NULL); -} - -static int proc_vis_data_read(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - struct vis_info *info; - struct vis_info_entry *entries; - HLIST_HEAD(vis_if_list); - struct if_list_entry *entry; - struct hlist_node *pos, *n; - int i; - char tmp_addr_str[ETH_STR_LEN]; - unsigned long flags; - int vis_server = atomic_read(&vis_mode); - - rcu_read_lock(); - if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { - rcu_read_unlock(); - goto end; - } - - rcu_read_unlock(); - - 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)); - - for (i = 0; i < info->packet.entries; i++) { - if (entries[i].quality == 0) - continue; - proc_vis_insert_interface(entries[i].src, &vis_if_list, - compare_orig(entries[i].src, - info->packet.vis_orig)); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - addr_to_string(tmp_addr_str, entry->addr); - seq_printf(seq, "%s,", tmp_addr_str); - - for (i = 0; i < info->packet.entries; i++) - proc_vis_read_entry(seq, &entries[i], - entry->addr, entry->primary); - - /* add primary/secondary records */ - if (compare_orig(entry->addr, info->packet.vis_orig)) - proc_vis_read_prim_sec(seq, &vis_if_list); - - seq_printf(seq, "\n"); - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { - hlist_del(&entry->list); - kfree(entry); - } - } - spin_unlock_irqrestore(&vis_hash_lock, flags); - -end: - return 0; -} - -static int proc_vis_data_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_vis_data_read, NULL); -} - -/* satisfying different prototypes ... */ -static ssize_t proc_dummy_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - return count; -} - -static const struct file_operations proc_vis_srv_fops = { - .owner = THIS_MODULE, - .open = proc_vis_srv_open, - .read = seq_read, - .write = proc_vis_srv_write, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations proc_vis_data_fops = { - .owner = THIS_MODULE, - .open = proc_vis_data_open, - .read = seq_read, - .write = proc_dummy_write, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -338,12 +198,6 @@ void cleanup_procfs(void) if (proc_interface_file) remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
- if (proc_vis_data_file) - remove_proc_entry(PROC_FILE_VIS_DATA, proc_batman_dir); - - if (proc_vis_srv_file) - remove_proc_entry(PROC_FILE_VIS_SRV, proc_batman_dir); - if (proc_batman_dir) #ifdef __NET_NET_NAMESPACE_H remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); @@ -387,26 +241,5 @@ int setup_procfs(void) return -EFAULT; }
- proc_vis_srv_file = create_proc_entry(PROC_FILE_VIS_SRV, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_vis_srv_file) { - proc_vis_srv_file->proc_fops = &proc_vis_srv_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_SRV); - cleanup_procfs(); - return -EFAULT; - } - - proc_vis_data_file = create_proc_entry(PROC_FILE_VIS_DATA, S_IRUGO, - proc_batman_dir); - if (proc_vis_data_file) { - proc_vis_data_file->proc_fops = &proc_vis_data_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_VIS_DATA); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index 68a255a..6a972a6 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -25,11 +25,6 @@ #define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" #define PROC_FILE_ORIG_INTERVAL "orig_interval" -#define PROC_FILE_GATEWAYS "gateways" -#define PROC_FILE_LOG "log" -#define PROC_FILE_LOG_LEVEL "log_level" -#define PROC_FILE_VIS_SRV "vis_server" -#define PROC_FILE_VIS_DATA "vis_data"
void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index a78ae5c..8c055a1 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -946,6 +946,7 @@ int recv_vis_packet(struct sk_buff *skb) { struct vis_packet *vis_packet; struct ethhdr *ethhdr; + struct bat_priv *bat_priv; int hdr_size = sizeof(struct vis_packet);
if (skb_headlen(skb) < hdr_size) @@ -965,15 +966,20 @@ int recv_vis_packet(struct sk_buff *skb) if (is_my_mac(vis_packet->sender_orig)) return NET_RX_DROP;
+ /* FIXME: each batman_if will be attached to a softif */ + bat_priv = netdev_priv(soft_device); + switch (vis_packet->vis_type) { case VIS_TYPE_SERVER_SYNC: /* TODO: handle fragmented skbs properly */ - receive_server_sync_packet(vis_packet, skb_headlen(skb)); + receive_server_sync_packet(bat_priv, vis_packet, + skb_headlen(skb)); break;
case VIS_TYPE_CLIENT_UPDATE: /* TODO: handle fragmented skbs properly */ - receive_client_update_packet(vis_packet, skb_headlen(skb)); + receive_client_update_packet(bat_priv, vis_packet, + skb_headlen(skb)); break;
default: /* ignore unknown packet */ diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 32d1756..a00aa88 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -243,7 +243,7 @@ void schedule_own_packet(struct batman_if *batman_if) struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode);
/** * the interface gets activated here to avoid race conditions between @@ -271,17 +271,17 @@ void schedule_own_packet(struct batman_if *batman_if) if (vis_server == VIS_TYPE_SERVER_SYNC) batman_packet->flags = VIS_SERVER; else - batman_packet->flags = 0; + batman_packet->flags &= ~VIS_SERVER;
/* could be read by receive_bat_packet() */ atomic_inc(&batman_if->seqno);
slide_own_bcast_window(batman_if); send_time = own_send_time(); - add_bat_packet_to_list(batman_if->packet_buff, + add_bat_packet_to_list(bat_priv, + batman_if->packet_buff, batman_if->packet_len, - batman_if, 1, send_time, - bat_priv); + batman_if, 1, send_time); }
void schedule_forward_packet(struct orig_node *orig_node, @@ -336,10 +336,10 @@ void schedule_forward_packet(struct orig_node *orig_node, batman_packet->flags &= ~DIRECTLINK;
send_time = forward_send_time(bat_priv); - add_bat_packet_to_list((unsigned char *)batman_packet, + add_bat_packet_to_list(bat_priv, + (unsigned char *)batman_packet, sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time, - bat_priv); + if_incoming, 0, send_time); }
static void forw_packet_free(struct forw_packet *forw_packet) diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 0dff959..829deb6 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -182,6 +182,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *priv = netdev_priv(dev); struct batman_if *batman_if; + struct bat_priv *bat_priv; uint8_t dstaddr[6]; int data_len = skb->len; unsigned long flags; @@ -189,6 +190,9 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) if (atomic_read(&module_state) != MODULE_ACTIVE) goto dropped;
+ /* FIXME: each batman_if will be attached to a softif */ + bat_priv = netdev_priv(soft_device); + dev->trans_start = jiffies; /* TODO: check this for locks */ hna_local_add(ethhdr->h_source); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index d43b1ad..b735200 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -165,6 +165,19 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; size_t hdr_len;
+ rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + hdr_len = sprintf(buff, "Locally retrieved addresses (from %s) announced via HNA:\n", net_dev->name); @@ -369,6 +382,19 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; size_t hdr_len;
+ rcu_read_lock(); + if (list_empty(&if_list)) { + rcu_read_unlock(); + + if (off == 0) + return sprintf(buff, + "BATMAN mesh %s disabled - please specify interfaces to enable it\n", + net_dev->name); + + return 0; + } + rcu_read_unlock(); + hdr_len = sprintf(buff, "Globally announced HNAs received via the mesh %s (translation table):\n", net_dev->name); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index db1bb0b..e8d2e8c 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -83,6 +83,7 @@ struct neigh_node { struct bat_priv { struct net_device_stats stats; atomic_t aggregation_enabled; + atomic_t vis_mode; struct kobject *mesh_obj; };
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 0bfc083..5edeb32 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -102,7 +102,7 @@ static int vis_info_choose(void *data, int size)
/* insert interface to the list of interfaces of one originator, if it * does not already exist in the list */ -void proc_vis_insert_interface(const uint8_t *interface, +static void vis_data_insert_interface(const uint8_t *interface, struct hlist_head *if_list, bool primary) { @@ -123,36 +123,119 @@ void proc_vis_insert_interface(const uint8_t *interface, hlist_add_head(&entry->list, if_list); }
-void proc_vis_read_prim_sec(struct seq_file *seq, - struct hlist_head *if_list) +static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) { struct if_list_entry *entry; struct hlist_node *pos; char tmp_addr_str[ETH_STR_LEN]; + size_t len = 0;
hlist_for_each_entry(entry, pos, if_list, list) { if (entry->primary) - seq_printf(seq, "PRIMARY, "); + len += sprintf(buff + len, "PRIMARY, "); else { addr_to_string(tmp_addr_str, entry->addr); - seq_printf(seq, "SEC %s, ", tmp_addr_str); + len += sprintf(buff + len, "SEC %s, ", tmp_addr_str); } } + + return len; }
/* read an entry */ -void proc_vis_read_entry(struct seq_file *seq, - struct vis_info_entry *entry, - uint8_t *src, - bool primary) +static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, + uint8_t *src, bool primary) { char to[40];
addr_to_string(to, entry->dest); if (primary && entry->quality == 0) - seq_printf(seq, "HNA %s, ", to); + return sprintf(buff, "HNA %s, ", to); else if (compare_orig(entry->src, src)) - seq_printf(seq, "TQ %s %d, ", to, entry->quality); + return sprintf(buff, "TQ %s %d, ", to, entry->quality); + + return 0; +} + +ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off) +{ + HASHIT(hashit); + struct vis_info *info; + struct vis_info_entry *entries; + struct bat_priv *bat_priv = netdev_priv(net_dev); + HLIST_HEAD(vis_if_list); + struct if_list_entry *entry; + struct hlist_node *pos, *n; + size_t hdr_len, tmp_len; + int i, bytes_written = 0; + char tmp_addr_str[ETH_STR_LEN]; + unsigned long flags; + int vis_server = atomic_read(&bat_priv->vis_mode); + + rcu_read_lock(); + if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { + rcu_read_unlock(); + return 0; + } + + rcu_read_unlock(); + hdr_len = 0; + + 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)); + + /* estimated line length */ + if (count < bytes_written + 200) + break; + + for (i = 0; i < info->packet.entries; i++) { + if (entries[i].quality == 0) + continue; + vis_data_insert_interface(entries[i].src, &vis_if_list, + compare_orig(entries[i].src, + info->packet.vis_orig)); + } + + hlist_for_each_entry(entry, pos, &vis_if_list, list) { + addr_to_string(tmp_addr_str, entry->addr); + tmp_len = sprintf(buff + bytes_written, + "%s,", tmp_addr_str); + + for (i = 0; i < info->packet.entries; i++) + tmp_len += vis_data_read_entry( + buff + bytes_written + tmp_len, + &entries[i], entry->addr, + entry->primary); + + /* add primary/secondary records */ + if (compare_orig(entry->addr, info->packet.vis_orig)) + tmp_len += vis_data_read_prim_sec( + buff + bytes_written + tmp_len, + &vis_if_list); + + tmp_len += sprintf(buff + bytes_written + tmp_len, + "\n"); + + hdr_len += tmp_len; + + if (off >= hdr_len) + continue; + + bytes_written += tmp_len; + } + + hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { + hlist_del(&entry->list); + kfree(entry); + } + } + spin_unlock_irqrestore(&vis_hash_lock, flags); + + return bytes_written; }
/* add the info packet to the send list, if it was not @@ -280,12 +363,14 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet, }
/* handle the server sync packet, forward if needed. */ -void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len) +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, + int vis_info_len) { struct vis_info *info; int is_new, make_broadcast; unsigned long flags; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode);
make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
@@ -303,13 +388,14 @@ end: }
/* handle an incoming client update packet and schedule forward if needed. */ -void receive_client_update_packet(struct vis_packet *vis_packet, +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len) { struct vis_info *info; int is_new; unsigned long flags; - int vis_server = atomic_read(&vis_mode); + int vis_server = atomic_read(&bat_priv->vis_mode); int are_target = 0;
/* clients shall not broadcast. */ @@ -376,7 +462,7 @@ static bool vis_packet_full(struct vis_info *info)
/* generates a packet of own vis data, * returns 0 on success, -1 if no packet could be generated */ -static int generate_vis_packet(void) +static int generate_vis_packet(struct bat_priv *bat_priv) { HASHIT(hashit_local); HASHIT(hashit_global); @@ -388,7 +474,7 @@ static int generate_vis_packet(void) unsigned long flags;
info->first_seen = jiffies; - info->packet.vis_type = atomic_read(&vis_mode); + info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
spin_lock_irqsave(&orig_hash_lock, flags); memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN); @@ -568,12 +654,14 @@ static void send_vis_packets(struct work_struct *work) { struct vis_info *info, *temp; unsigned long flags; + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device);
spin_lock_irqsave(&vis_hash_lock, flags);
purge_vis_packets();
- if (generate_vis_packet() == 0) { + if (generate_vis_packet(bat_priv) == 0) { /* schedule if generation was successful */ send_list_add(my_vis_info); } diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h index 4e417fb..9c1fd77 100644 --- a/drivers/staging/batman-adv/vis.h +++ b/drivers/staging/batman-adv/vis.h @@ -47,18 +47,13 @@ struct recvlist_node { extern struct hashtable_t *vis_hash; extern spinlock_t vis_hash_lock;
-void proc_vis_insert_interface(const uint8_t *interface, - struct hlist_head *if_list, - bool primary); -void proc_vis_read_entry(struct seq_file *seq, - struct vis_info_entry *entry, - uint8_t *src, - bool primary); -void proc_vis_read_prim_sec(struct seq_file *seq, - struct hlist_head *if_list); -void receive_server_sync_packet(struct vis_packet *vis_packet, +ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, + size_t count, loff_t off); +void receive_server_sync_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len); -void receive_client_update_packet(struct vis_packet *vis_packet, +void receive_client_update_packet(struct bat_priv *bat_priv, + struct vis_packet *vis_packet, int vis_info_len); int vis_init(void); void vis_quit(void);
From: Marek Lindner lindner_marek@yahoo.de
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/bat_sysfs.c | 47 ++++++++++++++++++++ drivers/staging/batman-adv/main.c | 2 - drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/proc.c | 75 -------------------------------- drivers/staging/batman-adv/proc.h | 1 - drivers/staging/batman-adv/send.c | 6 +- drivers/staging/batman-adv/types.h | 1 + 7 files changed, 51 insertions(+), 82 deletions(-)
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index c14ab47..ea7ce77 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -153,13 +153,59 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; }
+static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + + return sprintf(buff, "status: %i\n", + atomic_read(&bat_priv->orig_interval)); +} + +static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct bat_priv *bat_priv = netdev_priv(net_dev); + unsigned long orig_interval_tmp; + int ret; + + ret = strict_strtoul(buff, 10, &orig_interval_tmp); + if (ret) { + printk(KERN_INFO "batman-adv:Invalid parameter for 'orig_interval' setting on mesh %s received: %s\n", + net_dev->name, buff); + return -EINVAL; + } + + if (orig_interval_tmp <= JITTER * 2) { + printk(KERN_INFO "batman-adv:New originator interval too small: %li (min: %i)\n", + orig_interval_tmp, JITTER * 2); + return -EINVAL; + } + + if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp) + return count; + + printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li on mesh: %s\n", + atomic_read(&bat_priv->orig_interval), + orig_interval_tmp, net_dev->name); + + atomic_set(&bat_priv->orig_interval, orig_interval_tmp); + return count; +} + static BAT_ATTR(aggregate_ogm, S_IRUGO | S_IWUSR, show_aggr_ogm, store_aggr_ogm); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); +static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR, + show_orig_interval, store_orig_interval);
static struct bat_attribute *mesh_attrs[] = { &bat_attr_aggregate_ogm, &bat_attr_vis_mode, + &bat_attr_orig_interval, NULL, };
@@ -228,6 +274,7 @@ int sysfs_add_meshif(struct net_device *dev) routine as soon as we have it */ atomic_set(&bat_priv->aggregation_enabled, 1); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); + atomic_set(&bat_priv->orig_interval, 1000);
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 54e8cd5..7d72685 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -42,7 +42,6 @@ DEFINE_SPINLOCK(orig_hash_lock); DEFINE_SPINLOCK(forw_bat_list_lock); DEFINE_SPINLOCK(forw_bcast_list_lock);
-atomic_t originator_interval; atomic_t vis_interval; int16_t num_hna; int16_t num_ifs; @@ -80,7 +79,6 @@ int init_module(void)
atomic_set(&module_state, MODULE_INACTIVE);
- atomic_set(&originator_interval, 1000); atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index b2283a7..59a70c7 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -127,7 +127,6 @@ extern spinlock_t orig_hash_lock; extern spinlock_t forw_bat_list_lock; extern spinlock_t forw_bcast_list_lock;
-extern atomic_t originator_interval; extern atomic_t vis_interval; extern int16_t num_hna; extern int16_t num_ifs; diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c index cbea642..25b24fe 100644 --- a/drivers/staging/batman-adv/proc.c +++ b/drivers/staging/batman-adv/proc.c @@ -29,7 +29,6 @@ #include "vis.h"
static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; -static struct proc_dir_entry *proc_orig_interval_file;
static int proc_interfaces_read(struct seq_file *seq, void *offset) { @@ -121,57 +120,6 @@ end: return count; }
-static int proc_orig_interval_read(struct seq_file *seq, void *offset) -{ - seq_printf(seq, "%i\n", atomic_read(&originator_interval)); - - return 0; -} - -static ssize_t proc_orig_interval_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *ppos) -{ - char *interval_string; - int not_copied = 0; - unsigned long originator_interval_tmp; - int retval; - - interval_string = kmalloc(count, GFP_KERNEL); - - if (!interval_string) - return -ENOMEM; - - not_copied = copy_from_user(interval_string, buffer, count); - interval_string[count - not_copied - 1] = 0; - - retval = strict_strtoul(interval_string, 10, &originator_interval_tmp); - if (retval) { - printk(KERN_ERR "batman-adv:New originator interval invalid\n"); - goto end; - } - - if (originator_interval_tmp <= JITTER * 2) { - printk(KERN_WARNING "batman-adv:New originator interval too small: %li (min: %i)\n", - originator_interval_tmp, JITTER * 2); - goto end; - } - - printk(KERN_INFO "batman-adv:Changing originator interval from: %i to: %li\n", - atomic_read(&originator_interval), originator_interval_tmp); - - atomic_set(&originator_interval, originator_interval_tmp); - -end: - kfree(interval_string); - return count; -} - -static int proc_orig_interval_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_orig_interval_read, NULL); -} - static const struct file_operations proc_interfaces_fops = { .owner = THIS_MODULE, .open = proc_interfaces_open, @@ -181,20 +129,8 @@ static const struct file_operations proc_interfaces_fops = { .release = single_release, };
-static const struct file_operations proc_orig_interval_fops = { - .owner = THIS_MODULE, - .open = proc_orig_interval_open, - .read = seq_read, - .write = proc_orig_interval_write, - .llseek = seq_lseek, - .release = single_release, -}; - void cleanup_procfs(void) { - if (proc_orig_interval_file) - remove_proc_entry(PROC_FILE_ORIG_INTERVAL, proc_batman_dir); - if (proc_interface_file) remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir);
@@ -230,16 +166,5 @@ int setup_procfs(void) return -EFAULT; }
- proc_orig_interval_file = create_proc_entry(PROC_FILE_ORIG_INTERVAL, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_orig_interval_file) { - proc_orig_interval_file->proc_fops = &proc_orig_interval_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_ORIG_INTERVAL); - cleanup_procfs(); - return -EFAULT; - } - return 0; } diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h index 6a972a6..6f4f5b3 100644 --- a/drivers/staging/batman-adv/proc.h +++ b/drivers/staging/batman-adv/proc.h @@ -24,7 +24,6 @@
#define PROC_ROOT_DIR "batman-adv" #define PROC_FILE_INTERFACES "interfaces" -#define PROC_FILE_ORIG_INTERVAL "orig_interval"
void cleanup_procfs(void); int setup_procfs(void); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index a00aa88..de2344a 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -36,10 +36,10 @@ static uint8_t hop_penalty(const uint8_t tq) }
/* when do we schedule our own packet to be sent */ -static unsigned long own_send_time(void) +static unsigned long own_send_time(struct bat_priv *bat_priv) { return jiffies + - (((atomic_read(&originator_interval) - JITTER + + (((atomic_read(&bat_priv->orig_interval) - JITTER + (random32() % 2*JITTER)) * HZ) / 1000); }
@@ -277,7 +277,7 @@ void schedule_own_packet(struct batman_if *batman_if) atomic_inc(&batman_if->seqno);
slide_own_bcast_window(batman_if); - send_time = own_send_time(); + send_time = own_send_time(bat_priv); add_bat_packet_to_list(bat_priv, batman_if->packet_buff, batman_if->packet_len, diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index e8d2e8c..a8c6ad7 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -84,6 +84,7 @@ struct bat_priv { struct net_device_stats stats; atomic_t aggregation_enabled; atomic_t vis_mode; + atomic_t orig_interval; struct kobject *mesh_obj; };
From: Marek Lindner lindner_marek@yahoo.de
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/originator.c | 1 - drivers/staging/batman-adv/routing.c | 17 ++++------------- drivers/staging/batman-adv/soft-interface.c | 5 ++--- drivers/staging/batman-adv/types.h | 1 - drivers/staging/batman-adv/vis.c | 15 +++++++-------- 6 files changed, 14 insertions(+), 27 deletions(-)
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 9887f05..c419c62 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -250,7 +250,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (!orig_node->router) goto unlock;
- batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
spin_unlock_irqrestore(&orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 684db75..4152701 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -137,7 +137,6 @@ struct orig_node *get_orig_node(uint8_t *addr)
memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; - orig_node->batman_if = NULL; orig_node->hna_buff = NULL;
size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 8c055a1..0a9f52b 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -97,11 +97,6 @@ static void update_route(struct orig_node *orig_node, bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr); }
- if (neigh_node != NULL) - orig_node->batman_if = neigh_node->if_incoming; - else - orig_node->batman_if = NULL; - orig_node->router = neigh_node; }
@@ -616,12 +611,11 @@ static int recv_my_icmp_packet(struct sk_buff *skb) ret = NET_RX_DROP;
if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
/* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -678,12 +672,11 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb) ret = NET_RX_DROP;
if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
/* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -760,12 +753,11 @@ int recv_icmp_packet(struct sk_buff *skb) hash_find(orig_hash, icmp_packet->dst));
if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
/* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -844,12 +836,11 @@ int recv_unicast_packet(struct sk_buff *skb) hash_find(orig_hash, unicast_packet->dest));
if ((orig_node != NULL) && - (orig_node->batman_if != NULL) && (orig_node->router != NULL)) {
/* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 829deb6..4cdebe5 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -236,7 +236,6 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) orig_node = transtable_search(ethhdr->h_dest);
if ((orig_node) && - (orig_node->batman_if) && (orig_node->router)) { if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) goto unlock; @@ -252,13 +251,13 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
/* net_dev won't be available when not active */ - if (orig_node->batman_if->if_active != IF_ACTIVE) + if (orig_node->router->if_incoming->if_active != IF_ACTIVE) goto unlock;
/* don't lock while sending the packets ... we therefore * copy the required data before sending */
- batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index a8c6ad7..ffaa16c 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -49,7 +49,6 @@ struct batman_if { struct orig_node { /* structure for orig_list maintaining nodes of mesh */ uint8_t orig[ETH_ALEN]; struct neigh_node *router; - struct batman_if *batman_if; TYPE_OF_WORD *bcast_own; uint8_t *bcast_own_sum; uint8_t tq_own; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 5edeb32..57d69d7 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -498,14 +498,14 @@ static int generate_vis_packet(struct bat_priv *bat_priv) if (orig_node->router != NULL && compare_orig(orig_node->router->addr, orig_node->orig) - && orig_node->batman_if - && (orig_node->batman_if->if_active == IF_ACTIVE) + && (orig_node->router->if_incoming->if_active == + IF_ACTIVE) && orig_node->router->tq_avg > 0) {
/* fill one entry into buffer. */ entry = &entry_array[info->packet.entries]; memcpy(entry->src, - orig_node->batman_if->net_dev->dev_addr, + orig_node->router->if_incoming->net_dev->dev_addr, ETH_ALEN); memcpy(entry->dest, orig_node->orig, ETH_ALEN); entry->quality = orig_node->router->tq_avg; @@ -573,8 +573,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) orig_node = hashit.bucket->data;
/* if it's a vis server and reachable, send it. */ - if ((!orig_node) || (!orig_node->batman_if) || - (!orig_node->router)) + if ((!orig_node) || (!orig_node->router)) continue; if (!(orig_node->flags & VIS_SERVER)) continue; @@ -584,7 +583,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length) continue;
memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN); - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
@@ -609,12 +608,12 @@ static void unicast_vis_packet(struct vis_info *info, int packet_length) orig_node = ((struct orig_node *) hash_find(orig_hash, info->packet.target_orig));
- if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router)) + if ((!orig_node) || (!orig_node->router)) goto out;
/* don't lock while sending the packets ... we therefore * copy the required data before sending */ - batman_if = orig_node->batman_if; + batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
From: Marek Lindner lindner_marek@yahoo.de
Instead of having a single /proc file "interfaces" in which you have to echo the wanted interface batman-adv will create a subfolder in each suitable /sys/class/net folder. This subfolder contains files for the interface specific settings. For example, mesh_iface to add/remove an interface from a virtual mesh network (at the moment only bat0 is supported).
Example: echo bat0 > /sys/class/net/eth0/batman-adv/mesh_iface
to deactivate: echo none > /sys/class/net/eth0/batman-adv/mesh_iface
Interfaces which are not compatible with batman-adv won't contain the batman-adv folder, therefore can't be activated. Not supported are: loopback, non-ethernet, non-ARP and virtual mesh network interfaces
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/Makefile | 2 +- drivers/staging/batman-adv/bat_sysfs.c | 147 +++++++ drivers/staging/batman-adv/bat_sysfs.h | 3 + drivers/staging/batman-adv/device.c | 2 +- drivers/staging/batman-adv/hard-interface.c | 515 ++++++++++++------------ drivers/staging/batman-adv/hard-interface.h | 18 +- drivers/staging/batman-adv/main.c | 21 +- drivers/staging/batman-adv/main.h | 3 +- drivers/staging/batman-adv/originator.c | 193 ++++++++- drivers/staging/batman-adv/originator.h | 2 + drivers/staging/batman-adv/proc.c | 170 -------- drivers/staging/batman-adv/proc.h | 30 -- drivers/staging/batman-adv/routing.c | 6 +- drivers/staging/batman-adv/send.c | 59 ++- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/translation-table.c | 14 +- drivers/staging/batman-adv/types.h | 5 +- drivers/staging/batman-adv/vis.c | 9 +- 19 files changed, 670 insertions(+), 533 deletions(-) delete mode 100644 drivers/staging/batman-adv/proc.c delete mode 100644 drivers/staging/batman-adv/proc.h
diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 9ad0429..f25068c 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,4 @@ #
obj-m += batman-adv.o -batman-adv-objs := main.o proc.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o +batman-adv-objs := main.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index ea7ce77..1811c8d 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -36,6 +36,14 @@ struct bat_attribute { char *buf, size_t count); };
+struct hardif_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + char *buf, size_t count); +}; + #define BAT_ATTR(_name, _mode, _show, _store) \ struct bat_attribute bat_attr_##_name = { \ .attr = {.name = __stringify(_name), \ @@ -52,6 +60,14 @@ struct bin_attribute bat_attr_##_name = { \ .write = _write, \ };
+#define HARDIF_ATTR(_name, _mode, _show, _store) \ +struct hardif_attribute hardif_attr_##_name = { \ + .attr = {.name = __stringify(_name), \ + .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, char *buff) { @@ -275,6 +291,8 @@ int sysfs_add_meshif(struct net_device *dev) atomic_set(&bat_priv->aggregation_enabled, 1); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->orig_interval, 1000); + bat_priv->primary_if = NULL; + bat_priv->num_ifaces = 0;
bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, batif_kobject); @@ -335,3 +353,132 @@ void sysfs_del_meshif(struct net_device *dev) kobject_put(bat_priv->mesh_obj); bat_priv->mesh_obj = NULL; } + +static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + + if (!batman_if) + return 0; + + return sprintf(buff, "status: %s\ncommands: none, bat0 \n", + batman_if->if_status == IF_NOT_IN_USE ? + "none" : "bat0"); +} + +static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + int status_tmp = -1; + + if (!batman_if) + return count; + + if (strncmp(buff, "none", 4) == 0) + status_tmp = IF_NOT_IN_USE; + + if (strncmp(buff, "bat0", 4) == 0) + status_tmp = IF_I_WANT_YOU; + + if (status_tmp < 0) { + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + printk(KERN_ERR "batman-adv:Invalid parameter for 'mesh_iface' setting received: %s\n", + buff); + return -EINVAL; + } + + if ((batman_if->if_status == status_tmp) || + ((status_tmp == IF_I_WANT_YOU) && + (batman_if->if_status != IF_NOT_IN_USE))) + return count; + + if (status_tmp == IF_I_WANT_YOU) + status_tmp = hardif_enable_interface(batman_if); + else + hardif_disable_interface(batman_if); + + return (status_tmp < 0 ? status_tmp : count); +} + +static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct device *dev = to_dev(kobj->parent); + struct net_device *net_dev = to_net_dev(dev); + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + + if (!batman_if) + return 0; + + switch (batman_if->if_status) { + case IF_TO_BE_REMOVED: + return sprintf(buff, "disabling\n"); + case IF_INACTIVE: + return sprintf(buff, "inactive\n"); + case IF_ACTIVE: + return sprintf(buff, "active\n"); + case IF_TO_BE_ACTIVATED: + return sprintf(buff, "enabling\n"); + case IF_NOT_IN_USE: + default: + return sprintf(buff, "not in use\n"); + } +} + +static HARDIF_ATTR(mesh_iface, S_IRUGO | S_IWUSR, + show_mesh_iface, store_mesh_iface); +static HARDIF_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); + +static struct hardif_attribute *batman_attrs[] = { + &hardif_attr_mesh_iface, + &hardif_attr_iface_status, + NULL, +}; + +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) +{ + struct kobject *hardif_kobject = &dev->dev.kobj; + struct hardif_attribute **hardif_attr; + int err; + + *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, + hardif_kobject); + + if (!*hardif_obj) { + printk(KERN_ERR "batman-adv:Can't add sysfs directory: %s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR); + goto out; + } + + for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) { + err = sysfs_create_file(*hardif_obj, &((*hardif_attr)->attr)); + if (err) { + printk(KERN_ERR "batman-adv:Can't add sysfs file: %s/%s/%s\n", + dev->name, SYSFS_IF_BAT_SUBDIR, + ((*hardif_attr)->attr).name); + goto rem_attr; + } + } + + return 0; + +rem_attr: + for (hardif_attr = batman_attrs; *hardif_attr; ++hardif_attr) + sysfs_remove_file(*hardif_obj, &((*hardif_attr)->attr)); +out: + return -ENOMEM; +} + +void sysfs_del_hardif(struct kobject **hardif_obj) +{ + kobject_put(*hardif_obj); + *hardif_obj = NULL; +} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h index 671ebd1..e189341 100644 --- a/drivers/staging/batman-adv/bat_sysfs.h +++ b/drivers/staging/batman-adv/bat_sysfs.h @@ -21,6 +21,9 @@
#define SYSFS_IF_MESH_SUBDIR "mesh" +#define SYSFS_IF_BAT_SUBDIR "batman_adv"
int sysfs_add_meshif(struct net_device *dev); void sysfs_del_meshif(struct net_device *dev); +int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); +void sysfs_del_hardif(struct kobject **hardif_obj); diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index c419c62..b2ecba2 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -258,7 +258,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (!batman_if) goto dst_unreach;
- if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto dst_unreach;
memcpy(icmp_packet.orig, diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index cb9e927..b82cae7 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -25,22 +25,21 @@ #include "send.h" #include "translation-table.h" #include "routing.h" +#include "bat_sysfs.h" +#include "originator.h" #include "hash.h"
-#define MIN(x, y) ((x) < (y) ? (x) : (y)) - -static char avail_ifs; -static char active_ifs; +#include <linux/if_arp.h>
-static void hardif_free_interface(struct rcu_head *rcu); +#define MIN(x, y) ((x) < (y) ? (x) : (y))
-static struct batman_if *get_batman_if_by_name(char *name) +struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) { struct batman_if *batman_if;
rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if (strncmp(batman_if->dev, name, IFNAMSIZ) == 0) + if (batman_if->net_dev == net_dev) goto out; }
@@ -51,23 +50,90 @@ out: return batman_if; }
-int hardif_min_mtu(void) +static int is_valid_iface(struct net_device *net_dev) +{ + if (net_dev->flags & IFF_LOOPBACK) + return 0; + + if (net_dev->type != ARPHRD_ETHER) + return 0; + + if (net_dev->addr_len != ETH_ALEN) + return 0; + + /* no batman over batman */ +#ifdef HAVE_NET_DEVICE_OPS + if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + return 0; +#else + if (net_dev->hard_start_xmit == interface_tx) + return 0; +#endif + + /* Device is being bridged */ + /* if (net_dev->br_port != NULL) + return 0; */ + + return 1; +} + +static struct batman_if *get_active_batman_if(void) { struct batman_if *batman_if; - /* allow big frames if all devices are capable to do so - * (have MTU > 1500 + BAT_HEADER_LEN) */ - int min_mtu = ETH_DATA_LEN;
+ /* TODO: should check interfaces belonging to bat_priv */ rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_active == IF_ACTIVE) || - (batman_if->if_active == IF_TO_BE_ACTIVATED)) - min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN, - min_mtu); + if (batman_if->if_status == IF_ACTIVE) + goto out; } + + batman_if = NULL; + +out: rcu_read_unlock(); + return batman_if; +}
- return min_mtu; +static void set_primary_if(struct bat_priv *bat_priv, + struct batman_if *batman_if) +{ + struct batman_packet *batman_packet; + + bat_priv->primary_if = batman_if; + + if (!bat_priv->primary_if) + return; + + set_main_if_addr(batman_if->net_dev->dev_addr); + + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->flags = 0; + batman_packet->ttl = TTL; + + /*** + * hacky trick to make sure that we send the HNA information via + * our new primary interface + */ + atomic_set(&hna_local_changed, 1); +} + +static bool hardif_is_iface_up(struct batman_if *batman_if) +{ + if (batman_if->net_dev->flags & IFF_UP) + return true; + + return false; +} + +static void update_mac_addresses(struct batman_if *batman_if) +{ + addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); + + memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, + batman_if->net_dev->dev_addr, ETH_ALEN); + memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, + batman_if->net_dev->dev_addr, ETH_ALEN); }
static void check_known_mac_addr(uint8_t *addr) @@ -76,8 +142,8 @@ static void check_known_mac_addr(uint8_t *addr)
rcu_read_lock(); list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_active != IF_ACTIVE) && - (batman_if->if_active != IF_TO_BE_ACTIVATED)) + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) continue;
if (!compare_orig(batman_if->net_dev->dev_addr, addr)) @@ -90,6 +156,25 @@ static void check_known_mac_addr(uint8_t *addr) rcu_read_unlock(); }
+int hardif_min_mtu(void) +{ + struct batman_if *batman_if; + /* allow big frames if all devices are capable to do so + * (have MTU > 1500 + BAT_HEADER_LEN) */ + int min_mtu = ETH_DATA_LEN; + + rcu_read_lock(); + list_for_each_entry_rcu(batman_if, &if_list, list) { + if ((batman_if->if_status == IF_ACTIVE) || + (batman_if->if_status == IF_TO_BE_ACTIVATED)) + min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN, + min_mtu); + } + rcu_read_unlock(); + + return min_mtu; +} + /* adjusts the MTU if a new interface with a smaller MTU appeared. */ void update_min_mtu(void) { @@ -100,322 +185,246 @@ void update_min_mtu(void) soft_device->mtu = min_mtu; }
-/* checks if the interface is up. (returns 1 if it is) */ -static int hardif_is_interface_up(char *dev) +static void hardif_activate_interface(struct bat_priv *bat_priv, + struct batman_if *batman_if) { - struct net_device *net_dev; + if (batman_if->if_status != IF_INACTIVE) + return;
- /** - * if we already have an interface in our interface list and - * the current interface is not the primary interface and - * the primary interface is not up and - * the primary interface has never been up - don't activate any - * secondary interface ! - */ + dev_hold(batman_if->net_dev);
- rcu_read_lock(); - if ((!list_empty(&if_list)) && - strncmp(((struct batman_if *)if_list.next)->dev, dev, IFNAMSIZ) && - !(((struct batman_if *)if_list.next)->if_active == IF_ACTIVE) && - !(((struct batman_if *)if_list.next)->if_active == IF_TO_BE_ACTIVATED) && - (!main_if_was_up())) { - rcu_read_unlock(); - goto end; - } - rcu_read_unlock(); + update_mac_addresses(batman_if); + batman_if->if_status = IF_TO_BE_ACTIVATED;
-#ifdef __NET_NET_NAMESPACE_H - net_dev = dev_get_by_name(&init_net, dev); -#else - net_dev = dev_get_by_name(dev); -#endif - if (!net_dev) - goto end; + /** + * the first active interface becomes our primary interface or + * the next active interface after the old primay interface was removed + */ + if (!bat_priv->primary_if) + set_primary_if(bat_priv, batman_if);
- if (!(net_dev->flags & IFF_UP)) - goto failure; + printk(KERN_INFO "batman-adv:Interface activated: %s\n", + batman_if->dev);
- dev_put(net_dev); - return 1; + if (atomic_read(&module_state) == MODULE_INACTIVE) + activate_module();
-failure: - dev_put(net_dev); -end: - return 0; + update_min_mtu(); + return; }
-/* deactivates the interface. */ -void hardif_deactivate_interface(struct batman_if *batman_if) +static void hardif_deactivate_interface(struct batman_if *batman_if) { - if (batman_if->if_active != IF_ACTIVE) + if ((batman_if->if_status != IF_ACTIVE) && + (batman_if->if_status != IF_TO_BE_ACTIVATED)) return;
- /** - * batman_if->net_dev has been acquired by dev_get_by_name() in - * proc_interfaces_write() and has to be unreferenced. - */ - - if (batman_if->net_dev) - dev_put(batman_if->net_dev); + dev_put(batman_if->net_dev);
- batman_if->if_active = IF_INACTIVE; - active_ifs--; + batman_if->if_status = IF_INACTIVE;
printk(KERN_INFO "batman-adv:Interface deactivated: %s\n", - batman_if->dev); + batman_if->dev); + + update_min_mtu(); }
-/* (re)activate given interface. */ -static void hardif_activate_interface(struct batman_if *batman_if) +int hardif_enable_interface(struct batman_if *batman_if) { - if (batman_if->if_active != IF_INACTIVE) - return; - -#ifdef __NET_NET_NAMESPACE_H - batman_if->net_dev = dev_get_by_name(&init_net, batman_if->dev); -#else - batman_if->net_dev = dev_get_by_name(batman_if->dev); -#endif - if (!batman_if->net_dev) - goto dev_err; + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); + struct batman_packet *batman_packet;
- check_known_mac_addr(batman_if->net_dev->dev_addr); + if (batman_if->if_status != IF_NOT_IN_USE) + goto out;
- addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); + batman_if->packet_len = BAT_PACKET_LEN; + batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
- memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, - batman_if->net_dev->dev_addr, ETH_ALEN); - memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, - batman_if->net_dev->dev_addr, ETH_ALEN); + if (!batman_if->packet_buff) { + printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", + batman_if->dev); + goto err; + }
- batman_if->if_active = IF_TO_BE_ACTIVATED; - active_ifs++; + batman_packet = (struct batman_packet *)(batman_if->packet_buff); + batman_packet->packet_type = BAT_PACKET; + batman_packet->version = COMPAT_VERSION; + batman_packet->flags = 0; + batman_packet->ttl = 2; + batman_packet->tq = TQ_MAX_VALUE; + batman_packet->num_hna = 0;
- /* save the mac address if it is our primary interface */ - if (batman_if->if_num == 0) - set_main_if_addr(batman_if->net_dev->dev_addr); + batman_if->if_num = bat_priv->num_ifaces; + bat_priv->num_ifaces++; + batman_if->if_status = IF_INACTIVE; + orig_hash_add_if(batman_if, bat_priv->num_ifaces);
- printk(KERN_INFO "batman-adv:Interface activated: %s\n", - batman_if->dev); + atomic_set(&batman_if->seqno, 1); + printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev);
- return; + if (hardif_is_iface_up(batman_if)) + hardif_activate_interface(bat_priv, batman_if); + else + printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev);
-dev_err: - batman_if->net_dev = NULL; -} + /* begin scheduling originator messages on that interface */ + schedule_own_packet(batman_if);
-static void hardif_free_interface(struct rcu_head *rcu) -{ - struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu); +out: + return 0;
- kfree(batman_if->packet_buff); - kfree(batman_if->dev); - kfree(batman_if); +err: + return -ENOMEM; }
-/** - * called by - * - echo '' > /proc/.../interfaces - * - modprobe -r batman-adv-core - */ -/* removes and frees all interfaces */ -void hardif_remove_interfaces(void) +void hardif_disable_interface(struct batman_if *batman_if) { - struct batman_if *batman_if = NULL; - - avail_ifs = 0; - - /* no lock needed - we don't delete somewhere else */ - list_for_each_entry(batman_if, &if_list, list) { - - list_del_rcu(&batman_if->list); + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device);
- /* first deactivate interface */ - if (batman_if->if_active != IF_INACTIVE) - hardif_deactivate_interface(batman_if); - - call_rcu(&batman_if->rcu, hardif_free_interface); - } -} - -static int resize_orig(struct orig_node *orig_node, int if_num) -{ - void *data_ptr; + if (batman_if->if_status == IF_ACTIVE) + hardif_deactivate_interface(batman_if);
- data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS, - GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } + if (batman_if->if_status != IF_INACTIVE) + return;
- memcpy(data_ptr, orig_node->bcast_own, - if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS); - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; + printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev); + bat_priv->num_ifaces--; + orig_hash_del_if(batman_if, bat_priv->num_ifaces);
- data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); - return -1; - } + if (batman_if == bat_priv->primary_if) + set_primary_if(bat_priv, get_active_batman_if());
- memcpy(data_ptr, orig_node->bcast_own_sum, if_num * sizeof(uint8_t)); - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; + kfree(batman_if->packet_buff); + batman_if->packet_buff = NULL; + batman_if->if_status = IF_NOT_IN_USE;
- return 0; + if ((atomic_read(&module_state) == MODULE_ACTIVE) && + (bat_priv->num_ifaces == 0)) + deactivate_module(); }
- -/* adds an interface the interface list and activate it, if possible */ -int hardif_add_interface(char *dev, int if_num) +static struct batman_if *hardif_add_interface(struct net_device *net_dev) { struct batman_if *batman_if; - struct batman_packet *batman_packet; - struct orig_node *orig_node; - unsigned long flags; - HASHIT(hashit); + int ret;
- batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL); + ret = is_valid_iface(net_dev); + if (ret != 1) + goto out;
+ batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); if (!batman_if) { - printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", dev); - return -1; - } - - batman_if->net_dev = NULL; - - if ((if_num == 0) && (num_hna > 0)) - batman_if->packet_len = BAT_PACKET_LEN + num_hna * ETH_ALEN; - else - batman_if->packet_len = BAT_PACKET_LEN; - - batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL); - - if (!batman_if->packet_buff) { - printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", dev); + printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", + net_dev->name); goto out; }
- batman_if->if_num = if_num; - batman_if->dev = dev; - batman_if->if_active = IF_INACTIVE; - INIT_RCU_HEAD(&batman_if->rcu); + batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); + if (!batman_if->dev) + goto free_if;
- printk(KERN_INFO "batman-adv:Adding interface: %s\n", dev); - avail_ifs++; + ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev); + if (ret) + goto free_dev;
+ batman_if->if_num = -1; + batman_if->net_dev = net_dev; + batman_if->if_status = IF_NOT_IN_USE; + INIT_RCU_HEAD(&batman_if->rcu); INIT_LIST_HEAD(&batman_if->list);
- batman_packet = (struct batman_packet *)(batman_if->packet_buff); - batman_packet->packet_type = BAT_PACKET; - batman_packet->version = COMPAT_VERSION; - batman_packet->flags = 0x00; - batman_packet->ttl = (batman_if->if_num > 0 ? 2 : TTL); - batman_packet->flags = 0; - batman_packet->tq = TQ_MAX_VALUE; - batman_packet->num_hna = 0; - - if (batman_if->packet_len != BAT_PACKET_LEN) { - unsigned char *hna_buff; - int hna_len; - - hna_buff = batman_if->packet_buff + BAT_PACKET_LEN; - hna_len = batman_if->packet_len - BAT_PACKET_LEN; - batman_packet->num_hna = hna_local_fill_buffer(hna_buff, - hna_len); - } - - atomic_set(&batman_if->seqno, 1); + check_known_mac_addr(batman_if->net_dev->dev_addr); + list_add_tail_rcu(&batman_if->list, &if_list); + return batman_if;
- /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock_irqsave(&orig_hash_lock, flags); +free_dev: + kfree(batman_if->dev); +free_if: + kfree(batman_if); +out: + return NULL; +}
- while (hash_iterate(orig_hash, &hashit)) { - orig_node = hashit.bucket->data; - if (resize_orig(orig_node, if_num) == -1) { - spin_unlock_irqrestore(&orig_hash_lock, flags); - goto out; - } - } +static void hardif_free_interface(struct rcu_head *rcu) +{ + struct batman_if *batman_if = container_of(rcu, struct batman_if, rcu);
- spin_unlock_irqrestore(&orig_hash_lock, flags); + /* delete all references to this batman_if */ + purge_orig(NULL); + purge_outstanding_packets(batman_if);
- if (!hardif_is_interface_up(batman_if->dev)) - printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); - else - hardif_activate_interface(batman_if); + kfree(batman_if->dev); + kfree(batman_if); +}
- list_add_tail_rcu(&batman_if->list, &if_list); +static void hardif_remove_interface(struct batman_if *batman_if) +{ + /* first deactivate interface */ + if (batman_if->if_status != IF_NOT_IN_USE) + hardif_disable_interface(batman_if);
- /* begin sending originator messages on that interface */ - schedule_own_packet(batman_if); - return 1; + if (batman_if->if_status != IF_NOT_IN_USE) + return;
-out: - kfree(batman_if->packet_buff); - kfree(batman_if); - kfree(dev); - return -1; + batman_if->if_status = IF_TO_BE_REMOVED; + list_del_rcu(&batman_if->list); + sysfs_del_hardif(&batman_if->hardif_obj); + call_rcu(&batman_if->rcu, hardif_free_interface); }
-char hardif_get_active_if_num(void) +void hardif_remove_interfaces(void) { - return active_ifs; + struct batman_if *batman_if, *batman_if_tmp; + + list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) + hardif_remove_interface(batman_if); }
static int hard_if_event(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { - struct net_device *dev = (struct net_device *)ptr; - struct batman_if *batman_if = get_batman_if_by_name(dev->name); + struct net_device *net_dev = (struct net_device *)ptr; + struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); + + if (!batman_if) + batman_if = hardif_add_interface(net_dev);
if (!batman_if) goto out;
switch (event) { + case NETDEV_REGISTER: + break; + case NETDEV_UP: + hardif_activate_interface(bat_priv, batman_if); + break; case NETDEV_GOING_DOWN: case NETDEV_DOWN: - case NETDEV_UNREGISTER: hardif_deactivate_interface(batman_if); break; - case NETDEV_UP: - hardif_activate_interface(batman_if); - if ((atomic_read(&module_state) == MODULE_INACTIVE) && - (hardif_get_active_if_num() > 0)) { - activate_module(); - } + case NETDEV_UNREGISTER: + hardif_remove_interface(batman_if); + break; + case NETDEV_CHANGENAME: + break; + case NETDEV_CHANGEADDR: + check_known_mac_addr(batman_if->net_dev->dev_addr); + update_mac_addresses(batman_if); + if (batman_if == bat_priv->primary_if) + set_primary_if(bat_priv, batman_if); break; - /* NETDEV_CHANGEADDR - mac address change - what are we doing here ? */ default: break; };
- update_min_mtu(); - out: return NOTIFY_DONE; }
-/* find batman interface by netdev. assumes rcu_read_lock on */ -static struct batman_if *find_batman_if(struct net_device *dev) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->net_dev == dev) { - rcu_read_unlock(); - return batman_if; - } - } - rcu_read_unlock(); - return NULL; -} - - /* receive a packet with the batman ethertype coming on a hard * interface */ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, @@ -444,12 +453,12 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, || !skb_mac_header(skb))) goto err_free;
- batman_if = find_batman_if(skb->dev); + batman_if = get_batman_if_by_netdev(skb->dev); if (!batman_if) goto err_free;
/* discard frames on not active interfaces */ - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto err_free;
stats = (struct net_device_stats *)dev_get_stats(skb->dev); diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 4100a27..1e5fc3e 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -19,19 +19,19 @@ * */
-#define IF_INACTIVE 0 -#define IF_ACTIVE 1 -/* #define IF_TO_BE_DEACTIVATED 2 - not needed anymore */ -#define IF_TO_BE_ACTIVATED 3 +#define IF_NOT_IN_USE 0 +#define IF_TO_BE_REMOVED 1 +#define IF_INACTIVE 2 +#define IF_ACTIVE 3 +#define IF_TO_BE_ACTIVATED 4 +#define IF_I_WANT_YOU 5
extern struct notifier_block hard_if_notifier;
+struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); +int hardif_enable_interface(struct batman_if *batman_if); +void hardif_disable_interface(struct batman_if *batman_if); void hardif_remove_interfaces(void); -int hardif_add_interface(char *dev, int if_num); -void hardif_deactivate_interface(struct batman_if *batman_if); -char hardif_get_active_if_num(void); -void hardif_check_interfaces_status(void); -void hardif_check_interfaces_status_wq(struct work_struct *work); int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 7d72685..c1e57aa 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -20,7 +20,6 @@ */
#include "main.h" -#include "proc.h" #include "bat_sysfs.h" #include "routing.h" #include "send.h" @@ -44,7 +43,6 @@ DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t vis_interval; int16_t num_hna; -int16_t num_ifs;
struct net_device *soft_device;
@@ -89,10 +87,6 @@ int init_module(void) if (!bat_event_workqueue) return -ENOMEM;
- retval = setup_procfs(); - if (retval < 0) - return retval; - bat_device_init();
/* initialize layer 2 interface */ @@ -135,7 +129,10 @@ end:
void cleanup_module(void) { - shutdown_module(); + deactivate_module(); + + unregister_netdevice_notifier(&hard_if_notifier); + hardif_remove_interfaces();
if (soft_device) { sysfs_del_meshif(soft_device); @@ -145,9 +142,6 @@ void cleanup_module(void)
dev_remove_pack(&batman_adv_packet_type);
- unregister_netdevice_notifier(&hard_if_notifier); - cleanup_procfs(); - destroy_workqueue(bat_event_workqueue); bat_event_workqueue = NULL; } @@ -178,17 +172,17 @@ void activate_module(void)
err: printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n"); - shutdown_module(); + deactivate_module(); end: return; }
/* shuts down the whole module.*/ -void shutdown_module(void) +void deactivate_module(void) { atomic_set(&module_state, MODULE_DEACTIVATING);
- purge_outstanding_packets(); + purge_outstanding_packets(NULL); flush_workqueue(bat_event_workqueue);
vis_quit(); @@ -203,7 +197,6 @@ void shutdown_module(void) synchronize_net(); bat_device_destroy();
- hardif_remove_interfaces(); synchronize_rcu(); atomic_set(&module_state, MODULE_INACTIVE); } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 59a70c7..247196c 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -129,7 +129,6 @@ extern spinlock_t forw_bcast_list_lock;
extern atomic_t vis_interval; extern int16_t num_hna; -extern int16_t num_ifs;
extern struct net_device *soft_device;
@@ -138,7 +137,7 @@ extern atomic_t module_state; extern struct workqueue_struct *bat_event_workqueue;
void activate_module(void); -void shutdown_module(void); +void deactivate_module(void); void inc_module_count(void); void dec_module_count(void); int addr_to_string(char *buff, uint8_t *addr); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 4152701..44bbe89 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -118,6 +118,8 @@ void free_orig_node(void *data) * address if it does not exits */ struct orig_node *get_orig_node(uint8_t *addr) { + /* FIXME: each batman_if will be attached to a softif */ + struct bat_priv *bat_priv = netdev_priv(soft_device); struct orig_node *orig_node; struct hashtable_t *swaphash; int size; @@ -139,13 +141,13 @@ struct orig_node *get_orig_node(uint8_t *addr) orig_node->router = NULL; orig_node->hna_buff = NULL;
- size = num_ifs * sizeof(TYPE_OF_WORD) * NUM_WORDS; + size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS;
orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); if (!orig_node->bcast_own) goto free_orig_node;
- size = num_ifs * sizeof(uint8_t); + size = bat_priv->num_ifaces * sizeof(uint8_t); orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); if (!orig_node->bcast_own_sum) goto free_bcast_own; @@ -182,16 +184,25 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
*best_neigh_node = NULL;
- /* for all neighbors towards this originator ... */ list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { neigh_node = list_entry(list_pos, struct neigh_node, list);
- if (time_after(jiffies, + if ((time_after(jiffies, (neigh_node->last_valid + - ((PURGE_TIMEOUT * HZ) / 1000)))) { - - bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ)); + ((PURGE_TIMEOUT * HZ) / 1000)))) || + (neigh_node->if_incoming->if_status == + IF_TO_BE_REMOVED)) { + + if (neigh_node->if_incoming->if_status == + IF_TO_BE_REMOVED) + bat_dbg(DBG_BATMAN, "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", + orig_node->orig, neigh_node->addr, + neigh_node->if_incoming->dev); + else + bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", + orig_node->orig, neigh_node->addr, + (neigh_node->last_valid / HZ));
neigh_purged = true; list_del(list_pos); @@ -246,13 +257,17 @@ void purge_orig(struct work_struct *work)
spin_unlock_irqrestore(&orig_hash_lock, flags);
- start_purge_timer(); + /* if work == NULL we were not called by the timer + * and thus do not need to re-arm the timer */ + if (work) + start_purge_timer(); }
ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { HASHIT(hashit); + struct bat_priv *bat_priv = netdev_priv(net_dev); struct orig_node *orig_node; struct neigh_node *neigh_node; size_t hdr_len, tmp_len; @@ -260,10 +275,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -272,9 +284,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; }
- if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) { - rcu_read_unlock(); - + if (bat_priv->primary_if->if_status != IF_ACTIVE) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - primary interface not active\n", @@ -283,12 +293,12 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return 0; }
+ rcu_read_lock(); hdr_len = sprintf(buff, " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, - ((struct batman_if *)if_list.next)->dev, - ((struct batman_if *)if_list.next)->addr_str, + bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, net_dev->name); rcu_read_unlock();
@@ -347,3 +357,152 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, return bytes_written; }
+static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) +{ + void *data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, + GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own, + (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS); + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + (max_if_num - 1) * sizeof(uint8_t)); + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) +{ + struct orig_node *orig_node; + HASHIT(hashit); + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock(&orig_hash_lock); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + + if (orig_node_add_if(orig_node, max_if_num) == -1) + goto err; + } + + spin_unlock(&orig_hash_lock); + return 0; + +err: + spin_unlock(&orig_hash_lock); + return -ENOMEM; +} + +static int orig_node_del_if(struct orig_node *orig_node, + int max_if_num, int del_if_num) +{ + void *data_ptr = NULL; + int chunk_size; + + /* last interface was removed */ + if (max_if_num == 0) + goto free_bcast_own; + + chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; + data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + /* copy first part */ + memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); + + /* copy second part */ + memcpy(data_ptr, + orig_node->bcast_own + ((del_if_num + 1) * chunk_size), + (max_if_num - del_if_num) * chunk_size); + +free_bcast_own: + kfree(orig_node->bcast_own); + orig_node->bcast_own = data_ptr; + + if (max_if_num == 0) + goto free_own_sum; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + return -1; + } + + memcpy(data_ptr, orig_node->bcast_own_sum, + del_if_num * sizeof(uint8_t)); + + memcpy(data_ptr, + orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), + (max_if_num - del_if_num) * sizeof(uint8_t)); + +free_own_sum: + kfree(orig_node->bcast_own_sum); + orig_node->bcast_own_sum = data_ptr; + + return 0; +} + +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) +{ + struct batman_if *batman_if_tmp; + struct orig_node *orig_node; + HASHIT(hashit); + int ret; + + /* resize all orig nodes because orig_node->bcast_own(_sum) depend on + * if_num */ + spin_lock(&orig_hash_lock); + + while (hash_iterate(orig_hash, &hashit)) { + orig_node = hashit.bucket->data; + + ret = orig_node_del_if(orig_node, max_if_num, + batman_if->if_num); + + if (ret == -1) + goto err; + } + + /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ + rcu_read_lock(); + list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { + if (batman_if_tmp->if_status == IF_NOT_IN_USE) + continue; + + if (batman_if == batman_if_tmp) + continue; + + if (batman_if_tmp->if_num > batman_if->if_num) + batman_if_tmp->if_num--; + } + rcu_read_unlock(); + + batman_if->if_num = -1; + spin_unlock(&orig_hash_lock); + return 0; + +err: + spin_unlock(&orig_hash_lock); + return -ENOMEM; +} diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index 745b4b0..afbc7c0 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -30,3 +30,5 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, uint8_t *neigh, struct batman_if *if_incoming); ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off); +int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); +int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); diff --git a/drivers/staging/batman-adv/proc.c b/drivers/staging/batman-adv/proc.c deleted file mode 100644 index 25b24fe..0000000 --- a/drivers/staging/batman-adv/proc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "proc.h" -#include "routing.h" -#include "translation-table.h" -#include "hard-interface.h" -#include "types.h" -#include "hash.h" -#include "vis.h" - -static struct proc_dir_entry *proc_batman_dir, *proc_interface_file; - -static int proc_interfaces_read(struct seq_file *seq, void *offset) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - seq_printf(seq, "[%8s] %s %s\n", - (batman_if->if_active == IF_ACTIVE ? - "active" : "inactive"), - batman_if->dev, - (batman_if->if_active == IF_ACTIVE ? - batman_if->addr_str : " ")); - } - rcu_read_unlock(); - - return 0; -} - -static int proc_interfaces_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_interfaces_read, NULL); -} - -static ssize_t proc_interfaces_write(struct file *instance, - const char __user *userbuffer, - size_t count, loff_t *data) -{ - char *if_string, *colon_ptr = NULL, *cr_ptr = NULL; - int not_copied = 0, if_num = 0, add_success; - struct batman_if *batman_if = NULL; - - if_string = kmalloc(count, GFP_KERNEL); - - if (!if_string) - return -ENOMEM; - - if (count > IFNAMSIZ - 1) { - printk(KERN_WARNING "batman-adv:Can't add interface: device name is too long\n"); - goto end; - } - - not_copied = copy_from_user(if_string, userbuffer, count); - if_string[count - not_copied - 1] = 0; - - colon_ptr = strchr(if_string, ':'); - if (colon_ptr) - *colon_ptr = 0; - - if (!colon_ptr) { - cr_ptr = strchr(if_string, '\n'); - if (cr_ptr) - *cr_ptr = 0; - } - - if (strlen(if_string) == 0) { - shutdown_module(); - num_ifs = 0; - goto end; - } - - /* add interface */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (strncmp(batman_if->dev, if_string, count) == 0) { - printk(KERN_ERR "batman-adv:Given interface is already active: %s\n", if_string); - rcu_read_unlock(); - goto end; - - } - - if_num++; - } - rcu_read_unlock(); - - add_success = hardif_add_interface(if_string, if_num); - if (add_success < 0) - goto end; - - num_ifs = if_num + 1; - - if ((atomic_read(&module_state) == MODULE_INACTIVE) && - (hardif_get_active_if_num() > 0)) - activate_module(); - - return count; -end: - kfree(if_string); - return count; -} - -static const struct file_operations proc_interfaces_fops = { - .owner = THIS_MODULE, - .open = proc_interfaces_open, - .read = seq_read, - .write = proc_interfaces_write, - .llseek = seq_lseek, - .release = single_release, -}; - -void cleanup_procfs(void) -{ - if (proc_interface_file) - remove_proc_entry(PROC_FILE_INTERFACES, proc_batman_dir); - - if (proc_batman_dir) -#ifdef __NET_NET_NAMESPACE_H - remove_proc_entry(PROC_ROOT_DIR, init_net.proc_net); -#else - remove_proc_entry(PROC_ROOT_DIR, proc_net); -#endif -} - -int setup_procfs(void) -{ -#ifdef __NET_NET_NAMESPACE_H - proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, init_net.proc_net); -#else - proc_batman_dir = proc_mkdir(PROC_ROOT_DIR, proc_net); -#endif - - if (!proc_batman_dir) { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s' folder failed\n", PROC_ROOT_DIR); - return -EFAULT; - } - - proc_interface_file = create_proc_entry(PROC_FILE_INTERFACES, - S_IWUSR | S_IRUGO, - proc_batman_dir); - if (proc_interface_file) { - proc_interface_file->proc_fops = &proc_interfaces_fops; - } else { - printk(KERN_ERR "batman-adv: Registering the '/proc/net/%s/%s' file failed\n", PROC_ROOT_DIR, PROC_FILE_INTERFACES); - cleanup_procfs(); - return -EFAULT; - } - - return 0; -} diff --git a/drivers/staging/batman-adv/proc.h b/drivers/staging/batman-adv/proc.h deleted file mode 100644 index 6f4f5b3..0000000 --- a/drivers/staging/batman-adv/proc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include <linux/proc_fs.h> -#include <linux/seq_file.h> - -#define PROC_ROOT_DIR "batman-adv" -#define PROC_FILE_INTERFACES "interfaces" - -void cleanup_procfs(void); -int setup_procfs(void); - diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 0a9f52b..7b8aa27 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -205,7 +205,7 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, batman_packet->tq = ((batman_packet->tq * orig_neigh_node->tq_own * orig_neigh_node->tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); + (TQ_MAX_VALUE * TQ_MAX_VALUE));
bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, @@ -387,7 +387,7 @@ void receive_bat_packet(struct ethhdr *ethhdr, batman_packet->version, has_directlink_flag);
list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) continue;
if (compare_orig(ethhdr->h_source, @@ -893,7 +893,7 @@ int recv_bcast_packet(struct sk_buff *skb) if (is_my_mac(ethhdr->h_source)) return NET_RX_DROP;
- bcast_packet = (struct bcast_packet *) skb->data; + bcast_packet = (struct bcast_packet *)skb->data;
/* ignore broadcasts originated by myself */ if (is_my_mac(bcast_packet->orig)) diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index de2344a..31d86ae 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -57,7 +57,7 @@ int send_skb_packet(struct sk_buff *skb, { struct ethhdr *ethhdr;
- if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) goto send_skb_err;
if (unlikely(!batman_if->net_dev)) @@ -123,7 +123,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet, int16_t buff_pos; struct batman_packet *batman_packet;
- if (batman_if->if_active != IF_ACTIVE) + if (batman_if->if_status != IF_ACTIVE) return;
packet_num = 0; @@ -182,7 +182,7 @@ static void send_packet(struct forw_packet *forw_packet) return; }
- if (forw_packet->if_incoming->if_active != IF_ACTIVE) + if (forw_packet->if_incoming->if_status != IF_ACTIVE) return;
/* multihomed peer assumed */ @@ -243,7 +243,13 @@ void schedule_own_packet(struct batman_if *batman_if) struct bat_priv *bat_priv = netdev_priv(soft_device); unsigned long send_time; struct batman_packet *batman_packet; - int vis_server = atomic_read(&bat_priv->vis_mode); + int vis_server; + + if ((batman_if->if_status == IF_NOT_IN_USE) || + (batman_if->if_status == IF_TO_BE_REMOVED)) + return; + + vis_server = atomic_read(&bat_priv->vis_mode);
/** * the interface gets activated here to avoid race conditions between @@ -252,11 +258,12 @@ void schedule_own_packet(struct batman_if *batman_if) * outdated packets (especially uninitialized mac addresses) in the * packet queue */ - if (batman_if->if_active == IF_TO_BE_ACTIVATED) - batman_if->if_active = IF_ACTIVE; + if (batman_if->if_status == IF_TO_BE_ACTIVATED) + batman_if->if_status = IF_ACTIVE;
/* if local hna has changed and interface is a primary interface */ - if ((atomic_read(&hna_local_changed)) && (batman_if->if_num == 0)) + if ((atomic_read(&hna_local_changed)) && + (batman_if == bat_priv->primary_if)) rebuild_batman_packet(batman_if);
/** @@ -374,13 +381,11 @@ void add_bcast_packet_to_list(struct sk_buff *skb)
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); if (!forw_packet) - return; + goto out;
skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) { - kfree(forw_packet); - return; - } + if (!skb) + goto packet_free;
skb_reset_mac_header(skb);
@@ -391,6 +396,12 @@ void add_bcast_packet_to_list(struct sk_buff *skb) forw_packet->num_packets = 0;
_add_bcast_packet_to_list(forw_packet, 1); + return; + +packet_free: + kfree(forw_packet); +out: + return; }
void send_outstanding_bcast_packet(struct work_struct *work) @@ -455,19 +466,31 @@ void send_outstanding_bat_packet(struct work_struct *work) forw_packet_free(forw_packet); }
-void purge_outstanding_packets(void) +void purge_outstanding_packets(struct batman_if *batman_if) { struct forw_packet *forw_packet; struct hlist_node *tmp_node, *safe_tmp_node; unsigned long flags;
- bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n"); + if (batman_if) + bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n", + batman_if->dev); + else + bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
/* free bcast list */ spin_lock_irqsave(&forw_bcast_list_lock, flags); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bcast_list, list) {
+ /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + spin_unlock_irqrestore(&forw_bcast_list_lock, flags);
/** @@ -484,6 +507,14 @@ void purge_outstanding_packets(void) hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &forw_bat_list, list) {
+ /** + * if purge_outstanding_packets() was called with an argmument + * we delete only packets belonging to the given interface + */ + if ((batman_if) && + (forw_packet->if_incoming != batman_if)) + continue; + spin_unlock_irqrestore(&forw_bat_list_lock, flags);
/** diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index b2ddf63..b84a470 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -36,4 +36,4 @@ void schedule_forward_packet(struct orig_node *orig_node, void add_bcast_packet_to_list(struct sk_buff *skb); void send_outstanding_bcast_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work); -void purge_outstanding_packets(void); +void purge_outstanding_packets(struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 4cdebe5..681a0ad 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -251,7 +251,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
/* net_dev won't be available when not active */ - if (orig_node->router->if_incoming->if_active != IF_ACTIVE) + if (orig_node->router->if_incoming->if_status != IF_ACTIVE) goto unlock;
/* don't lock while sending the packets ... we therefore diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index b735200..c7a6635 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -159,16 +159,14 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len) int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { + struct bat_priv *bat_priv = netdev_priv(net_dev); struct hna_local_entry *hna_local_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; size_t hdr_len;
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -176,7 +174,6 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
return 0; } - rcu_read_unlock();
hdr_len = sprintf(buff, "Locally retrieved addresses (from %s) announced via HNA:\n", @@ -376,16 +373,14 @@ void hna_global_add_orig(struct orig_node *orig_node, int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, size_t count, loff_t off) { + struct bat_priv *bat_priv = netdev_priv(net_dev); struct hna_global_entry *hna_global_entry; HASHIT(hashit); int bytes_written = 0; unsigned long flags; size_t hdr_len;
- rcu_read_lock(); - if (list_empty(&if_list)) { - rcu_read_unlock(); - + if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, "BATMAN mesh %s disabled - please specify interfaces to enable it\n", @@ -393,7 +388,6 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
return 0; } - rcu_read_unlock();
hdr_len = sprintf(buff, "Globally announced HNAs received via the mesh %s (translation table):\n", diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index ffaa16c..eba1fa6 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -36,12 +36,13 @@ struct batman_if { struct list_head list; int16_t if_num; char *dev; - char if_active; + char if_status; char addr_str[ETH_STR_LEN]; struct net_device *net_dev; atomic_t seqno; unsigned char *packet_buff; int packet_len; + struct kobject *hardif_obj; struct rcu_head rcu;
}; @@ -84,6 +85,8 @@ struct bat_priv { atomic_t aggregation_enabled; atomic_t vis_mode; atomic_t orig_interval; + char num_ifaces; + struct batman_if *primary_if; struct kobject *mesh_obj; };
diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 57d69d7..b6ff031 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -173,13 +173,10 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff, unsigned long flags; int vis_server = atomic_read(&bat_priv->vis_mode);
- rcu_read_lock(); - if (list_empty(&if_list) || (vis_server == VIS_TYPE_CLIENT_UPDATE)) { - rcu_read_unlock(); + if ((!bat_priv->primary_if) || + (vis_server == VIS_TYPE_CLIENT_UPDATE)) return 0; - }
- rcu_read_unlock(); hdr_len = 0;
spin_lock_irqsave(&vis_hash_lock, flags); @@ -498,7 +495,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) if (orig_node->router != NULL && compare_orig(orig_node->router->addr, orig_node->orig) - && (orig_node->router->if_incoming->if_active == + && (orig_node->router->if_incoming->if_status == IF_ACTIVE) && orig_node->router->tq_avg > 0) {
From: Sven Eckelmann sven.eckelmann@gmx.de
This patch fixes unnecessary whitespaces before a quoted newline that the remaining batman-adv files had.
Reported-by: Luis de Bethencourt luisbg@ubuntu.com Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/bat_sysfs.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 1811c8d..e2c000b 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -75,7 +75,7 @@ static ssize_t show_aggr_ogm(struct kobject *kobj, struct attribute *attr, struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); int aggr_status = atomic_read(&bat_priv->aggregation_enabled);
- return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1 \n", + return sprintf(buff, "status: %s\ncommands: enable, disable, 0, 1\n", aggr_status == 0 ? "disabled" : "enabled"); }
@@ -123,7 +123,7 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); int vis_mode = atomic_read(&bat_priv->vis_mode);
- return sprintf(buff, "status: %s\ncommands: client, server, %d, %d \n", + return sprintf(buff, "status: %s\ncommands: client, server, %d, %d\n", vis_mode == VIS_TYPE_CLIENT_UPDATE ? "client" : "server", VIS_TYPE_SERVER_SYNC, VIS_TYPE_CLIENT_UPDATE); @@ -364,7 +364,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, if (!batman_if) return 0;
- return sprintf(buff, "status: %s\ncommands: none, bat0 \n", + return sprintf(buff, "status: %s\ncommands: none, bat0\n", batman_if->if_status == IF_NOT_IN_USE ? "none" : "bat0"); }
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
BATMAN and broadcast packets are tracked with a sequence number window of currently 64 entries to measure and avoid duplicates. Packets which have a sequence number smaller than the newest received packet minus 64 are not within this sequence number window anymore and are called "old packets" from now on.
When old packets are received, the routing code assumes that the host of the originator has been restarted. This assumption however might be wrong as packets can also be delayed by NIC drivers, e.g. because of long queues or collision detection in dense WiFi? environments. This behaviour can be reproduced by doing a broadcast ping flood in a dense node environment.
The effect is that the sequence number window is jumping forth and back, accepting and forwarding any packet (because packets are assumed to be "new") and causing loops.
To overcome this problem, the sequence number handling has been reorganized. When an old packet is received, the window is reset back only once. Other old packets are dropped for (currently) 30 seconds to "protect" the new sequence number and avoid the hopping as described above.
The reorganization brings some code cleanups (at least i hope you feel the same) and also fixes a bug in count_real_packets() which falsely updated the last_real_seqno for slightly older packets within the seqno window if they are no duplicates.
This second version of the patch also fixes a problem where for seq_diff==64 bit_shift() reads from outside of the seqno window, and removes the loop for seq_diff == -64 which was present in the first patch.
The third iteration also adds a window for the next expected sequence numbers. This minimizes sequence number flapping for packets with very big differences (e.g. 3 packets with seqno 0, 25000 and 50000 might still cause problems without this window).
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/bitarray.c | 74 ++++++++++++++++------- drivers/staging/batman-adv/main.h | 4 + drivers/staging/batman-adv/originator.c | 2 + drivers/staging/batman-adv/routing.c | 99 +++++++++++++++++++++++-------- drivers/staging/batman-adv/types.h | 4 + 5 files changed, 136 insertions(+), 47 deletions(-)
diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c index 7848305..2fef6e3 100644 --- a/drivers/staging/batman-adv/bitarray.c +++ b/drivers/staging/batman-adv/bitarray.c @@ -68,7 +68,7 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) int32_t word_offset, word_num; int32_t i;
- if (n <= 0) + if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) return;
word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ @@ -111,48 +111,76 @@ void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) seq_bits[i] = 0; }
+static void bit_reset_window(TYPE_OF_WORD *seq_bits) +{ + int i; + for (i = 0; i < NUM_WORDS; i++) + seq_bits[i] = 0; +} +
-/* receive and process one packet, returns 1 if received seq_num is considered - * new, 0 if old */ +/* receive and process one packet within the sequence number window. + * + * returns: + * 1 if the window was moved (either new or very old) + * 0 if the window was not moved/shifted. + */ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff, int8_t set_mark) { - int i; + /* sequence number is slightly older. We already got a sequence number + * higher than this one, so we just mark it. */
- /* we already got a sequence number higher than this one, so we just - * mark it. this should wrap around the integer just fine */ - if ((seq_num_diff < 0) && (seq_num_diff >= -TQ_LOCAL_WINDOW_SIZE)) { + if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { if (set_mark) bit_mark(seq_bits, -seq_num_diff); return 0; }
- /* it seems we missed a lot of packets or the other host restarted */ - if ((seq_num_diff > TQ_LOCAL_WINDOW_SIZE) || - (seq_num_diff < -TQ_LOCAL_WINDOW_SIZE)) { + /* sequence number is slightly newer, so we shift the window and + * set the mark if required */
- if (seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - bat_dbg(DBG_BATMAN, - "We missed a lot of packets (%i) !\n", - seq_num_diff-1); + if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { + bit_shift(seq_bits, seq_num_diff);
- if (-seq_num_diff > TQ_LOCAL_WINDOW_SIZE) - bat_dbg(DBG_BATMAN, - "Other host probably restarted !\n"); + if (set_mark) + bit_mark(seq_bits, 0); + return 1; + }
- for (i = 0; i < NUM_WORDS; i++) - seq_bits[i] = 0; + /* sequence number is much newer, probably missed a lot of packets */
+ if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { + bat_dbg(DBG_BATMAN, + "We missed a lot of packets (%i) !\n", + seq_num_diff - 1); + bit_reset_window(seq_bits); if (set_mark) - seq_bits[0] = 1; /* we only have the latest packet */ - } else { - bit_shift(seq_bits, seq_num_diff); + bit_mark(seq_bits, 0); + return 1; + } + + /* received a much older packet. The other host either restarted + * or the old packet got delayed somewhere in the network. The + * packet should be dropped without calling this function if the + * seqno window is protected. */ + + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
+ bat_dbg(DBG_BATMAN, + "Other host probably restarted!\n"); + + bit_reset_window(seq_bits); if (set_mark) bit_mark(seq_bits, 0); + + return 1; }
- return 1; + /* never reached */ + return 0; }
/* count the hamming weight, how many good packets did we receive? just count diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 247196c..58c1ec1 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -61,6 +61,10 @@ * forw_packet->direct_link_flags */ #define MAX_AGGREGATION_MS 100
+#define RESET_PROTECTION_MS 30000 +#define EXPECTED_SEQNO_RANGE 4096 +/* don't reset again within 30 seconds */ + #define MODULE_INACTIVE 0 #define MODULE_ACTIVE 1 #define MODULE_DEACTIVATING 2 diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 44bbe89..01d71d7 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -140,6 +140,8 @@ struct orig_node *get_orig_node(uint8_t *addr) memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; orig_node->hna_buff = NULL; + orig_node->bcast_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; + orig_node->batman_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1;
size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS;
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 7b8aa27..bf67059 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -304,6 +304,38 @@ update_hna: update_routes(orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); }
+/* checks whether the host restarted and is in the protection time. + * returns: + * 0 if the packet is to be accepted + * 1 if the packet is to be ignored. + */ +static int window_protected(int16_t seq_num_diff, + unsigned long *last_reset) +{ + if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) + || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { + if (time_after(jiffies, *last_reset + + msecs_to_jiffies(RESET_PROTECTION_MS))) { + + *last_reset = jiffies; + bat_dbg(DBG_BATMAN, + "old packet received, start protection\n"); + + return 0; + } else + return 1; + } + return 0; +} + +/* processes a batman packet for all interfaces, adjusts the sequence number and + * finds out whether it is a duplicate. + * returns: + * 1 the packet is a duplicate + * 0 the packet has not yet been received + * -1 the packet is old and has been received while the seqno window + * was protected. Caller should drop it. + */ static char count_real_packets(struct ethhdr *ethhdr, struct batman_packet *batman_packet, struct batman_if *if_incoming) @@ -311,31 +343,41 @@ static char count_real_packets(struct ethhdr *ethhdr, struct orig_node *orig_node; struct neigh_node *tmp_neigh_node; char is_duplicate = 0; - uint16_t seq_diff; + int16_t seq_diff; + int need_update = 0; + int set_mark;
orig_node = get_orig_node(batman_packet->orig); if (orig_node == NULL) return 0;
+ seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + + /* signalize caller that the packet is to be dropped. */ + if (window_protected(seq_diff, &orig_node->batman_seqno_reset)) + return -1; + list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) {
- if (!is_duplicate) - is_duplicate = - get_bit_status(tmp_neigh_node->real_bits, + is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, orig_node->last_real_seqno, batman_packet->seqno); - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; + if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && (tmp_neigh_node->if_incoming == if_incoming)) - bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 1); + set_mark = 1; else - bit_get_packet(tmp_neigh_node->real_bits, seq_diff, 0); + set_mark = 0; + + /* if the window moved, set the update flag. */ + need_update |= bit_get_packet(tmp_neigh_node->real_bits, + seq_diff, set_mark);
tmp_neigh_node->real_packet_count = bit_packet_count(tmp_neigh_node->real_bits); }
- if (!is_duplicate) { + if (need_update) { bat_dbg(DBG_BATMAN, "updating last_seqno: old %d, new %d\n", orig_node->last_real_seqno, batman_packet->seqno); orig_node->last_real_seqno = batman_packet->seqno; @@ -453,24 +495,27 @@ void receive_bat_packet(struct ethhdr *ethhdr, return; }
- if (batman_packet->tq == 0) { - count_real_packets(ethhdr, batman_packet, if_incoming); - - bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); - return; - } - if (is_my_oldorig) { bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); return; }
- is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); - orig_node = get_orig_node(batman_packet->orig); if (orig_node == NULL) return;
+ is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); + + if (is_duplicate == -1) { + bat_dbg(DBG_BATMAN, "Drop packet: packet within seqno protection time (sender: %pM)\n", ethhdr->h_source); + return; + } + + if (batman_packet->tq == 0) { + bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); + return; + } + /* avoid temporary routing loops */ if ((orig_node->router) && (orig_node->router->orig_node->router) && @@ -866,13 +911,13 @@ int recv_unicast_packet(struct sk_buff *skb) return ret; }
- int recv_bcast_packet(struct sk_buff *skb) { struct orig_node *orig_node; struct bcast_packet *bcast_packet; struct ethhdr *ethhdr; int hdr_size = sizeof(struct bcast_packet); + int16_t seq_diff; unsigned long flags;
/* drop packet if it has not necessary minimum size */ @@ -908,7 +953,7 @@ int recv_bcast_packet(struct sk_buff *skb) return NET_RX_DROP; }
- /* check flood history */ + /* check whether the packet is a duplicate */ if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohs(bcast_packet->seqno))) { @@ -916,14 +961,20 @@ int recv_bcast_packet(struct sk_buff *skb) return NET_RX_DROP; }
- /* mark broadcast in flood history */ - if (bit_get_packet(orig_node->bcast_bits, - ntohs(bcast_packet->seqno) - - orig_node->last_bcast_seqno, 1)) + seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno; + + /* check whether the packet is old and the host just restarted. */ + if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) { + spin_unlock_irqrestore(&orig_hash_lock, flags); + return NET_RX_DROP; + } + + /* mark broadcast in flood history, update window position + * if required. */ + if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1)) orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
spin_unlock_irqrestore(&orig_hash_lock, flags); - /* rebroadcast packet */ add_bcast_packet_to_list(skb);
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index eba1fa6..c926219 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -55,6 +55,10 @@ struct orig_node { /* structure for orig_list maintaining nodes of uint8_t tq_own; int tq_asym_penalty; unsigned long last_valid; /* when last packet from this node was received */ + unsigned long bcast_seqno_reset; /* time when the broadcast + seqno window was reset. */ + unsigned long batman_seqno_reset;/* time when the batman seqno + window was reset. */ /* uint8_t gwflags; * flags related to gateway functions: gateway class */ uint8_t flags; /* for now only VIS_SERVER flag. */ unsigned char *hna_buff;
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
This patch limits the queue lengths of batman and broadcast packets. BATMAN packets are held back for aggregation and jittered to avoid interferences. Broadcast packets are stored to be sent out multiple times to increase the probability to be received by other nodes in lossy environments.
Especially in extreme cases like broadcast storms, the queues have been seen to run full, eating up all the memory and triggering the infamous OOM killer. With the queue length limits introduced in this patch, this problem is avoided.
Each queue is limited to 256 entries for now, resulting in 1 MB of maximum space available in total for typical setups (assuming one packet including overhead does not require more than 2000 byte). This should also be reasonable for smaller routers, otherwise the defines can be tweaked later.
This third version of the patch does not increase the local broadcast sequence number when the queue is already full.
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/aggregation.c | 16 ++++++++++++- drivers/staging/batman-adv/main.c | 5 ++++ drivers/staging/batman-adv/main.h | 4 +++ drivers/staging/batman-adv/send.c | 33 ++++++++++++++++++++++---- drivers/staging/batman-adv/send.h | 2 +- drivers/staging/batman-adv/soft-interface.c | 6 ++-- 6 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index a5818ff..ce8b8a6 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -95,6 +95,7 @@ static bool can_aggregate_with(struct batman_packet *new_batman_packet, return false; }
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) /* create a new aggregated packet and add this packet to it */ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, @@ -106,13 +107,26 @@ static void new_aggregated_packet(unsigned char *packet_buff, struct forw_packet *forw_packet_aggr; unsigned long flags;
+ /* own packet should always be scheduled */ + if (!own_packet) { + if (!atomic_dec_not_zero(&batman_queue_left)) { + bat_dbg(DBG_BATMAN, "batman packet queue full\n"); + return; + } + } + forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - if (!forw_packet_aggr) + if (!forw_packet_aggr) { + if (!own_packet) + atomic_inc(&batman_queue_left); return; + }
forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES, GFP_ATOMIC); if (!forw_packet_aggr->packet_buff) { + if (!own_packet) + atomic_inc(&batman_queue_left); kfree(forw_packet_aggr); return; } diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index c1e57aa..aa072d1 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -42,6 +42,9 @@ DEFINE_SPINLOCK(forw_bat_list_lock); DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t vis_interval; +atomic_t bcast_queue_left; +atomic_t batman_queue_left; + int16_t num_hna;
struct net_device *soft_device; @@ -79,6 +82,8 @@ int init_module(void)
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only * for debugging now. */ + atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN); + atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
/* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 58c1ec1..6749ce0 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -69,6 +69,8 @@ #define MODULE_ACTIVE 1 #define MODULE_DEACTIVATING 2
+#define BCAST_QUEUE_LEN 256 +#define BATMAN_QUEUE_LE 256
/* * Debug Messages @@ -132,6 +134,8 @@ extern spinlock_t forw_bat_list_lock; extern spinlock_t forw_bcast_list_lock;
extern atomic_t vis_interval; +extern atomic_t bcast_queue_left; +extern atomic_t batman_queue_left; extern int16_t num_hna;
extern struct net_device *soft_device; diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 31d86ae..f58a9ed 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -375,13 +375,28 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet, send_time); }
-void add_bcast_packet_to_list(struct sk_buff *skb) +#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) +/* add a broadcast packet to the queue and setup timers. broadcast packets + * are sent multiple times to increase probability for beeing received. + * + * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on + * errors. + * + * The skb is not consumed, so the caller should make sure that the + * skb is freed. */ +int add_bcast_packet_to_list(struct sk_buff *skb) { struct forw_packet *forw_packet;
+ if (!atomic_dec_not_zero(&bcast_queue_left)) { + bat_dbg(DBG_BATMAN, "bcast packet queue full\n"); + goto out; + } + forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); + if (!forw_packet) - goto out; + goto out_and_inc;
skb = skb_copy(skb, GFP_ATOMIC); if (!skb) @@ -396,12 +411,14 @@ void add_bcast_packet_to_list(struct sk_buff *skb) forw_packet->num_packets = 0;
_add_bcast_packet_to_list(forw_packet, 1); - return; + return NETDEV_TX_OK;
packet_free: kfree(forw_packet); +out_and_inc: + atomic_inc(&bcast_queue_left); out: - return; + return NETDEV_TX_BUSY; }
void send_outstanding_bcast_packet(struct work_struct *work) @@ -436,8 +453,10 @@ void send_outstanding_bcast_packet(struct work_struct *work) if ((forw_packet->num_packets < 3) && (atomic_read(&module_state) != MODULE_DEACTIVATING)) _add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000)); - else + else { forw_packet_free(forw_packet); + atomic_inc(&bcast_queue_left); + } }
void send_outstanding_bat_packet(struct work_struct *work) @@ -463,6 +482,10 @@ void send_outstanding_bat_packet(struct work_struct *work) (atomic_read(&module_state) != MODULE_DEACTIVATING)) schedule_own_packet(forw_packet->if_incoming);
+ /* don't count own packet */ + if (!forw_packet->own) + atomic_inc(&batman_queue_left); + forw_packet_free(forw_packet); }
diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h index b84a470..feaa2fc 100644 --- a/drivers/staging/batman-adv/send.h +++ b/drivers/staging/batman-adv/send.h @@ -33,7 +33,7 @@ void schedule_forward_packet(struct orig_node *orig_node, struct batman_packet *batman_packet, uint8_t directlink, int hna_buff_len, struct batman_if *if_outgoing); -void add_bcast_packet_to_list(struct sk_buff *skb); +int add_bcast_packet_to_list(struct sk_buff *skb); void send_outstanding_bcast_packet(struct work_struct *work); void send_outstanding_bat_packet(struct work_struct *work); void purge_outstanding_packets(struct batman_if *batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 681a0ad..14b5cca 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -216,10 +216,10 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* set broadcast sequence number */ bcast_packet->seqno = htons(bcast_seqno);
- bcast_seqno++; + /* broadcast packet. on success, increase seqno. */ + if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK) + bcast_seqno++;
- /* broadcast packet */ - add_bcast_packet_to_list(skb); /* a copy is stored in the bcast list, therefore removing * the original skb. */ kfree_skb(skb);
From: Simon Wunderlich siwu@hrz.tu-chemnitz.de
As we always return that the we consumed the skb, we should also free the skb in the case of an error.
Signed-off-by: Simon Wunderlich siwu@hrz.tu-chemnitz.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/soft-interface.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 14b5cca..c3b5288 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -275,6 +275,7 @@ unlock: spin_unlock_irqrestore(&orig_hash_lock, flags); dropped: priv->stats.tx_dropped++; + kfree_skb(skb); end: return NETDEV_TX_OK; }
From: Sven Eckelmann sven.eckelmann@gmx.de
We must ensure that all pointer to a socket buffer are updated when we copy a socket buffer and free our reference to the old one. Another part of the kernel could also free its reference which maybe removes the buffer completely. In that situation we would would feed wrong information to the routing algorithm after the memory area is written again by someone else.
Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/routing.c | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index bf67059..919a4f8 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -614,6 +614,7 @@ int recv_bat_packet(struct sk_buff *skb, skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); }
@@ -639,8 +640,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb) unsigned long flags; uint8_t dstaddr[ETH_ALEN];
- icmp_packet = (struct icmp_packet *) skb->data; - ethhdr = (struct ethhdr *) skb_mac_header(skb); + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb);
/* add data to device queue */ if (icmp_packet->msg_type != ECHO_REQUEST) { @@ -671,7 +672,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; + + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); }
@@ -732,6 +735,7 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb) if (!skb) return NET_RX_DROP; icmp_packet = (struct icmp_packet *) skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); }
@@ -780,7 +784,7 @@ int recv_icmp_packet(struct sk_buff *skb) if (!is_my_mac(ethhdr->h_dest)) return NET_RX_DROP;
- icmp_packet = (struct icmp_packet *) skb->data; + icmp_packet = (struct icmp_packet *)skb->data;
/* packet for me */ if (is_my_mac(icmp_packet->dst)) @@ -812,7 +816,8 @@ int recv_icmp_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - icmp_packet = (struct icmp_packet *) skb->data; + icmp_packet = (struct icmp_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); }
@@ -895,7 +900,8 @@ int recv_unicast_packet(struct sk_buff *skb) skb = skb_copy(skb, GFP_ATOMIC); if (!skb) return NET_RX_DROP; - unicast_packet = (struct unicast_packet *) skb->data; + unicast_packet = (struct unicast_packet *)skb->data; + ethhdr = (struct ethhdr *)skb_mac_header(skb); kfree_skb(skb_old); } /* decrement ttl */
Not much left to do on the TODO list :-)
Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/TODO | 23 +++-------------------- 1 files changed, 3 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 2f15136..518db7f 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,23 +1,6 @@ -=> proc interface -* implement new interface to add/delete interfaces and setting options -* /proc/sys/net/batman-adv/ as main folder -* in interfaces/ list every available interface of the host -* each interfaces/$iface/ contains the following files: --> enable (def: 0) [add/remove this interface to batman-adv] --> ogm_interval (def: 1000) [ogm interval of that interface] --> context (def: bat0) [later we want to support multiple mesh instances via --> bat0/bat1/bat2/..] --> status (read-only) [outputs the interface status from batman's --> perspective] -* in mesh/batX/ list every available mesh subnet --> vis_server (def: 0) [enable/disable vis server for that mesh] --> vis_data (read-only) [outputs the vis data in a raw format] --> aggregate_ogm (def: 1) [enable/disable ogm aggregation for that mesh] --> originators (read-only) [outputs the originator table] --> transtable_global (read-only) [outputs the global translation table] --> transtable_local (read-only) [outputs the local translation table] - -=> fix checkpatch.pl errors +Request a review. +Process the comments from the review. +Move into mainline proper.
Please send all patches to: Marek Lindner lindner_marek@yahoo.de
From: Sven Eckelmann sven.eckelmann@gmx.de
Trailing spaces at the end of a line or before a tab are against Documentation/CodingStyle "3.1: Spaces" and should be avoided. It is also common style to add a single space after commas unless it is followed either by a newline or a tab.
Reported-by: Mikal Sande mikal.sande@gmail.com Reported-by: Luis de Bethencourt luisbg@ubuntu.com Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/main.h | 2 +- drivers/staging/batman-adv/originator.c | 4 ++-- drivers/staging/batman-adv/types.h | 3 +-- drivers/staging/batman-adv/vis.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 6749ce0..8818e2b 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -70,7 +70,7 @@ #define MODULE_DEACTIVATING 2
#define BCAST_QUEUE_LEN 256 -#define BATMAN_QUEUE_LE 256 +#define BATMAN_QUEUE_LEN 256
/* * Debug Messages diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 01d71d7..25a9e21 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -297,7 +297,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
rcu_read_lock(); hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)] \n", + " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, @@ -354,7 +354,7 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
if ((batman_count == 0) && (off == 0)) bytes_written += sprintf(buff + bytes_written, - "No batman nodes in range ... \n"); + "No batman nodes in range ...\n");
return bytes_written; } diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index c926219..0b1fe9e 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -59,8 +59,7 @@ struct orig_node { /* structure for orig_list maintaining nodes of seqno window was reset. */ unsigned long batman_seqno_reset;/* time when the batman seqno window was reset. */ -/* uint8_t gwflags; * flags related to gateway functions: gateway class */ - uint8_t flags; /* for now only VIS_SERVER flag. */ + uint8_t flags; /* for now only VIS_SERVER flag. */ unsigned char *hna_buff; int16_t hna_buff_len; uint16_t last_real_seqno; /* last and best known squence number */ diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index b6ff031..1d3d954 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -40,7 +40,7 @@ * when adding 128 - it is neither a predecessor nor a successor, * after adding more than 127 to the starting value - it is a successor */ #define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ - _dummy > smallest_signed_int(_dummy); }) + _dummy > smallest_signed_int(_dummy); }) #define seq_after(x, y) seq_before(y, x)
struct hashtable_t *vis_hash;
From: Sven Eckelmann sven.eckelmann@gmx.de
Documentation/CodingStyle sets a strongly prefered limit of 80 characters per line in "Chapter 2: Breaking long lines and strings".
Strings must be broken into smaller parts and long statements must be rewritten.
Reported-by: Mikal Sande mikal.sande@gmail.com Reported-by: Mark Rankilor reodge@gmail.com Signed-off-by: Sven Eckelmann sven.eckelmann@gmx.de Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/device.c | 22 +++++++--- drivers/staging/batman-adv/hard-interface.c | 20 ++++++--- drivers/staging/batman-adv/main.c | 17 +++++--- drivers/staging/batman-adv/main.h | 3 +- drivers/staging/batman-adv/originator.c | 47 ++++++++++++------- drivers/staging/batman-adv/routing.c | 57 +++++++++++++++++------ drivers/staging/batman-adv/send.c | 21 +++++--- drivers/staging/batman-adv/soft-interface.c | 8 ++- drivers/staging/batman-adv/translation-table.c | 34 +++++++++----- drivers/staging/batman-adv/types.h | 45 +++++++++++++----- 10 files changed, 186 insertions(+), 88 deletions(-)
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index b2ecba2..ad82ec4 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -57,7 +57,8 @@ int bat_device_setup(void) /* register our device - kernel assigns a free major number */ tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); if (tmp_major < 0) { - printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n", + printk(KERN_ERR "batman-adv:" + "Registering the character device failed with %d\n", tmp_major); return 0; } @@ -65,7 +66,8 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv");
if (IS_ERR(batman_class)) { - printk(KERN_ERR "batman-adv:Could not register class 'batman-adv'\n"); + printk(KERN_ERR "batman-adv:" + "Could not register class 'batman-adv'\n"); return 0; }
@@ -108,7 +110,9 @@ int bat_device_open(struct inode *inode, struct file *file) }
if (i == ARRAY_SIZE(device_client_hash)) { - printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached\n"); + printk(KERN_ERR "batman-adv:" + "Error - can't add another packet client: " + "maximum number of clients reached\n"); kfree(device_client); return -EXFULL; } @@ -209,7 +213,9 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, unsigned long flags;
if (len < sizeof(struct icmp_packet)) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "invalid packet size\n"); return -EINVAL; }
@@ -220,12 +226,16 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, return -EFAULT;
if (icmp_packet.packet_type != BAT_ICMP) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "got bogus packet type (expected: BAT_ICMP)\n"); return -EINVAL; }
if (icmp_packet.msg_type != ECHO_REQUEST) { - bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:" + "Error - can't send packet from char device: " + "got bogus message type (expected: ECHO_REQUEST)\n"); return -EINVAL; }
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index b82cae7..0d1d101 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -149,9 +149,12 @@ static void check_known_mac_addr(uint8_t *addr) if (!compare_orig(batman_if->net_dev->dev_addr, addr)) continue;
- printk(KERN_WARNING "batman-adv:The newly added mac address (%pM) already exists on: %s\n", - addr, batman_if->dev); - printk(KERN_WARNING "batman-adv:It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + printk(KERN_WARNING "batman-adv:" + "The newly added mac address (%pM) already exists on: %s\n", + addr, batman_if->dev); + printk(KERN_WARNING "batman-adv:" + "It is strongly recommended to keep mac addresses unique" + "to avoid problems!\n"); } rcu_read_unlock(); } @@ -242,7 +245,8 @@ int hardif_enable_interface(struct batman_if *batman_if) batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
if (!batman_if->packet_buff) { - printk(KERN_ERR "batman-adv:Can't add interface packet (%s): out of memory\n", + printk(KERN_ERR "batman-adv:" + "Can't add interface packet (%s): out of memory\n", batman_if->dev); goto err; } @@ -266,7 +270,10 @@ int hardif_enable_interface(struct batman_if *batman_if) if (hardif_is_iface_up(batman_if)) hardif_activate_interface(bat_priv, batman_if); else - printk(KERN_ERR "batman-adv:Not using interface %s (retrying later): interface not active\n", batman_if->dev); + printk(KERN_ERR "batman-adv:" + "Not using interface %s " + "(retrying later): interface not active\n", + batman_if->dev);
/* begin scheduling originator messages on that interface */ schedule_own_packet(batman_if); @@ -316,7 +323,8 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); if (!batman_if) { - printk(KERN_ERR "batman-adv:Can't add interface (%s): out of memory\n", + printk(KERN_ERR "batman-adv:" + "Can't add interface (%s): out of memory\n", net_dev->name); goto out; } diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index aa072d1..9d13979 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -99,14 +99,16 @@ int init_module(void) interface_setup);
if (!soft_device) { - printk(KERN_ERR "batman-adv:Unable to allocate the batman interface\n"); + printk(KERN_ERR "batman-adv:" + "Unable to allocate the batman interface\n"); goto end; }
retval = register_netdev(soft_device);
if (retval < 0) { - printk(KERN_ERR "batman-adv:Unable to register the batman interface: %i\n", retval); + printk(KERN_ERR "batman-adv:" + "Unable to register the batman interface: %i\n", retval); goto free_soft_device; }
@@ -118,8 +120,9 @@ int init_module(void) register_netdevice_notifier(&hard_if_notifier); dev_add_pack(&batman_adv_packet_type);
- printk(KERN_INFO "batman-adv:B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", - SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION); + printk(KERN_INFO "batman-adv:" + "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n", + SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
return 0;
@@ -176,7 +179,9 @@ void activate_module(void) goto end;
err: - printk(KERN_ERR "batman-adv:Unable to allocate memory for mesh information structures: out of mem ?\n"); + printk(KERN_ERR "batman-adv:" + "Unable to allocate memory for mesh information structures: " + "out of mem ?\n"); deactivate_module(); end: return; @@ -218,7 +223,7 @@ void dec_module_count(void)
int addr_to_string(char *buff, uint8_t *addr) { - return sprintf(buff, "%02x:%02x:%02x:%02x:%02x:%02x", + return sprintf(buff, MAC_FMT, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); }
diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 8818e2b..5f8343d 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -22,7 +22,8 @@ /* Kernel Programming */ #define LINUX
-#define DRIVER_AUTHOR "Marek Lindner lindner_marek@yahoo.de, Simon Wunderlich siwu@hrz.tu-chemnitz.de" +#define DRIVER_AUTHOR "Marek Lindner lindner_marek@yahoo.de, " \ + "Simon Wunderlich siwu@hrz.tu-chemnitz.de" #define DRIVER_DESC "B.A.T.M.A.N. advanced" #define DRIVER_DEVICE "batman-adv"
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 25a9e21..568aef8 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -140,8 +140,10 @@ struct orig_node *get_orig_node(uint8_t *addr) memcpy(orig_node->orig, addr, ETH_ALEN); orig_node->router = NULL; orig_node->hna_buff = NULL; - orig_node->bcast_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; - orig_node->batman_seqno_reset = jiffies - msecs_to_jiffies(RESET_PROTECTION_MS) - 1; + orig_node->bcast_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS); + orig_node->batman_seqno_reset = jiffies - 1 + - msecs_to_jiffies(RESET_PROTECTION_MS);
size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS;
@@ -198,11 +200,15 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
if (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED) - bat_dbg(DBG_BATMAN, "neighbor purge: originator %pM, neighbor: %pM, iface: %s\n", + bat_dbg(DBG_BATMAN, + "neighbor purge: originator %pM, " + "neighbor: %pM, iface: %s\n", orig_node->orig, neigh_node->addr, neigh_node->if_incoming->dev); else - bat_dbg(DBG_BATMAN, "neighbor timeout: originator %pM, neighbor: %pM, last_valid: %lu\n", + bat_dbg(DBG_BATMAN, + "neighbor timeout: originator %pM, " + "neighbor: %pM, last_valid: %lu\n", orig_node->orig, neigh_node->addr, (neigh_node->last_valid / HZ));
@@ -280,24 +286,25 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name);
return 0; }
- if (bat_priv->primary_if->if_status != IF_ACTIVE) { - if (off == 0) - return sprintf(buff, - "BATMAN mesh %s disabled - primary interface not active\n", - net_dev->name); - + if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0) + return sprintf(buff, + "BATMAN mesh %s " + "disabled - primary interface not active\n", + net_dev->name); + else if (bat_priv->primary_if->if_status != IF_ACTIVE) return 0; - }
rcu_read_lock(); hdr_len = sprintf(buff, - " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", + " %-14s (%s/%i) %17s [%10s]: %20s " + "... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n", "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR, bat_priv->primary_if->dev, bat_priv->primary_if->addr_str, @@ -366,7 +373,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; }
@@ -377,7 +385,8 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; }
@@ -426,7 +435,8 @@ static int orig_node_del_if(struct orig_node *orig_node, chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; }
@@ -447,7 +457,8 @@ free_bcast_own:
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) { - printk(KERN_ERR "batman-adv:Can't resize orig: out of memory\n"); + printk(KERN_ERR + "batman-adv:Can't resize orig: out of memory\n"); return -1; }
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 919a4f8..066dc8b 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -94,7 +94,11 @@ static void update_route(struct orig_node *orig_node,
/* route changed */ } else { - bat_dbg(DBG_ROUTES, "Changing route towards: %pM (now via %pM - was via %pM)\n", orig_node->orig, neigh_node->addr, orig_node->router->addr); + bat_dbg(DBG_ROUTES, + "Changing route towards: %pM " + "(now via %pM - was via %pM)\n", + orig_node->orig, neigh_node->addr, + orig_node->router->addr); }
orig_node->router = neigh_node; @@ -207,7 +211,11 @@ static int isBidirectionalNeigh(struct orig_node *orig_node, orig_neigh_node->tq_asym_penalty) / (TQ_MAX_VALUE * TQ_MAX_VALUE));
- bat_dbg(DBG_BATMAN, "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n", + bat_dbg(DBG_BATMAN, + "bidirectional: " + "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " + "real recv = %2i, local tq: %3i, asym_penalty: %3i, " + "total tq: %3i\n", orig_node->orig, orig_neigh_node->orig, total_count, neigh_node->real_packet_count, orig_neigh_node->tq_own, orig_neigh_node->tq_asym_penalty, batman_packet->tq); @@ -229,7 +237,8 @@ static void update_orig(struct orig_node *orig_node, struct ethhdr *ethhdr, struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; int tmp_hna_buff_len;
- bat_dbg(DBG_BATMAN, "update_originator(): Searching and updating originator entry of received packet\n"); + bat_dbg(DBG_BATMAN, "update_originator(): " + "Searching and updating originator entry of received packet\n");
list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && @@ -422,7 +431,9 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_single_hop_neigh = (compare_orig(ethhdr->h_source, batman_packet->orig) ? 1 : 0);
- bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] (from OG: %pM, via prev OG: %pM, seqno %d, tq %d, TTL %d, V %d, IDF %d)\n", + bat_dbg(DBG_BATMAN, "Received BATMAN packet via NB: %pM, IF: %s [%s] " + "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " + "TTL %d, V %d, IDF %d)\n", ethhdr->h_source, if_incoming->dev, if_incoming->addr_str, batman_packet->orig, batman_packet->prev_sender, batman_packet->seqno, batman_packet->tq, batman_packet->ttl, @@ -457,13 +468,16 @@ void receive_bat_packet(struct ethhdr *ethhdr,
if (is_my_addr) { bat_dbg(DBG_BATMAN, - "Drop packet: received my own broadcast (sender: %pM)\n", + "Drop packet: received my own broadcast (sender: %pM" + ")\n", ethhdr->h_source); return; }
if (is_broadcast) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, "Drop packet: " + "ignoring all packets with broadcast source addr (sender: %pM" + ")\n", ethhdr->h_source); return; }
@@ -491,12 +505,15 @@ void receive_bat_packet(struct ethhdr *ethhdr, bit_packet_count(word); }
- bat_dbg(DBG_BATMAN, "Drop packet: originator packet from myself (via neighbor)\n"); + bat_dbg(DBG_BATMAN, "Drop packet: " + "originator packet from myself (via neighbor)\n"); return; }
if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast echos (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: ignoring all rebroadcast echos (sender: " + "%pM)\n", ethhdr->h_source); return; }
@@ -507,12 +524,15 @@ void receive_bat_packet(struct ethhdr *ethhdr, is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming);
if (is_duplicate == -1) { - bat_dbg(DBG_BATMAN, "Drop packet: packet within seqno protection time (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: packet within seqno protection time " + "(sender: %pM)\n", ethhdr->h_source); return; }
if (batman_packet->tq == 0) { - bat_dbg(DBG_BATMAN, "Drop packet: originator packet with tq equal 0\n"); + bat_dbg(DBG_BATMAN, + "Drop packet: originator packet with tq equal 0\n"); return; }
@@ -524,7 +544,9 @@ void receive_bat_packet(struct ethhdr *ethhdr, !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && (compare_orig(orig_node->router->addr, orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, "Drop packet: ignoring all rebroadcast packets that may make me loop (sender: %pM)\n", ethhdr->h_source); + bat_dbg(DBG_BATMAN, + "Drop packet: ignoring all rebroadcast packets that " + "may make me loop (sender: %pM)\n", ethhdr->h_source); return; }
@@ -562,7 +584,8 @@ void receive_bat_packet(struct ethhdr *ethhdr, schedule_forward_packet(orig_node, ethhdr, batman_packet, 1, hna_buff_len, if_incoming);
- bat_dbg(DBG_BATMAN, "Forwarding packet: rebroadcast neighbor packet with direct link flag\n"); + bat_dbg(DBG_BATMAN, "Forwarding packet: " + "rebroadcast neighbor packet with direct link flag\n"); return; }
@@ -708,8 +731,10 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb)
/* send TTL exceeded if packet is an echo request (traceroute) */ if (icmp_packet->msg_type != ECHO_REQUEST) { - printk(KERN_WARNING "batman-adv:Warning - can't forward icmp packet from %pM to %pM: ttl exceeded\n", - icmp_packet->orig, icmp_packet->dst); + printk(KERN_WARNING "batman-adv:" + "Warning - can't forward icmp packet from %pM to %pM: " + "ttl exceeded\n", + icmp_packet->orig, icmp_packet->dst); return NET_RX_DROP; }
@@ -874,7 +899,9 @@ int recv_unicast_packet(struct sk_buff *skb)
/* TTL exceeded */ if (unicast_packet->ttl < 2) { - printk(KERN_WARNING "batman-adv:Warning - can't forward unicast packet from %pM to %pM: ttl exceeded\n", + printk(KERN_WARNING "batman-adv:Warning - " + "can't forward unicast packet from %pM to %pM: " + "ttl exceeded\n", ethhdr->h_source, unicast_packet->dest); return NET_RX_DROP; } diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index f58a9ed..d8536e2 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -65,7 +65,8 @@ int send_skb_packet(struct sk_buff *skb,
if (!(batman_if->net_dev->flags & IFF_UP)) { printk(KERN_WARNING - "batman-adv:Interface %s is not up - can't send packet via that interface!\n", + "batman-adv:Interface %s " + "is not up - can't send packet via that interface!\n", batman_if->dev); goto send_skb_err; } @@ -148,9 +149,9 @@ static void send_packet_to_if(struct forw_packet *forw_packet, "Sending own" : "Forwarding")); bat_dbg(DBG_BATMAN, - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n", - fwd_str, - (packet_num > 0 ? "aggregated " : ""), + "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," + " IDF %s) on interface %s [%s]\n", + fwd_str, (packet_num > 0 ? "aggregated " : ""), batman_packet->orig, ntohs(batman_packet->seqno), batman_packet->tq, batman_packet->ttl, (batman_packet->flags & DIRECTLINK ? @@ -178,7 +179,8 @@ static void send_packet(struct forw_packet *forw_packet) unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) { - printk(KERN_ERR "batman-adv: Error - can't forward packet: incoming iface not specified\n"); + printk(KERN_ERR "batman-adv: Error - can't forward packet: " + "incoming iface not specified\n"); return; }
@@ -192,7 +194,8 @@ static void send_packet(struct forw_packet *forw_packet)
/* FIXME: what about aggregated packets ? */ bat_dbg(DBG_BATMAN, - "%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n", + "%s packet (originator %pM, seqno %d, TTL %d) " + "on interface %s [%s]\n", (forw_packet->own ? "Sending own" : "Forwarding"), batman_packet->orig, ntohs(batman_packet->seqno), batman_packet->ttl, forw_packet->if_incoming->dev, @@ -322,7 +325,8 @@ void schedule_forward_packet(struct orig_node *orig_node, batman_packet->tq = orig_node->router->tq_avg;
if (orig_node->router->last_ttl) - batman_packet->ttl = orig_node->router->last_ttl - 1; + batman_packet->ttl = orig_node->router->last_ttl + - 1; }
tq_avg = orig_node->router->tq_avg; @@ -331,7 +335,8 @@ void schedule_forward_packet(struct orig_node *orig_node, /* apply hop penalty */ batman_packet->tq = hop_penalty(batman_packet->tq);
- bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", + bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, " + "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", in_tq, tq_avg, batman_packet->tq, in_ttl - 1, batman_packet->ttl);
diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index c3b5288..51c40b7 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -237,6 +237,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
if ((orig_node) && (orig_node->router)) { + struct neigh_node *router = orig_node->router; + if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0) goto unlock;
@@ -251,14 +253,14 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
/* net_dev won't be available when not active */ - if (orig_node->router->if_incoming->if_status != IF_ACTIVE) + if (router->if_incoming->if_status != IF_ACTIVE) goto unlock;
/* don't lock while sending the packets ... we therefore * copy the required data before sending */
- batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + batman_if = router->if_incoming; + memcpy(dstaddr, router->addr, ETH_ALEN); spin_unlock_irqrestore(&orig_hash_lock, flags);
send_skb_packet(skb, batman_if, dstaddr); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index c7a6635..e01ff21 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -77,7 +77,10 @@ void hna_local_add(uint8_t *addr) MAC-flooding. */ if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) || (num_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, "Can't add new local hna entry (%pM): number of local hna entries exceeds packet size\n", addr); + bat_dbg(DBG_ROUTES, + "Can't add new local hna entry (%pM): " + "number of local hna entries exceeds packet size\n", + addr); return; }
@@ -108,7 +111,8 @@ void hna_local_add(uint8_t *addr) hna_local_hash->size * 2);
if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize local hna hash table\n"); + printk(KERN_ERR "batman-adv:" + "Couldn't resize local hna hash table\n"); else hna_local_hash = swaphash; } @@ -169,14 +173,16 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name);
return 0; }
hdr_len = sprintf(buff, - "Locally retrieved addresses (from %s) announced via HNA:\n", + "Locally retrieved addresses (from %s) " + "announced via HNA:\n", net_dev->name);
if (off < hdr_len) @@ -196,7 +202,7 @@ int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff, hna_local_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, 22, - " * %02x:%02x:%02x:%02x:%02x:%02x\n", + " * " MAC_FMT "\n", hna_local_entry->addr[0], hna_local_entry->addr[1], hna_local_entry->addr[2], @@ -317,7 +323,8 @@ void hna_global_add_orig(struct orig_node *orig_node, memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
bat_dbg(DBG_ROUTES, - "Creating new global hna entry: %pM (via %pM)\n", + "Creating new global hna entry: " + "%pM (via %pM)\n", hna_global_entry->addr, orig_node->orig);
spin_lock_irqsave(&hna_global_hash_lock, flags); @@ -362,7 +369,8 @@ void hna_global_add_orig(struct orig_node *orig_node, hna_global_hash->size * 2);
if (swaphash == NULL) - printk(KERN_ERR "batman-adv:Couldn't resize global hna hash table\n"); + printk(KERN_ERR "batman-adv:" + "Couldn't resize global hna hash table\n"); else hna_global_hash = swaphash; } @@ -383,14 +391,16 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, if (!bat_priv->primary_if) { if (off == 0) return sprintf(buff, - "BATMAN mesh %s disabled - please specify interfaces to enable it\n", - net_dev->name); + "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name);
return 0; }
hdr_len = sprintf(buff, - "Globally announced HNAs received via the mesh %s (translation table):\n", + "Globally announced HNAs received via the mesh %s " + "(translation table):\n", net_dev->name);
if (off < hdr_len) @@ -410,7 +420,7 @@ int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff, hna_global_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, 44, - " * %02x:%02x:%02x:%02x:%02x:%02x via %02x:%02x:%02x:%02x:%02x:%02x\n", + " * " MAC_FMT " via " MAC_FMT "\n", hna_global_entry->addr[0], hna_global_entry->addr[1], hna_global_entry->addr[2], diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 0b1fe9e..86007c7 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -29,7 +29,10 @@ #include "packet.h" #include "bitarray.h"
-#define BAT_HEADER_LEN (sizeof(struct ethhdr) + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? sizeof(struct unicast_packet) : sizeof(struct bcast_packet)))) +#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ + ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ + sizeof(struct unicast_packet) : \ + sizeof(struct bcast_packet))))
struct batman_if { @@ -47,28 +50,40 @@ struct batman_if {
};
-struct orig_node { /* structure for orig_list maintaining nodes of mesh */ +/** + * orig_node - structure for orig_list maintaining nodes of mesh + * @last_valid: when last packet from this node was received + * @bcast_seqno_reset: time when the broadcast seqno window was reset + * @batman_seqno_reset: time when the batman seqno window was reset + * @flags: for now only VIS_SERVER flag + * @last_real_seqno: last and best known squence number + * @last_ttl: ttl of last received packet + * @last_bcast_seqno: last broadcast sequence number received by this host + */ +struct orig_node { uint8_t orig[ETH_ALEN]; struct neigh_node *router; TYPE_OF_WORD *bcast_own; uint8_t *bcast_own_sum; uint8_t tq_own; int tq_asym_penalty; - unsigned long last_valid; /* when last packet from this node was received */ - unsigned long bcast_seqno_reset; /* time when the broadcast - seqno window was reset. */ - unsigned long batman_seqno_reset;/* time when the batman seqno - window was reset. */ - uint8_t flags; /* for now only VIS_SERVER flag. */ + unsigned long last_valid; + unsigned long bcast_seqno_reset; + unsigned long batman_seqno_reset; + uint8_t flags; unsigned char *hna_buff; int16_t hna_buff_len; - uint16_t last_real_seqno; /* last and best known squence number */ - uint8_t last_ttl; /* ttl of last received packet */ + uint16_t last_real_seqno; + uint8_t last_ttl; TYPE_OF_WORD bcast_bits[NUM_WORDS]; - uint16_t last_bcast_seqno; /* last broadcast sequence number received by this host */ + uint16_t last_bcast_seqno; struct list_head neigh_list; };
+/** + * neigh_node + * @last_valid: when last packet via this neighbor was received + */ struct neigh_node { struct list_head list; uint8_t addr[ETH_ALEN]; @@ -77,7 +92,7 @@ struct neigh_node { uint8_t tq_index; uint8_t tq_avg; uint8_t last_ttl; - unsigned long last_valid; /* when last packet via this neighbor was received */ + unsigned long last_valid; TYPE_OF_WORD real_bits[NUM_WORDS]; struct orig_node *orig_node; struct batman_if *if_incoming; @@ -117,7 +132,11 @@ struct hna_global_entry { struct orig_node *orig_node; };
-struct forw_packet { /* structure for forw_list maintaining packets to be send/forwarded */ +/** + * forw_packet - structure for forw_list maintaining packets to be + * send/forwarded + */ +struct forw_packet { struct hlist_node list; unsigned long send_time; uint8_t own;
Signed-off-by: Marek Lindner lindner_marek@yahoo.de Signed-off-by: Andrew Lunn andrew@lunn.ch --- drivers/staging/batman-adv/README | 275 +++++++++++++++++++++++-------------- 1 files changed, 173 insertions(+), 102 deletions(-)
diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index e2a7271..14244a2 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,169 +1,240 @@ -[state: 22-03-2010] +[state: 03-05-2010]
BATMAN-ADV ----------
-Batman-advanced is a new approach to wireless networking which does no longer -operate on the IP basis. Unlike B.A.T.M.A.N, which exchanges information -using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI -Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It -emulates a virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating protocols won't be -affected by any changes within the network. You can run almost any protocol -above B.A.T.M.A.N. Advanced, prominent examples are: IPv4, IPv6, DHCP, IPX. +Batman advanced is a new approach to wireless networking which +does no longer operate on the IP basis. Unlike the batman daemon, +which exchanges information using UDP packets and sets routing +tables, batman-advanced operates on ISO/OSI Layer 2 only and uses +and routes (or better: bridges) Ethernet Frames. It emulates a +virtual network switch of all nodes participating. Therefore all +nodes appear to be link local, thus all higher operating proto- +cols won't be affected by any changes within the network. You can +run almost any protocol above batman advanced, prominent examples +are: IPv4, IPv6, DHCP, IPX.
-This is batman-advanced implemented as Linux kernel driver. It does not depend -on any network (other) driver, and can be used on wifi as well as ethernet, -vpn, etc ... (anything with ethernet-style layer 2). +Batman advanced was implemented as a Linux kernel driver to re- +duce the overhead to a minimum. It does not depend on any (other) +network driver, and can be used on wifi as well as ethernet lan, +vpn, etc ... (anything with ethernet-style layer 2).
-USAGE ------ +CONFIGURATION +-------------
-insmod the batman-adv.ko in your kernel: +Load the batman-adv module into your kernel:
# insmod batman-adv.ko
-the module is now waiting for activation. You must add some interfaces -on which batman can operate. Each interface must be added separately: +The module is now waiting for activation. You must add some in- +terfaces on which batman can operate. After loading the module +batman advanced will scan your systems interfaces to search for +compatible interfaces. Once found, it will create subfolders in +the /sys directories of each supported interface, e.g.
-# echo wlan0 > /proc/net/batman-adv/interfaces +# ls /sys/class/net/eth0/batman_adv/ +# iface_status mesh_iface
-( # echo wlan1 > /proc/net/batman-adv/interfaces ) -( # echo eth0 > /proc/net/batman-adv/interfaces ) -( ... ) +If an interface does not have the "batman_adv" subfolder it prob- +ably is not supported. Not supported interfaces are: loopback, +non-ethernet and batman's own interfaces.
-Now batman starts broadcasting on this interface. -You can now view the table of originators (mesh participants) with: +Note: After the module was loaded it will continuously watch for +new interfaces to verify the compatibility. There is no need to +reload the module if you plug your USB wifi adapter into your ma- +chine after batman advanced was initially loaded.
-# cat /proc/net/batman-adv/originators +To activate a given interface simply write "bat0" into its +"mesh_iface" file inside the batman_adv subfolder:
-The module will create a new interface "bat0", which can be used as a -regular interface: +# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface
-# ifconfig bat0 inet 192.168.0.1 up -# ping 192.168.0.2 -... +Repeat this step for all interfaces you wish to add. Now batman +starts using/broadcasting on this/these interface(s).
---- -If you want topology visualization, your meshnode must be configured -as VIS-server: +By reading the "iface_status" file you can check its status:
-# echo "server" > /proc/net/batman-adv/vis_server +# cat /sys/class/net/eth0/batman_adv/iface_status +# active
-Each node is either configured as "server" or as "client" (default: -"client"). Clients send their topology data to the server next to them, -and server synchronize with other servers. If there is no server -configured (default) within the mesh, no topology information will be -transmitted. With these "synchronizing servers", there can be 1 or -more vis servers sharing the same (or at least very similar) data. +To deactivate an interface you have to write "none" into its +"mesh_iface" file:
-When configured as server, you can get a topology snapshot of your mesh: +# echo none > /sys/class/net/eth0/batman_adv/mesh_iface
-# cat /proc/net/batman-adv/vis_data
-This raw output is intended to be easily parsable and convertable with -other tools. Have a look at the batctl README if you want a vis output -in dot or json format for instance and how those outputs could then be -visualised in an image. +All mesh wide settings can be found in batman's own interface +folder: + +# ls /sys/class/net/bat0/mesh/ +# aggregate_ogm originators transtable_global vis_mode +# orig_interval transtable_local 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 +originators (mesh participants) with: + +# cat /sys/class/net/bat0/mesh/originators + +Other files allow to change batman's behaviour to better fit your +requirements. For instance, you can check the current originator +interval (value in milliseconds which determines how often batman +sends its broadcast packets): + +# cat /sys/class/net/bat0/mesh/orig_interval +# status: 1000 + +and also change its value: + +# echo 3000 > /sys/class/net/bat0/mesh/orig_interval
-The raw format consists of comma seperated values per entry where each -entry is giving information about a certain source interface. Each entry -can/has to have the following values: --> "mac" -> mac address of an originator's source interface - (each line begins with it) --> "TQ mac value" -> src mac's link quality towards mac address of a neighbor - originator's interface which is being used for routing --> "HNA mac" -> HNA announced by source mac --> "PRIMARY" -> this is a primary interface --> "SEC mac" -> secondary mac address of source (requires preceeding --> PRIMARY) - -The TQ value has a range from 4 to 255 with 255 being the best. -The HNA entries are showing which hosts are connected to the mesh via bat0 -or being bridged into the mesh network. -The PRIMARY/SEC values are only applied on primary interfaces - ---- In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more responsive to -topology changes, but will also increase the overhead. Please make sure -that all nodes in your mesh use the same interval. The default value -is 1000 ms (1 second). +interval to a lower value. This will make the mesh more respon- +sive to topology changes, but will also increase the overhead. + + +USAGE +----- + +To make use of your newly created mesh, batman advanced provides +a new interface "bat0" which you should use from this point on. +All interfaces added to batman advanced are not relevant any +longer because batman handles them for you. Basically, one "hands +over" the data by using the batman interface and batman will make +sure it reaches its destination.
-# echo 1000 > /proc/net/batman-adv/orig_interval +The "bat0" interface can be used like any other regular inter- +face. It needs an IP address which can be either statically con- +figured or dynamically (by using DHCP or similar services):
-To deactivate batman, do: +# NodeA: ifconfig bat0 192.168.0.1 +# NodeB: ifconfig bat0 192.168.0.2 +# NodeB: ping 192.168.0.1 + +Note: In order to avoid problems remove all IP addresses previ- +ously assigned to interfaces now used by batman advanced, e.g. + +# ifconfig eth0 0.0.0.0 + + +VISUALIZATION +------------- + +If you want topology visualization, at least one mesh node must +be configured as VIS-server: + +# echo "server" > /sys/class/net/bat0/mesh/vis_mode + +Each node is either configured as "server" or as "client" (de- +fault: "client"). Clients send their topology data to the server +next to them, and server synchronize with other servers. If there +is no server configured (default) within the mesh, no topology +information will be transmitted. With these "synchronizing +servers", there can be 1 or more vis servers sharing the same (or +at least very similar) data. + +When configured as server, you can get a topology snapshot of +your mesh: + +# cat /sys/class/net/bat0/mesh/vis_data + +This raw output is intended to be easily parsable and convertable +with other tools. Have a look at the batctl README if you want a +vis output in dot or json format for instance and how those out- +puts could then be visualised in an image. + +The raw format consists of comma separated values per entry where +each entry is giving information about a certain source inter- +face. Each entry can/has to have the following values: +-> "mac" - mac address of an originator's source interface + (each line begins with it) +-> "TQ mac value" - src mac's link quality towards mac address + of a neighbor originator's interface which + is being used for routing +-> "HNA mac" - HNA announced by source mac +-> "PRIMARY" - this is a primary interface +-> "SEC mac" - secondary mac address of source + (requires preceding PRIMARY) + +The TQ value has a range from 4 to 255 with 255 being the best. +The HNA entries are showing which hosts are connected to the mesh +via bat0 or being bridged into the mesh network. The PRIMARY/SEC +values are only applied on primary interfaces
-# echo "" > /proc/net/batman-adv/interfaces
LOGGING/DEBUGGING -----------------
-All error messages, warnings and information messages are sent to the -kernel log. Depending on your operating system distribution this can be -read in one of a number of ways. Try using the commands: dmesg, -logread, or looking in the files /var/log/kern.log or -/var/log/syslog. All batman-adv messages are prefixed with +All error messages, warnings and information messages are sent to +the kernel log. Depending on your operating system distribution +this can be read in one of a number of ways. Try using the com- +mands: dmesg, logread, or looking in the files /var/log/kern.log +or /var/log/syslog. All batman-adv messages are prefixed with "batman-adv:" So to see just these messages try
-dmesg | grep batman-adv +# dmesg | grep batman-adv
-When investigating problems with your mesh network it is sometimes -necessary to see more detail debug messages. This must be enabled when -compiling the batman-adv module. Use "make menuconfig" and enable the +When investigating problems with your mesh network it is some- +times necessary to see more detail debug messages. This must be +enabled when compiling the batman-adv module. When building bat- +man-adv as part of kernel, use "make menuconfig" and enable the option "B.A.T.M.A.N. debugging".
-The additional debug output is by default disabled. It can be enabled -either at kernel module load time or during run time. To enable debug -output at module load time, add the module parameter debug=<value>. -<value> can take one of four values. +The additional debug output is by default disabled. It can be en- +abled either at kernel modules load time or during run time. To +enable debug output at module load time, add the module parameter +debug=<value>. <value> can take one of four values.
-0 - All debug output disabled +0 - All debug output disabled 1 - Enable messages related to routing / flooding / broadcasting 2 - Enable route or hna added / changed / deleted 3 - Enable all messages
e.g.
-modprobe batman-adv debug=2 +# modprobe batman-adv debug=2
-will load the module and enable debug messages for when routes or HNAs -change. +will load the module and enable debug messages for when routes or +HNAs change.
-The debug output can also be changed at runtime using the file +The debug output can also be changed at runtime using the file /sys/module/batman-adv/parameters/debug. e.g.
-echo 2 > /sys/module/batman-adv/parameters/debug +# echo 2 > /sys/module/batman-adv/parameters/debug
enables debug messages for when routes or HNAs
-The debug output is sent to the kernel logs. So try dmesg, logread etc -to see the debug messages. +The debug output is sent to the kernel logs. So try dmesg, lo- +gread, etc to see the debug messages. +
BATCTL ------
-B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts -participating in the virtual switch are completely transparent for all -protocols above layer 2. Therefore the common diagnosis tools do not -work as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and +As batman advanced operates on layer 2 all hosts participating in +the virtual switch are completely transparent for all protocols +above layer 2. Therefore the common diagnosis tools do not work +as expected. To overcome these problems batctl was created. At +the moment the batctl contains ping, traceroute, tcpdump and interfaces to the kernel module settings.
For more information, please see the manpage (man batctl).
-batctl is available on http://www.open-mesh.net/ +batctl is available on http://www.open-mesh.org/ +
CONTACT -------
Please send us comments, experiences, questions, anything :)
-IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@open-mesh.net -(subscription at https://list.open-mesh.net/mm/listinfo/b.a.t.m.a.n ) +IRC: #batman on irc.freenode.org +Mailing-list: b.a.t.m.a.n@open-mesh.net (optional subscription + at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
You can also contact the Authors:
-Marek Lindner lindner_marek@yahoo.de -Simon Wunderlich siwu@hrz.tu-chemnitz.de +Marek Lindner lindner_marek@yahoo.de +Simon Wunderlich siwu@hrz.tu-chemnitz.de +
b.a.t.m.a.n@lists.open-mesh.org