Re: [B.A.T.M.A.N.] [PATCHv2] batman-adv: Add the backbone gateway list to debugfs

2012-06-15 Thread Simon Wunderlich
Hey Sven,

On Thu, Jun 14, 2012 at 10:43:55PM +0200, Sven Eckelmann wrote:
 You forgot the README and most likely the batctl part.

I planned to send the batctl patch later, but README is definitly
missing. Thanks!

Simon


signature.asc
Description: Digital signature


[B.A.T.M.A.N.] [PATCH] batctl: add support for the bla backbone table in debugfs

2012-06-15 Thread Simon Wunderlich
Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
---
 debug.c |   10 ++
 debug.h |2 ++
 main.c  |6 ++
 3 files changed, 18 insertions(+)

diff --git a/debug.c b/debug.c
index 928f81d..5dca633 100644
--- a/debug.c
+++ b/debug.c
@@ -70,6 +70,16 @@ void bla_claim_table_usage(void)
printf( \t -w [interval] watch mode - refresh the bridge loop 
avoidance claim table continuously\n);
 }
 
+void bla_backbone_table_usage(void)
+{
+   printf(Usage: batctl [options] backbone table\n);
+   printf(options:\n);
+   printf( \t -h print this help\n);
+   printf( \t -n don't replace mac addresses with bat-host names\n);
+   printf( \t -w [interval] watch mode - refresh the bridge loop 
avoidance backbone table continuously\n);
+}
+
+
 void gateways_usage(void)
 {
printf(Usage: batctl [options] gateways \n);
diff --git a/debug.h b/debug.h
index 50d0e24..2c6d24c 100644
--- a/debug.h
+++ b/debug.h
@@ -25,6 +25,7 @@
 #define DEBUG_TRANSTABLE_LOCAL transtable_local
 #define DEBUG_TRANSTABLE_GLOBAL transtable_global
 #define DEBUG_BLA_CLAIM_TABLE bla_claim_table
+#define DEBUG_BLA_BACKBONE_TABLE bla_backbone_table
 #define DEBUG_GATEWAYS gateways
 #define DEBUG_VIS_DATA vis_data
 #define DEBUG_LOG log
@@ -33,6 +34,7 @@ void originators_usage(void);
 void trans_local_usage(void);
 void trans_global_usage(void);
 void bla_claim_table_usage(void);
+void bla_backbone_table_usage(void);
 void gateways_usage(void);
 int handle_debug_table(char *mesh_iface, int argc, char **argv,
   char *file_path, void table_usage(void));
diff --git a/main.c b/main.c
index 72b1ea4..929b762 100644
--- a/main.c
+++ b/main.c
@@ -56,6 +56,7 @@ void print_usage(void) {
printf( \ttranslocal|tl\tdisplay the 
local translation table\n);
printf( \ttransglobal|tg   \tdisplay the 
global translation table\n);
printf( \tclaimtable|cl\tdisplay the 
bridge loop avoidance claim table\n);
+   printf( \tbackbonetable|bbl\tdisplay the 
bridge loop avoidance backbone table\n);
printf( \tvis_mode|vm[mode]\tdisplay or 
modify the status of the VIS server\n);
printf( \tvis_data|vd[dot|JSON]\tdisplay the 
VIS data in dot or JSON format\n);
printf( \taggregation|ag [0|1] \tdisplay or 
modify the packet aggregation setting\n);
@@ -158,6 +159,11 @@ int main(int argc, char **argv)
 
ret = handle_debug_table(mesh_iface, argc - 1, argv + 1,
 DEBUG_BLA_CLAIM_TABLE, 
bla_claim_table_usage);
+   } else if ((strcmp(argv[1], backbonetable) == 0) || (strcmp(argv[1], 
bbl) == 0)) {
+
+   ret = handle_debug_table(mesh_iface, argc - 1, argv + 1,
+DEBUG_BLA_BACKBONE_TABLE,
+bla_backbone_table_usage);
 
} else if ((strcmp(argv[1], loglevel) == 0) || (strcmp(argv[1], ll) 
== 0)) {
 
-- 
1.7.10



[B.A.T.M.A.N.] [PATCHv3] batman-adv: Add the backbone gateway list to debugfs

2012-06-15 Thread Simon Wunderlich
This is especially useful if there are no claims yet, but we still want
to know which gateways are using bridge loop avoidance in the network.

Signed-off-by: Simon Wunderlich s...@hrz.tu-chemnitz.de
---
[EDITv2: forgot to rename the function ...]
[EDITv3: add README entry]
---
 README  |7 ++---
 bridge_loop_avoidance.c |   68 +++
 bridge_loop_avoidance.h |8 ++
 debugfs.c   |   12 +
 4 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/README b/README
index 8f3ae4a..a173d2a 100644
--- a/README
+++ b/README
@@ -75,9 +75,10 @@ folder:
 
 There is a special folder for debugging information:
 
-#  ls /sys/kernel/debug/batman_adv/bat0/
-# bla_claim_tablelogsocket transtable_local
-# gateways   originatorstranstable_global  vis_data
+# ls /sys/kernel/debug/batman_adv/bat0/
+# bla_backbone_table  log transtable_global
+# bla_claim_table originators transtable_local
+# gatewayssocket  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
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 38aab1e..75587af 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -1592,3 +1592,71 @@ out:
batadv_hardif_free_ref(primary_if);
return ret;
 }
+
+int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq, void 
*offset)
+{
+   struct net_device *net_dev = (struct net_device *)seq-private;
+   struct batadv_priv *bat_priv = netdev_priv(net_dev);
+   struct batadv_hashtable *hash = bat_priv-backbone_hash;
+   struct batadv_backbone_gw *backbone_gw;
+   struct batadv_hard_iface *primary_if;
+   struct hlist_node *node;
+   struct hlist_head *head;
+   int last_seen_secs;
+   int last_seen_msecs;
+   uint32_t i;
+   bool is_own;
+   int ret = 0;
+   uint8_t *primary_addr;
+
+   primary_if = batadv_primary_if_get_selected(bat_priv);
+   if (!primary_if) {
+   ret = seq_printf(seq,
+BATMAN mesh %s disabled - please specify 
interfaces to enable it\n,
+net_dev-name);
+   goto out;
+   }
+
+   if (primary_if-if_status != BATADV_IF_ACTIVE) {
+   ret = seq_printf(seq,
+BATMAN mesh %s disabled - primary interface 
not active\n,
+net_dev-name);
+   goto out;
+   }
+
+   primary_addr = primary_if-net_dev-dev_addr;
+   seq_printf(seq,
+  Backbones announced for the mesh %s (orig %pM, group id 
%04x)\n,
+  net_dev-name, primary_addr,
+  ntohs(bat_priv-claim_dest.group));
+   seq_printf(seq,%-17s%-5s %-9s (%-4s)\n,
+  Originator, VID, last seen, CRC);
+   for (i = 0; i  hash-size; i++) {
+   head = hash-table[i];
+
+   rcu_read_lock();
+   hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
+   last_seen_msecs = jiffies_to_msecs(jiffies -
+   backbone_gw-lasttime);
+   last_seen_secs = last_seen_msecs / 1000;
+   last_seen_msecs = last_seen_msecs % 1000;
+
+
+   is_own = batadv_compare_eth(backbone_gw-orig,
+   primary_addr);
+   if (is_own)
+   continue;
+
+   seq_printf(seq,
+   * %pM on % 5d % 4i.%03is (%04x)\n,
+  backbone_gw-orig, backbone_gw-vid,
+  last_seen_secs, last_seen_msecs,
+  backbone_gw-crc);
+   }
+   rcu_read_unlock();
+   }
+out:
+   if (primary_if)
+   batadv_hardif_free_ref(primary_if);
+   return ret;
+}
diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h
index 08d13cb..58015ce 100644
--- a/bridge_loop_avoidance.h
+++ b/bridge_loop_avoidance.h
@@ -26,6 +26,8 @@ int batadv_bla_tx(struct batadv_priv *bat_priv, struct 
sk_buff *skb, short vid);
 int batadv_bla_is_backbone_gw(struct sk_buff *skb,
  struct batadv_orig_node *orig_node, int hdr_size);
 int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
+int batadv_bla_backbone_table_seq_print_text(struct seq_file *seq,
+void *offset);
 int batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, uint8_t 
*orig);
 int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
   struct 

Re: [B.A.T.M.A.N.] link alternation when radios are not on batman-adv router?

2012-06-15 Thread Simon Wunderlich
On Thu, Jun 14, 2012 at 04:51:01PM -0300, gto...@inti.gob.ar wrote:
 Hi,
 
 we are interested too in interface alternating, so we made some
 tests to understand how it works. As you can see on the attached
 sketch.png, we connected two pair of routers using their ethernet
 interfaces, E6 with E7, and E8 with E9. All of them have eth0, and
 an ad hoc interface, wlan0-1, managed by batman. E6 and E8 are in
 channel 11, whereas E7 and E9 are in channel 1. Besides we used two
 other routers, E12 and E13, both in channel 11, with their tx power
 set to just 0 dbm, to avoid a direct sight between them.
 
 Then we sent traffic from E12 to E13. We expected that packets
 travelled from E12 to E6, and that E6 forwarded them to his eth0 to
 use the interface alternating feature, making traffic flow to E7,
 then E9, E8 and finally E13. But instead, we observed that the
 actual path was E12--E6--E8--E13. The resulting routes for each
 router are attached in a text file, and also the graph from the
 batctl vd dot command.
 
 After this result, we read again the thread mentioned by Guido,
 specially in this part:
 
 https://lists.open-mesh.org/pipermail/b.a.t.m.a.n/2012-March/006344.html
 
And if we understand correctly, the alternation feature works
 after the batman path has been selected. So in our case, E12 looks
 at his table to know where to send a packet to E13, and finds E6.
 Then E6 receives the packet and looks in his own table, finding that
 the best path to reach E13 is E8. At this point, the alternating
 should work, but there's only one interface directly connected to
 E8, so the packet goes there, and so on. We think that if E6 and E7
 were not two different routers running batman-adv but they were two
 radios of the same batman-adv router, and the same for E8 and E9,
 the alternating would work, because the unique router would choose
 the best path, and then would find two possible interfaces to the
 same next-hop, changing the interface.

This is entirely correct - batman-adv has only one link to choose from
(E6 - E8) to reach its best nexthop E8, so there is no way to
alternate the interfaces.

 We'd like to know if this interpretation is correct, and in that
 case, if it were possible to use interface alternating in a case
 like this, with two routers connected to work together. Thanks!

Mhm, with the current implementation - no, unfortunately not. We would
need some kind of multipath routing to select between routes, this is
much more complex.

An alternative might be to use the routers E7/E9 as secondary routers
without batman, but only forwarding traffic between Ethernet and
WiFi. Then the primary routers (E6 - E8) would think they have
an alternative route via Ethernet (because they don't see the
intermediate hops E7/E9). This comes with some caveats however, e.g.
4-addr mode in Ad-Hoc, you need some very simple ethernet forwarder,
and most probably other things I forgot.

Cheers,
Simon



signature.asc
Description: Digital signature


Re: [B.A.T.M.A.N.] [PATCH] batman-adv: fix skb-data assignment

2012-06-15 Thread Sven Eckelmann
On Thursday 14 June 2012 22:21:28 Antonio Quartulli wrote:
 skb_linearize(skb) possibly rearranges the skb internal data and then
 changes the skb-data pointer value. For this reason any other pointer in
 the code that was assigned skb-data before invoking skb_linearise(skb)
 must be re-assigned.
 
 In the current tt_query message handling code this is not done and
 therefore, in case of skb linearization, the pointer used to handle the
 packet header ends up in pointing to poisoned memory. The packet is then
 dropped but the translation-table mechanism is corrupted.
 
 Signed-off-by: Antonio Quartulli or...@autistici.org
 ---
 
 *** this patch is an important fix and it is for maint ***

Don't forget to add 

Cc: stable sta...@vger.kernel.org

to the patch and a small explanation since when the bug is there (I guess 
v3.1) and that it may lead to crashes and not only poisened memory (that is 
the best case.. but maybe the page was removed and we end up in hell when 
accessing the memory region).

Kind regards,
Sven

signature.asc
Description: This is a digitally signed message part.


Re: [B.A.T.M.A.N.] [PATCH] batman-adv: fix skb-data assignment

2012-06-15 Thread Antonio Quartulli
On Fri, Jun 15, 2012 at 01:45:11PM +0200, Sven Eckelmann wrote:
 On Thursday 14 June 2012 22:21:28 Antonio Quartulli wrote:
  skb_linearize(skb) possibly rearranges the skb internal data and then
  changes the skb-data pointer value. For this reason any other pointer in
  the code that was assigned skb-data before invoking skb_linearise(skb)
  must be re-assigned.
  
  In the current tt_query message handling code this is not done and
  therefore, in case of skb linearization, the pointer used to handle the
  packet header ends up in pointing to poisoned memory. The packet is then
  dropped but the translation-table mechanism is corrupted.
  
  Signed-off-by: Antonio Quartulli or...@autistici.org
  ---
  
  *** this patch is an important fix and it is for maint ***
 
 Don't forget to add 
 
 Cc: stable sta...@vger.kernel.org
 
 to the patch and a small explanation since when the bug is there (I guess 
 v3.1) and that it may lead to crashes and not only poisened memory (that is 
 the best case.. but maybe the page was removed and we end up in hell when 
 accessing the memory region).

Hi Sven,

Thank you for your suggestions. Sure, I will.

Regards,


-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgpydwm5Qp0pD.pgp
Description: PGP signature


[B.A.T.M.A.N.] batman-adv 2012.2.0 released

2012-06-15 Thread Marek Lindner

Today, the B.A.T.M.A.N. team releases batman-adv 2012.2.0, packed with new 
features and improvements in various subsystems as well as the usual set of 
fixes and cleanups. As the kernel module always depends on the Linux kernel it 
was compiled against, it does not make sense to provide binaries on our 
website. As usual, you will find the signed tarballs in our download section:

http://downloads.open-mesh.org/batman/releases/batman-adv-2012.2.0/

as well as prepackaged binaries in your distribution.


Important changes
-

This release comes with a completely rewritten bridge loop avoidance (also 
known as bridge loop avoidance II). The concept of the first bridge loop 
avoidance was simple and worked well in small size LANs while larger networks 
suffered from the overhead. The new concept is very different and requires 
changes in your batman-adv configuration. If you were using the bridge loop 
avoidance you should consult our documentation before upgrading your 
network(s).

The default per hop penalty was increased to encourage batman-adv to take 
shorter routes. If you notice altered routing behavior and are unhappy with 
the result you should revisit the hop penalty configuration option.


Thanks
--

Thanks to all people sending in patches:

 * Antonio Quartulli or...@autistici.org
 * Danny Kukawka danny.kuka...@bisect.de
 * David S. Miller da...@davemloft.net
 * Eric Dumazet eric.duma...@gmail.com
 * Linus Luessing linus.luess...@web.de
 * Marek Lindner lindner_ma...@yahoo.de
 * Simon Wunderlich s...@hrz.tu-chemnitz.de
 * Sven Eckelmann s...@narfation.org
 * Xabier Rodriguez x...@kalrong.net

and to all those that supported us with good advice, code review and/or 
rigorous testing:

 * Al Viro v...@zeniv.linux.org.uk
 * David Laight david.lai...@aculab.com
 * Jo-Philipp Wich j...@openwrt.org
 * Martin Hundebøll mar...@hundeboll.net


batman-adv
--

The new bridge loop avoidance certainly is the most prominent of the new 
features this release has to offer (completely replacing the old bridge loop 
avoidance mechanism). The major design goals were performance and scalability. 
Since the old implementation was relying on a single gateway to be the master 
gateway to the LAN for everybody else it created a performance bottleneck. 
Furthermore, the LAN was used to send traffic to and receive data from the 
master gateway. With the number of bridged gateways grew the amount of 
broadcast traffic in the LAN. The new bridge loop avoidance splits the client 
responsibility amongst all participating gateways. Each gateway claims the 
clients it feels responsible for and ignores the traffic from all other 
clients to avoid the bridge loop. It also is able to handle multiple VLANs on 
top of the batX interface connected to different topologies. All details about 
the loop avoidance mechanism are explained in our documentation section.

The routing code also received lots of attention: The recently added routing 
protocol abstraction was further polished and extended to better accommodate 
the needs of alternative routing protocols. B.A.T.M.A.N. IV protocol has been 
enhanced with an additional flag to apply stricter forwarding rules to OGMs 
which allows the protocol to avert routing loops in certain corner cases. 
Also, the B.A.T.M.A.N. IV sequence numbers are now randomized at startup to 
reduce the probability of a collision and thus, slowing down the protocol in 
the startup phase. Rerouting of unicast payload packets during a roaming phase 
is handled with greater efficiency to avoid as much packet loss while roaming 
as possible. 

All manual HZ-jiffies-calculations have been replaced with the in-kernel 
jiffies_to_msecs() function. To facilitate comprehension of the code base the 
ETH_ALEN macro is used instead of hardcoded numeric constants. The batman-adv 
internal bitarray operations have been converted to the efficient in-kernel 
bitmap operations. It was discovered that the TT-Request packet did not always 
send the tt-crc field in network byte order, thereby invalidating the packet. 
This has been fixed alongside the suboptimal DHCP option list parser used by 
the gateway extension. OGM sequence numbers now are always printed as unsigned 
long to avoid misinterpretation while printing the numbers in the debug log.


batctl
--

The batctl utility supports the new bridge loop avoidance by providing an 
option to conveniently enable/disable the bridge loop avoidance and exports 
the bridge loop avoidance claim table. It will also warn about features that 
haven't been compiled into batman-adv such as debug log and bridge loop 
avoidance. The mini-tcpdump learned to display the newly added 'not best hop 
flag' when parsing OGMs. 


Happy routing, 
The B.A.T.M.A.N. team


Re: [B.A.T.M.A.N.] [PATCH] batman-adv: fix skb-data assignment

2012-06-15 Thread Marek Lindner
On Friday, June 15, 2012 04:21:28 Antonio Quartulli wrote:
 skb_linearize(skb) possibly rearranges the skb internal data and then
 changes the skb-data pointer value. For this reason any other pointer in
 the code that was assigned skb-data before invoking skb_linearise(skb)
 must be re-assigned.
 
 In the current tt_query message handling code this is not done and
 therefore, in case of skb linearization, the pointer used to handle the
 packet header ends up in pointing to poisoned memory. The packet is then
 dropped but the translation-table mechanism is corrupted.
 
 Signed-off-by: Antonio Quartulli or...@autistici.org
 ---
 
 *** this patch is an important fix and it is for maint ***

Next time you send a patch for maint, please be sure the patch is actually 
based on maint. Your patch does not even apply on top of maint ...

Applied in revision c7d05ee.

Thanks,
Marek


[B.A.T.M.A.N.] [PATCH] batctl: check interface support and print corresponding error message

2012-06-15 Thread Marek Lindner
Signed-off-by: Marek Lindner lindner_ma...@yahoo.de
---
 functions.c |7 +++
 functions.h |1 +
 main.h  |2 ++
 sys.c   |   17 +
 sys.h   |1 +
 5 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/functions.c b/functions.c
index 8ce2419..36a4d40 100644
--- a/functions.c
+++ b/functions.c
@@ -107,6 +107,13 @@ char *get_name_by_macstr(char *mac_str, int read_opt)
return get_name_by_macaddr(mac_addr, read_opt);
 }
 
+int file_exists(const char *fpath)
+{
+   struct stat st;
+
+   return stat(fpath, st) == 0;
+}
+
 static int check_sys_dir(char *dir)
 {
struct stat st;
diff --git a/functions.h b/functions.h
index fe03dc0..92d6ae5 100644
--- a/functions.h
+++ b/functions.h
@@ -33,6 +33,7 @@ double end_timer(void);
 char *ether_ntoa_long(const struct ether_addr *addr);
 char *get_name_by_macaddr(struct ether_addr *mac_addr, int read_opt);
 char *get_name_by_macstr(char *mac_str, int read_opt);
+int file_exists(const char *fpath);
 int read_file(char *dir, char *path, int read_opt,
  float orig_timeout, float watch_interval);
 int write_file(char *dir, char *fname, char *arg1, char *arg2);
diff --git a/main.h b/main.h
index 872a2fe..4819cf4 100644
--- a/main.h
+++ b/main.h
@@ -28,3 +28,5 @@
 #define EXIT_NOSUCCESS 2
 
 #define __packed __attribute((packed))   /* linux kernel compat */
+
+extern char module_ver_path[];
diff --git a/sys.c b/sys.c
index 0b4cac3..5702c6c 100644
--- a/sys.c
+++ b/sys.c
@@ -154,6 +154,23 @@ int interface(char *mesh_iface, int argc, char **argv)
for (i = 2; i  argc; i++) {
snprintf(path_buff, PATH_BUFF_LEN, SYS_MESH_IFACE_FMT, argv[i]);
 
+   if (!file_exists(path_buff)) {
+   snprintf(path_buff, PATH_BUFF_LEN, SYS_IFACE_DIR, 
argv[i]);
+
+   if (!file_exists(path_buff)) {
+   printf(Error - interface does not exist: 
%s\n, argv[i]);
+   continue;
+   }
+
+   if (!file_exists(module_ver_path)) {
+   printf(Error - batman-adv module has not been 
loaded\n);
+   goto err;
+   }
+
+   printf(Error - interface type not supported by 
batman-adv: %s\n, argv[i]);
+   continue;
+   }
+
if (argv[1][0] == 'a')
res = write_file(, path_buff, mesh_iface, NULL);
else
diff --git a/sys.h b/sys.h
index 46a1159..f48902e 100644
--- a/sys.h
+++ b/sys.h
@@ -32,6 +32,7 @@
 #define SYS_VIS_MODE vis_mode
 #define SYS_ORIG_INTERVAL orig_interval
 #define SYS_IFACE_PATH /sys/class/net
+#define SYS_IFACE_DIR SYS_IFACE_PATH/%s/
 #define SYS_MESH_IFACE_FMT SYS_IFACE_PATH/%s/batman_adv/mesh_iface
 #define SYS_IFACE_STATUS_FMT SYS_IFACE_PATH/%s/batman_adv/iface_status
 #define SYS_FRAG fragmentation
-- 
1.7.9.1



Re: [B.A.T.M.A.N.] [PATCHv2] batman-adv: don't reroute tt_request for me

2012-06-15 Thread Antonio Quartulli
On Sat, Jun 16, 2012 at 03:50:00AM +0800, Marek Lindner wrote:
 On Friday, June 15, 2012 05:38:37 Antonio Quartulli wrote:
  If a tt_request is directed to me, it never has to be rerouted
 
 We will need a little more explanation here about what is going on and what 
 is 
 fixed and why we want it to be fixed.

Sure,
I'll send v2 with a improved message

 
 Cheers,
 Marek

-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgpwA0tJwG31t.pgp
Description: PGP signature


Re: [B.A.T.M.A.N.] [PATCHv2] batman-adv: don't reroute tt_request for me

2012-06-15 Thread Antonio Quartulli
On Fri, Jun 15, 2012 at 10:20:35PM +0200, Antonio Quartulli wrote:
 On Sat, Jun 16, 2012 at 03:50:00AM +0800, Marek Lindner wrote:
  On Friday, June 15, 2012 05:38:37 Antonio Quartulli wrote:
   If a tt_request is directed to me, it never has to be rerouted
  
  We will need a little more explanation here about what is going on and what 
  is 
  fixed and why we want it to be fixed.
 
 Sure,
 I'll send v2 with a improved message
 

I clearly meant v3, sorry


  
  Cheers,
  Marek
 
 -- 
 Antonio Quartulli
 
 ..each of us alone is worth nothing..
 Ernesto Che Guevara



-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto Che Guevara


pgplQ4iTGz0M5.pgp
Description: PGP signature