All of lore.kernel.org
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] [RFC 03/11] batman-adv: make bridge loop avoidance switchable
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bat_sysfs.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/bat_sysfs.c b/bat_sysfs.c
index ec2e437..cb7a524 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -379,6 +379,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr,
 
 BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
 BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
+BAT_ATTR_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
 BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
 BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
@@ -396,6 +397,7 @@ BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
 static struct bat_attribute *mesh_attrs[] = {
 	&bat_attr_aggregated_ogms,
 	&bat_attr_bonding,
+	&bat_attr_bridge_loop_avoidance,
 	&bat_attr_fragmentation,
 	&bat_attr_ap_isolation,
 	&bat_attr_vis_mode,
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 02/11] batman-adv: add basic bridge loop avoidance code
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

This second version of the bridge loop avoidance for batman-adv
avoids loops between the mesh and a backbone (usually a LAN).

By connecting multiple batman-adv mesh nodes to the same ethernet
segment a loop can be created when the soft-interface is bridged
into that ethernet segment. A simple visualization of the loop
involving the most common case - a LAN as ethernet segment:

node1  <-- LAN  -->  node2
  |                   |
wifi   <-- mesh -->  wifi

Packets from the LAN (e.g. ARP broadcasts) will circle forever from
node1 or node2 over the mesh back into the LAN.

With this patch, batman recognizes backbone gateways, nodes which are
part of the mesh and backbone/LAN at the same time. Each backbone
gateway "claims" clients from within the mesh to handle them
exclusively. By restricting that only responsible backbone gateways
may handle their claimed clients traffic, loops are effectively
avoided.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

---
[2011-10-27] Changes suggested by Marek Lindner:

 * move claim types into packet.h
 * uint16_t -> short for vid in compare_*
 * remove refcount debugging
 * add comments to spinlocks to silence checkpatch --strict
 * move hardif_free_ref at the end of the function in bla_send_claim()
 * bla_del_claim(): move free ref up to make it more clear why we free
 * the reference
 * bla_purge_claims() does not need spinlock
 * move rcu_read_lock() more into the loops

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

[2011-10-27] add a type for the bla destinations

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

[2011-10-30] Changes suggested by Marek Lindner:

 * add BLA_CRC_INIT to show more visibly the initializiation of the CRC
 * put own_orig into bat_priv instead using a function which needlessly
   copies around
 * update backbone gws when primary if address changes
 * add bla_send_announce() as own function for readability
 * fix some comments
 * give hw_src and hw_dst as parameter in handle_*() and
   check_claim_group() to avoid code duplicates
 * change various debugging code
 * replace add_own_claim and del_own_claim with handle_claim() and
   handle_unclaim() to reduce code size
 * pimp up claim table debugfs output

VLAN fixes:
 * reset skb_mac_header(), it might not be set when its a VLAN frame
 * always become a backbone gw for a VLAN when there is traffic,
   even if there are no claims, to let at least let other backbone gw
   nodes that we are able to receive on that VLAN and avoid broadcast
   loops.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 Makefile.kbuild         |    1 +
 bat_sysfs.c             |    2 +-
 bridge_loop_avoidance.c | 1240 +++++++++++++++++++++++++++++++++++++++++++++++
 bridge_loop_avoidance.h |   30 ++
 compat.c                |    8 +
 compat.h                |    2 +
 hard-interface.c        |    8 +-
 main.c                  |    6 +
 main.h                  |    6 +-
 originator.c            |    1 +
 packet.h                |   16 +
 routing.c               |    6 +
 soft-interface.c        |   11 +
 types.h                 |   28 ++
 14 files changed, 1362 insertions(+), 3 deletions(-)
 create mode 100644 bridge_loop_avoidance.c
 create mode 100644 bridge_loop_avoidance.h

diff --git a/Makefile.kbuild b/Makefile.kbuild
index bd7e93c..d626513 100644
--- a/Makefile.kbuild
+++ b/Makefile.kbuild
@@ -51,3 +51,4 @@ batman-adv-y += translation-table.o
 batman-adv-y += unicast.o
 batman-adv-y += vis.o
 batman-adv-y += compat.o
+batman-adv-y += bridge_loop_avoidance.o
diff --git a/bat_sysfs.c b/bat_sysfs.c
index c25492f..ec2e437 100644
--- a/bat_sysfs.c
+++ b/bat_sysfs.c
@@ -390,7 +390,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
 static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth,
 		store_gw_bwidth);
 #ifdef CONFIG_BATMAN_ADV_DEBUG
-BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 7, NULL);
+BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 15, NULL);
 #endif
 
 static struct bat_attribute *mesh_attrs[] = {
diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
new file mode 100644
index 0000000..641dbcc
--- /dev/null
+++ b/bridge_loop_avoidance.c
@@ -0,0 +1,1240 @@
+/*
+ * Copyright (C) 2011 B.A.T.M.A.N. contributors:
+ *
+ * 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 "hash.h"
+#include "hard-interface.h"
+#include "originator.h"
+#include "bridge_loop_avoidance.h"
+#include "send.h"
+
+#include <linux/etherdevice.h>
+#include <linux/crc16.h>
+#include <linux/if_arp.h>
+#include <net/arp.h>
+#include <linux/if_vlan.h>
+
+static const uint8_t claim_dest[6] = {0xff, 0x43, 0x05, 0x00, 0x00, 0x00};
+static const uint8_t announce_mac[6] = {0x43, 0x05, 0x43, 0x05, 0x00, 0x00};
+
+static void bla_periodic_work(struct work_struct *work);
+static void bla_send_announce(struct bat_priv *bat_priv,
+		struct backbone_gw *backbone_gw);
+
+/**
+ *
+ * @mac: MAC address of the client which is to be checked
+ * @vid: VID of the VLAN
+ *
+ * Returns 1 if the mac is already claimed by ourselves or another node.
+ */
+
+static inline uint32_t choose_claim(const void *data, uint32_t size)
+{
+	const unsigned char *key = data;
+	uint32_t hash = 0;
+	size_t i;
+
+	for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
+		hash += key[i];
+		hash += (hash << 10);
+		hash ^= (hash >> 6);
+	}
+
+	hash += (hash << 3);
+	hash ^= (hash >> 11);
+	hash += (hash << 15);
+
+	return hash % size;
+}
+
+/* compares address and vid of two backbone gws */
+static int compare_backbone_gw(const struct hlist_node *node, const void *data2)
+{
+	const void *data1 = container_of(node, struct backbone_gw,
+					 hash_entry);
+
+	return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
+}
+
+/* compares address and vid of two claims */
+static int compare_claim(const struct hlist_node *node, const void *data2)
+{
+	const void *data1 = container_of(node, struct claim,
+					 hash_entry);
+
+	return (memcmp(data1, data2, ETH_ALEN + sizeof(short)) == 0 ? 1 : 0);
+}
+
+/* free a backbone gw */
+static void backbone_gw_free_ref(struct backbone_gw *backbone_gw)
+{
+	if (atomic_dec_and_test(&backbone_gw->refcount))
+		kfree_rcu(backbone_gw, rcu);
+}
+
+/* finally deinitialize the claim */
+static void claim_free_rcu(struct rcu_head *rcu)
+{
+	struct claim *claim;
+
+	claim = container_of(rcu, struct claim, rcu);
+
+	backbone_gw_free_ref(claim->backbone_gw);
+	kfree(claim);
+}
+
+/* free a claim, call claim_free_rcu if its the last reference */
+static void claim_free_ref(struct claim *claim)
+{
+	if (atomic_dec_and_test(&claim->refcount))
+		call_rcu(&claim->rcu, claim_free_rcu);
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @data: search data (may be local/static data)
+ *
+ * looks for a claim in the hash, and returns it if found
+ * or NULL otherwise.
+ */
+
+static struct claim *claim_hash_find(struct bat_priv *bat_priv,
+		struct claim *data)
+{
+	struct hashtable_t *hash = bat_priv->claim_hash;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct claim *claim;
+	struct claim *claim_tmp = NULL;
+	int index;
+
+	if (!hash)
+		return NULL;
+
+	index = choose_claim(data, hash->size);
+	head = &hash->table[index];
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
+		if (!compare_claim(&claim->hash_entry, data))
+			continue;
+
+		if (!atomic_inc_not_zero(&claim->refcount))
+			continue;
+
+		claim_tmp = claim;
+		break;
+	}
+	rcu_read_unlock();
+
+	return claim_tmp;
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @addr: the address of the originator
+ * @vid: the VLAN ID
+ *
+ * looks for a claim in the hash, and returns it if found
+ * or NULL otherwise.
+ */
+
+static struct backbone_gw *backbone_hash_find(struct bat_priv *bat_priv,
+		uint8_t *addr, short vid)
+{
+	struct hashtable_t *hash = bat_priv->backbone_hash;
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct backbone_gw search_entry, *backbone_gw;
+	struct backbone_gw *backbone_gw_tmp = NULL;
+	int index;
+
+	if (!hash)
+		return NULL;
+
+	memcpy(search_entry.orig, addr, ETH_ALEN);
+	search_entry.vid = vid;
+
+	/* *_claim() works for backbone gws too */
+	index = choose_claim(&search_entry, hash->size);
+	head = &hash->table[index];
+
+	rcu_read_lock();
+	hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
+		if (!compare_backbone_gw(&backbone_gw->hash_entry,
+					&search_entry))
+			continue;
+
+		if (!atomic_inc_not_zero(&backbone_gw->refcount))
+			continue;
+
+		backbone_gw_tmp = backbone_gw;
+		break;
+	}
+	rcu_read_unlock();
+
+	return backbone_gw_tmp;
+}
+
+/* delete all claims for a backbone */
+static void bla_del_backbone_claims(struct backbone_gw *backbone_gw)
+{
+	struct hashtable_t *hash;
+	struct hlist_node *node, *node_tmp;
+	struct hlist_head *head;
+	struct claim *claim;
+	int i;
+	spinlock_t *list_lock;	/* protects write access to the hash lists */
+
+	hash = backbone_gw->bat_priv->claim_hash;
+	if (!hash)
+		return;
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+		list_lock = &hash->list_locks[i];
+
+		spin_lock_bh(list_lock);
+		hlist_for_each_entry_safe(claim, node, node_tmp,
+					 head, hash_entry) {
+
+			if (claim->backbone_gw != backbone_gw)
+				continue;
+
+			claim_free_ref(claim);
+			hlist_del_rcu(node);
+		}
+		spin_unlock_bh(list_lock);
+	}
+
+	/* all claims gone, intialize CRC */
+	backbone_gw->crc = BLA_CRC_INIT;
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the mac address to be announced within the claim
+ * @vid: the VLAN ID
+ * @claimtype: the type of the claim (CLAIM, UNCLAIM, ANNOUNCE, ...)
+ *
+ * sends a claim frame according to the provided info.
+ */
+
+static void bla_send_claim(struct bat_priv *bat_priv, uint8_t *mac,
+		short vid, int claimtype)
+{
+	struct sk_buff *skb;
+	struct ethhdr *ethhdr;
+	struct hard_iface *primary_if;
+	struct net_device *soft_iface;
+	uint8_t *hw_src;
+	struct bla_claim_dst local_claim_dest;
+	uint32_t zeroip = 0;
+
+	primary_if = primary_if_get_selected(bat_priv);
+	if (!primary_if)
+		return;
+
+	memcpy(&local_claim_dest, claim_dest,
+			sizeof(local_claim_dest));
+	local_claim_dest.type = claimtype;
+
+	soft_iface = primary_if->soft_iface;
+
+	skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
+		zeroip,				/* IP DST: 0.0.0.0 */
+		primary_if->soft_iface,
+		zeroip,				/* IP SRC: 0.0.0.0 */
+		NULL,				/* Ethernet DST: Broadcast */
+		primary_if->net_dev->dev_addr,	/* Ethernet SRC/HW SRC:
+						 * originator mac */
+		(uint8_t *)&local_claim_dest	/* HW DST: FF:43:05:XX:00:00
+						 * with XX   = claim type */
+		);
+
+	if (!skb)
+		goto out;
+
+	ethhdr = (struct ethhdr *)skb->data;
+	hw_src = (uint8_t *) ethhdr
+		+ sizeof(struct ethhdr) + sizeof(struct arphdr);
+
+	/* now we pretend that the client would have sent this ... */
+	switch (claimtype) {
+	case CLAIM_TYPE_ADD:
+		/*
+		 * normal claim frame
+		 * set Ethernet SRC to the clients mac
+		 */
+		memcpy(ethhdr->h_source, mac, ETH_ALEN);
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid);
+		break;
+	case CLAIM_TYPE_DEL:
+		/*
+		 * unclaim frame
+		 * set HW SRC to the clients mac
+		 */
+		memcpy(hw_src, mac, ETH_ALEN);
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_send_claim(): UNCLAIM %pM on vid %d\n", mac, vid);
+		break;
+	case CLAIM_TYPE_ANNOUNCE:
+		/*
+		 * announcement frame
+		 * set HW SRC to the special mac containg the crc
+		 */
+		memcpy(hw_src, mac, ETH_ALEN);
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
+			ethhdr->h_source, vid);
+		break;
+	case CLAIM_TYPE_REQUEST:
+		/*
+		 * request frame
+		 * set HW SRC to the special mac containg the crc
+		 */
+		memcpy(hw_src, mac, ETH_ALEN);
+		memcpy(ethhdr->h_dest, mac, ETH_ALEN);
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_send_claim(): REQUEST of %pM to %pMon vid %d\n",
+			ethhdr->h_source, ethhdr->h_dest, vid);
+		break;
+
+	}
+
+	if (vid != -1)
+		skb = vlan_insert_tag(skb, vid);
+
+	skb_reset_mac_header(skb);
+	skb->protocol = eth_type_trans(skb, soft_iface);
+	bat_priv->stats.rx_packets++;
+	bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr);
+	soft_iface->last_rx = jiffies;
+
+	netif_rx(skb);
+out:
+	if (primary_if)
+		hardif_free_ref(primary_if);
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @orig: the mac address of the originator
+ * @vid: the VLAN ID
+ *
+ * searches for the backbone gw or creates a new one if it could not
+ * be found.
+ */
+
+static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
+		uint8_t *orig, short vid)
+{
+	struct backbone_gw *entry;
+
+	entry = backbone_hash_find(bat_priv, orig, vid);
+
+	if (entry)
+		return entry;
+
+	bat_dbg(DBG_BLA, bat_priv,
+		"bla_get_backbone_gw(): not found (%pM, %d),"
+		" creating new entry\n", orig, vid);
+
+	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+	if (!entry)
+		return NULL;
+
+	entry->vid = vid;
+	entry->lasttime = jiffies;
+	entry->crc = BLA_CRC_INIT;
+	entry->bat_priv = bat_priv;
+	atomic_set(&entry->request_sent, 0);
+	memcpy(entry->orig, orig, ETH_ALEN);
+
+	/* one for the hash, one for returning */
+	atomic_set(&entry->refcount, 2);
+
+	hash_add(bat_priv->backbone_hash, compare_backbone_gw, choose_claim,
+			entry, &entry->hash_entry);
+
+	return entry;
+}
+
+/*
+ * update or add the own backbone gw to make sure we announce
+ * where we receive other backbone gws
+ */
+void bla_update_own_backbone_gw(struct bat_priv *bat_priv, short vid)
+{
+	struct backbone_gw *backbone_gw;
+
+	backbone_gw = bla_get_backbone_gw(bat_priv, bat_priv->own_orig, vid);
+	backbone_gw->lasttime = jiffies;
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the vid where the request came on
+ *
+ * Repeat all of our own claims, and finally send an ANNOUNCE frame
+ * to allow the requester another check if the CRC is correct now.
+ */
+
+static void bla_handle_request(struct bat_priv *bat_priv, short vid)
+{
+	struct hlist_node *node;
+	struct hlist_head *head;
+	struct hashtable_t *hash;
+	struct claim *claim;
+	struct backbone_gw *backbone_gw;
+	int i;
+
+	bat_dbg(DBG_BLA, bat_priv,
+		"bla_handle_request(): received a "
+		"claim request, send all of our own claims again\n");
+
+	backbone_gw = backbone_hash_find(bat_priv, bat_priv->own_orig, vid);
+
+	hash = bat_priv->claim_hash;
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(claim, node,
+					 head, hash_entry) {
+			/* only own claims are interesting */
+			if (claim->backbone_gw != backbone_gw)
+				continue;
+
+			bla_send_claim(bat_priv, claim->addr, claim->vid,
+					CLAIM_TYPE_ADD);
+		}
+		rcu_read_unlock();
+	}
+
+	/* finally, send an announcement frame */
+	bla_send_announce(bat_priv, backbone_gw);
+	backbone_gw_free_ref(backbone_gw);
+}
+
+/*
+ * @backbone_gw: the backbone gateway from whom we are out of sync
+ *
+ * When the crc is wrong, ask the backbone gateway for a full table update.
+ * After the request, it will repeat all of his own claims and finally
+ * send an announcement claim with which we can check again.
+ */
+
+static void bla_send_request(struct backbone_gw *backbone_gw)
+{
+	/* first, remove all old entries */
+	bla_del_backbone_claims(backbone_gw);
+
+	bat_dbg(DBG_BLA, backbone_gw->bat_priv,
+		"Sending REQUEST to %pM\n",
+		backbone_gw->orig);
+
+	/* send request */
+	bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
+			backbone_gw->vid, CLAIM_TYPE_REQUEST);
+
+	/* no local broadcasts should be sent or received, for now. */
+	if (!atomic_read(&backbone_gw->request_sent)) {
+		atomic_inc(&backbone_gw->bat_priv->bla_num_requests);
+		atomic_set(&backbone_gw->request_sent, 1);
+	}
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @backbone_gw: our backbone gateway which should be announced
+ *
+ * This function sends an announcement. It is called from multiple
+ * places.
+ */
+static void bla_send_announce(struct bat_priv *bat_priv,
+		struct backbone_gw *backbone_gw)
+{
+	uint8_t mac[6];
+	uint16_t crc;
+
+	memcpy(mac, announce_mac, 4);
+	crc = htons(backbone_gw->crc);
+	memcpy(&mac[4], (uint8_t *) &crc, 2);
+
+	bla_send_claim(bat_priv, mac, backbone_gw->vid, CLAIM_TYPE_ANNOUNCE);
+
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @mac: the mac address of the claim
+ * @vid: the VLAN ID of the frame
+ * @backbone_gw: the backbone gateway which claims it
+ *
+ * Adds a claim in the claim hash.
+ */
+
+static void bla_add_claim(struct bat_priv *bat_priv, const uint8_t *mac,
+		const short vid, struct backbone_gw *backbone_gw)
+{
+	struct claim *claim;
+	struct claim search_claim;
+
+	memcpy(search_claim.addr, mac, ETH_ALEN);
+	search_claim.vid = vid;
+	claim = claim_hash_find(bat_priv, &search_claim);
+
+	/* create a new claim entry if it does not exist yet. */
+	if (!claim) {
+		claim = kzalloc(sizeof(*claim), GFP_ATOMIC);
+		if (!claim)
+			return;
+
+		memcpy(claim->addr, mac, ETH_ALEN);
+		claim->vid = vid;
+		claim->lasttime = jiffies;
+		claim->backbone_gw = backbone_gw;
+
+		atomic_set(&claim->refcount, 2);
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
+			mac, vid);
+		hash_add(bat_priv->claim_hash, compare_claim, choose_claim,
+			claim, &claim->hash_entry);
+	} else {
+		claim->lasttime = jiffies;
+		if (claim->backbone_gw == backbone_gw)
+			/* no need to register a new backbone */
+			goto claim_free_ref;
+
+		bat_dbg(DBG_BLA, bat_priv,
+			"bla_add_claim(): changing ownership for %pM, vid %d\n",
+			mac, vid);
+
+		claim->backbone_gw->crc ^=
+			crc16(0, claim->addr, ETH_ALEN);
+		backbone_gw_free_ref(claim->backbone_gw);
+
+	}
+	/* set (new) backbone gw */
+	atomic_inc(&backbone_gw->refcount);
+	claim->backbone_gw = backbone_gw;
+
+	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
+	backbone_gw->lasttime = jiffies;
+
+claim_free_ref:
+	claim_free_ref(claim);
+}
+
+/*
+ * Delete a claim from the claim hash which has the
+ * given mac address and vid.
+ */
+static void bla_del_claim(struct bat_priv *bat_priv, const uint8_t *mac,
+		const short vid)
+{
+	struct claim search_claim, *claim;
+
+	memcpy(search_claim.addr, mac, ETH_ALEN);
+	search_claim.vid = vid;
+	claim = claim_hash_find(bat_priv, &search_claim);
+	if (!claim)
+		return;
+
+	bat_dbg(DBG_BLA, bat_priv, "bla_del_claim(): %pM, vid %d\n", mac, vid);
+
+	hash_remove(bat_priv->claim_hash, compare_claim, choose_claim,
+		    claim);
+	claim_free_ref(claim); /* reference from the hash is gone */
+
+	claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
+
+	/* don't need the reference from hash_find() anymore */
+	claim_free_ref(claim);
+}
+
+/* check for ANNOUNCE frame, return 1 if handled */
+static int handle_announce(struct bat_priv *bat_priv,
+		uint8_t *an_addr, uint8_t *backbone_addr, short vid)
+{
+	struct backbone_gw *backbone_gw;
+	uint16_t crc;
+
+	if (memcmp(an_addr, announce_mac, 4) != 0)
+		return 0;
+
+	backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid);
+
+	if (unlikely(!backbone_gw))
+		return 1;
+
+
+	/* handle as ANNOUNCE frame */
+	backbone_gw->lasttime = jiffies;
+	crc = ntohs(*((uint16_t *) (&an_addr[4])));
+
+	bat_dbg(DBG_BLA, bat_priv,
+		"handle_announce(): ANNOUNCE vid %d (sent "
+		"by %pM)... CRC = %04x (nw order)\n",
+		vid, backbone_gw->orig, crc);
+
+	if (backbone_gw->crc != crc) {
+		bat_dbg(DBG_BLA, backbone_gw->bat_priv,
+			"handle_announce(): CRC FAILED for %pM/%d"
+			"(my = %04x, sent = %04x)\n",
+			backbone_gw->orig, backbone_gw->vid,
+			backbone_gw->crc, crc);
+
+		bla_send_request(backbone_gw);
+	} else {
+		/* if we have sent a request and the crc was OK,
+		 * we can allow traffic again. */
+		if (atomic_read(&backbone_gw->request_sent)) {
+			atomic_dec(&backbone_gw->bat_priv->bla_num_requests);
+			atomic_set(&backbone_gw->request_sent, 0);
+		}
+	}
+
+	backbone_gw_free_ref(backbone_gw);
+	return 1;
+}
+
+/* check for REQUEST frame, return 1 if handled */
+static int handle_request(struct bat_priv *bat_priv,
+		uint8_t *backbone_addr, struct ethhdr *ethhdr, short vid)
+{
+	/* check for REQUEST frame */
+	if (!compare_eth(backbone_addr, ethhdr->h_dest))
+		return 0;
+
+	/* sanity check, this should not happen on a normal switch,
+	 * we ignore it in this case. */
+	if (!compare_eth(ethhdr->h_dest, bat_priv->own_orig))
+		return 1;
+
+	bat_dbg(DBG_BLA, bat_priv,
+		"handle_request(): REQUEST vid %d (sent "
+		"by %pM)...\n",
+		vid, ethhdr->h_source);
+
+	bla_handle_request(bat_priv, vid);
+	return 1;
+}
+
+/* check for UNCLAIM frame, return 1 if handled */
+static int handle_unclaim(struct bat_priv *bat_priv,
+		uint8_t *backbone_addr, uint8_t *claim_addr, short vid)
+{
+	struct backbone_gw *backbone_gw;
+
+	/* unclaim in any case if it is our own */
+	if (compare_eth(backbone_addr, bat_priv->own_orig))
+		bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_DEL);
+
+	backbone_gw = backbone_hash_find(bat_priv, backbone_addr, vid);
+
+	if (!backbone_gw)
+		return 0;
+
+	/* this must be an UNCLAIM frame */
+	bat_dbg(DBG_BLA, bat_priv, "handle_unclaim():"
+		"UNCLAIM %pM on vid %d (sent by %pM)...\n",
+		claim_addr, vid, backbone_gw->orig);
+
+	bla_del_claim(bat_priv, claim_addr, vid);
+	backbone_gw_free_ref(backbone_gw);
+	return 1;
+}
+
+/* check for CLAIM frame, return 1 if handled */
+static int handle_claim(struct bat_priv *bat_priv,
+		uint8_t *backbone_addr, uint8_t *claim_addr, short vid)
+{
+	struct backbone_gw *backbone_gw;
+
+	/* register the gateway if not yet available, and add the claim. */
+
+	backbone_gw = bla_get_backbone_gw(bat_priv, backbone_addr, vid);
+
+	if (unlikely(!backbone_gw))
+		return 0;
+
+	/* this must be a CLAIM frame */
+	bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
+	if (compare_eth(backbone_addr, bat_priv->own_orig))
+		bla_send_claim(bat_priv, claim_addr, vid, CLAIM_TYPE_ADD);
+
+	/* TODO: we could cal something like tt_local_del() here. */
+
+	backbone_gw_free_ref(backbone_gw);
+	return 1;
+}
+
+/*
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the frame to be checked
+ *
+ * Check if this is a claim frame, and process it accordingly.
+ *
+ * returns 1 if it was a claim frame, otherwise return 0 to
+ * tell the callee that it can use the frame on its own.
+ */
+
+static int bla_process_claim(struct bat_priv *bat_priv, struct sk_buff *skb)
+{
+	struct ethhdr *ethhdr;
+	struct vlan_ethhdr *vhdr;
+	struct arphdr *arphdr;
+	uint8_t *hw_src, *hw_dst;
+	struct bla_claim_dst *bla_dst;
+	uint16_t proto;
+	int headlen;
+	short vid = -1;
+
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
+		vhdr = (struct vlan_ethhdr *) ethhdr;
+		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+		proto = ntohs(vhdr->h_vlan_encapsulated_proto);
+		headlen = sizeof(*vhdr);
+	} else {
+		proto = ntohs(ethhdr->h_proto);
+		headlen = sizeof(*ethhdr);
+	}
+
+	if (proto != ETH_P_ARP)
+		return 0; /* not a claim frame */
+
+	/* this must be a ARP frame. check if it is a claim. */
+
+	if (unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->dev))))
+		return 0;
+
+	arphdr = (struct arphdr *) ((uint8_t *)ethhdr + headlen);
+
+	/* Check whether the ARP frame carries a valid
+	 * IP information */
+
+	if (arphdr->ar_hrd != htons(ARPHRD_ETHER))
+		return 0;
+	if (arphdr->ar_pro != htons(ETH_P_IP))
+		return 0;
+	if (arphdr->ar_hln != ETH_ALEN)
+		return 0;
+	if (arphdr->ar_pln != 4)
+		return 0;
+
+	hw_src = (uint8_t *)arphdr + sizeof(struct arphdr);
+	hw_dst = hw_src + ETH_ALEN + 4;
+	bla_dst = (struct bla_claim_dst *) hw_dst;
+
+	/* check if it is a claim frame. */
+	if (memcmp(hw_dst, claim_dest, 3) != 0)
+		return 0;
+
+	/* become a backbone gw ourselves on this vlan if not happened yet */
+	bla_update_own_backbone_gw(bat_priv, vid);
+
+	/* check for the different types of claim frames ... */
+	switch (bla_dst->type) {
+	case CLAIM_TYPE_ADD:
+		if (handle_claim(bat_priv, hw_src, ethhdr->h_source, vid))
+			return 1;
+		break;
+	case CLAIM_TYPE_DEL:
+		if (handle_unclaim(bat_priv, ethhdr->h_source, hw_src, vid))
+			return 1;
+		break;
+
+	case CLAIM_TYPE_ANNOUNCE:
+		if (handle_announce(bat_priv, hw_src, ethhdr->h_source, vid))
+			return 1;
+		break;
+	case CLAIM_TYPE_REQUEST:
+		if (handle_request(bat_priv, hw_src, ethhdr, vid))
+			return 1;
+		break;
+	}
+
+	bat_dbg(DBG_BLA, bat_priv, "bla_process_claim(): ERROR - this looks"
+		"like a claim frame, but is useless. eth src"
+		"%pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
+		ethhdr->h_source, vid, hw_src, hw_dst);
+	return 1;
+}
+
+/*
+ * Update the backbone gateways when the own orig address changes.
+ */
+void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr)
+{
+	struct backbone_gw *backbone_gw;
+	struct hlist_node *node;
+	struct hlist_head *head;
+	struct hashtable_t *hash;
+	int i;
+
+	hash = bat_priv->backbone_hash;
+	if (!hash)
+		return;
+
+	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) {
+			/* own orig still holds the old value. */
+			if (!compare_eth(backbone_gw->orig,
+						bat_priv->own_orig))
+				continue;
+
+			memcpy(backbone_gw->orig, newaddr, ETH_ALEN);
+			/* send an announce frame so others will ask for our
+			 * claims and update their tables. */
+			bla_send_announce(bat_priv, backbone_gw);
+		}
+		rcu_read_unlock();
+	}
+}
+
+/*
+ * Check when we last heard from other nodes, and remove them in case of
+ * a time out.
+ */
+static void bla_purge_backbone_gw(struct bat_priv *bat_priv)
+{
+	struct backbone_gw *backbone_gw;
+	struct hlist_node *node, *node_tmp;
+	struct hlist_head *head;
+	struct hashtable_t *hash;
+	spinlock_t *list_lock;	/* protects write access to the hash lists */
+	int i;
+
+	hash = bat_priv->backbone_hash;
+	if (!hash)
+		return;
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+		list_lock = &hash->list_locks[i];
+
+		spin_lock_bh(list_lock);
+		hlist_for_each_entry_safe(backbone_gw, node, node_tmp,
+					  head, hash_entry) {
+			if (!time_after(jiffies, backbone_gw->lasttime
+				+ msecs_to_jiffies(BLA_BACKBONE_TIMEOUT)))
+				continue;
+
+			bat_dbg(DBG_BLA, backbone_gw->bat_priv,
+				"bla_purge_backbone_gw(): backbone gw %pM"
+				" timed out\n",	backbone_gw->orig);
+
+			/* don't wait for the pending request anymore */
+			if (atomic_read(&backbone_gw->request_sent))
+				atomic_dec(&bat_priv->bla_num_requests);
+
+			bla_del_backbone_claims(backbone_gw);
+
+			hlist_del_rcu(node);
+			backbone_gw_free_ref(backbone_gw);
+		}
+		spin_unlock_bh(list_lock);
+	}
+}
+
+/*
+ * Check when we heard last time from our own claims, and remove them in case of
+ * a time out
+ */
+static void bla_purge_claims(struct bat_priv *bat_priv)
+{
+	struct claim *claim;
+	struct hlist_node *node;
+	struct hlist_head *head;
+	struct hashtable_t *hash;
+	int i;
+
+	hash = bat_priv->claim_hash;
+	if (!hash)
+		return;
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+
+		rcu_read_lock();
+		hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
+			if (!compare_eth(claim->backbone_gw->orig,
+						bat_priv->own_orig))
+				continue;
+			if (!time_after(jiffies, claim->lasttime
+				+ msecs_to_jiffies(BLA_CLAIM_TIMEOUT)))
+				continue;
+
+			bat_dbg(DBG_BLA, bat_priv,
+				"bla_purge_claims(): %pM, vid %d, time out\n",
+				claim->addr, claim->vid);
+
+			handle_unclaim(bat_priv, bat_priv->own_orig,
+					claim->addr, claim->vid);
+		}
+		rcu_read_unlock();
+	}
+}
+
+/* (re)start the timer */
+static void bla_start_timer(struct bat_priv *bat_priv)
+{
+	INIT_DELAYED_WORK(&bat_priv->bla_work, bla_periodic_work);
+	queue_delayed_work(bat_event_workqueue, &bat_priv->bla_work,
+			   msecs_to_jiffies(BLA_PERIOD_LENGTH));
+}
+
+/*
+ * periodic work to do:
+ *  * purge structures when they are too old
+ *  * send announcements
+ */
+
+static void bla_periodic_work(struct work_struct *work)
+{
+	struct delayed_work *delayed_work =
+		container_of(work, struct delayed_work, work);
+	struct bat_priv *bat_priv =
+		container_of(delayed_work, struct bat_priv, bla_work);
+	struct hlist_node *node;
+	struct hlist_head *head;
+	struct backbone_gw *backbone_gw;
+	struct hashtable_t *hash;
+	int i;
+
+	bla_purge_claims(bat_priv);
+	bla_purge_backbone_gw(bat_priv);
+
+	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+		goto timer;
+
+	hash = bat_priv->backbone_hash;
+	if (!hash)
+		return;
+
+	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) {
+			if (!compare_eth(backbone_gw->orig, bat_priv->own_orig))
+				continue;
+
+			backbone_gw->lasttime = jiffies;
+
+			bla_send_announce(bat_priv, backbone_gw);
+		}
+		rcu_read_unlock();
+	}
+timer:
+	bla_start_timer(bat_priv);
+}
+
+/* initialize all bla structures */
+int bla_init(struct bat_priv *bat_priv)
+{
+	bat_dbg(DBG_BLA, bat_priv, "bla hash registering\n");
+
+	if (bat_priv->claim_hash)
+		return 1;
+
+	bat_priv->claim_hash = hash_new(128);
+	bat_priv->backbone_hash = hash_new(32);
+
+	if (!bat_priv->claim_hash || !bat_priv->backbone_hash)
+		return -1;
+
+	bat_dbg(DBG_BLA, bat_priv, "bla hashes initialized\n");
+
+	bla_start_timer(bat_priv);
+	return 1;
+}
+
+/**
+ * @skb: the frame to be checked
+ * @orig_node: the orig_node of the frame
+ * @hdr_size: maximum length of the frame
+ *
+ * bla_is_backbone_gw inspects the skb for the VLAN ID and returns 1
+ * if the orig_node is also a gateway on the soft interface, otherwise it
+ * returns 0.
+ *
+ **/
+
+int bla_is_backbone_gw(struct sk_buff *skb,
+		struct orig_node *orig_node, int hdr_size)
+{
+	struct ethhdr *ethhdr;
+	struct vlan_ethhdr *vhdr;
+	struct backbone_gw *backbone_gw;
+	short vid = -1;
+
+	if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
+		return 0;
+
+	/* first, find out the vid. */
+	if (!pskb_may_pull(skb, hdr_size + sizeof(struct ethhdr)))
+		return 0;
+
+	ethhdr = (struct ethhdr *) (((uint8_t *)skb->data) + hdr_size);
+
+	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) {
+		if (!pskb_may_pull(skb, hdr_size + sizeof(struct vlan_ethhdr)))
+			return 0;
+
+		vhdr = (struct vlan_ethhdr *) ethhdr;
+		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
+	}
+
+	/* see if this originator is a backbone gw for this VLAN */
+
+	backbone_gw = backbone_hash_find(orig_node->bat_priv,
+			orig_node->orig, vid);
+	if (!backbone_gw)
+		return 0;
+
+	bat_dbg(DBG_BLA, orig_node->bat_priv,
+		"bla_is_backbone_gw(): originator %pM has a claim "
+		"for vid %d on the LAN ...\n", orig_node->orig, vid);
+	backbone_gw_free_ref(backbone_gw);
+	return 1;
+}
+
+/* free all bla structures (for softinterface free or module unload) */
+void bla_free(struct bat_priv *bat_priv)
+{
+	struct claim *claim;
+	struct backbone_gw *backbone_gw;
+	struct hlist_node *node, *node_tmp;
+	struct hlist_head *head;
+	struct hashtable_t *hash;
+	spinlock_t *list_lock;	/* protects write access to the hash lists */
+	int i;
+
+	cancel_delayed_work_sync(&bat_priv->bla_work);
+	atomic_set(&bat_priv->bla_num_requests, 0);
+
+	hash = bat_priv->claim_hash;
+	if (!hash)
+		goto free_backbone_hash;
+
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+		list_lock = &hash->list_locks[i];
+
+		spin_lock_bh(list_lock);
+		hlist_for_each_entry_safe(claim, node, node_tmp,
+					  head, hash_entry) {
+			hlist_del_rcu(node);
+			claim_free_ref(claim);
+		}
+		spin_unlock_bh(list_lock);
+	}
+
+	hash_destroy(hash);
+	bat_priv->claim_hash = NULL;
+free_backbone_hash:
+	hash = bat_priv->backbone_hash;
+	if (!hash)
+		return;
+
+	for (i = 0; i < hash->size; i++) {
+		head = &hash->table[i];
+		list_lock = &hash->list_locks[i];
+
+		spin_lock_bh(list_lock);
+		hlist_for_each_entry_safe(backbone_gw, node, node_tmp,
+					  head, hash_entry) {
+			hlist_del_rcu(node);
+			backbone_gw_free_ref(backbone_gw);
+		}
+		spin_unlock_bh(list_lock);
+	}
+
+	hash_destroy(hash);
+	bat_priv->backbone_hash = NULL;
+
+}
+
+/**
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the frame to be checked
+ * @vid: the VLAN ID of the frame
+ *
+ * bla_rx avoidance checks if:
+ *  * we have to race for a claim
+ *  * if the frame is allowed on the LAN
+ *
+ * in these cases, the skb is further handled by this function and
+ * returns 1, otherwise it returns 0 and the caller shall further
+ * process the skb.
+ *
+ **/
+
+int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid)
+{
+	struct ethhdr *ethhdr;
+	struct claim search_claim, *claim = NULL;
+
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+		goto allow;
+
+
+	if (unlikely(atomic_read(&bat_priv->bla_num_requests)))
+		/* don't allow broadcasts while requests are in flight */
+		if (is_multicast_ether_addr(ethhdr->h_dest))
+			goto handled;
+
+	memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
+	search_claim.vid = vid;
+	claim = claim_hash_find(bat_priv, &search_claim);
+
+	if (!claim) {
+		/* possible optimization: race for a claim */
+		/* No claim exists yet, claim it for us! */
+		handle_claim(bat_priv, bat_priv->own_orig,
+				ethhdr->h_source, vid);
+		goto allow;
+	}
+
+	/* if it is our own claim ... */
+	if (compare_eth(claim->backbone_gw->orig, bat_priv->own_orig)) {
+		/* ... allow it in any case */
+		claim->lasttime = jiffies;
+		goto allow;
+	}
+
+	/* if it is a broadcast ... */
+	if (is_multicast_ether_addr(ethhdr->h_dest)) {
+		/* ... drop it. the responsible gateway is in charge. */
+		goto handled;
+	} else {
+		/* seems the client considers us as its best gateway.
+		 * send a claim and update the claim table
+		 * immediately. */
+		handle_claim(bat_priv, bat_priv->own_orig,
+				ethhdr->h_source, vid);
+		goto allow;
+	}
+allow:
+	bla_update_own_backbone_gw(bat_priv, vid);
+	if (claim)
+		claim_free_ref(claim);
+	return 0;
+handled:
+	kfree_skb(skb);
+	if (claim)
+		claim_free_ref(claim);
+	return 1;
+}
+
+/**
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the frame to be checked
+ * @vid: the VLAN ID of the frame
+ *
+ * bla_tx checks if:
+ *  * a claim was received which has to be processed
+ *  * the frame is allowed on the mesh
+ *
+ * in these cases, the skb is further handled by this function and
+ * returns 1, otherwise it returns 0 and the caller shall further
+ * process the skb.
+ *
+ **/
+
+int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid)
+{
+	struct ethhdr *ethhdr;
+	struct claim search_claim, *claim = NULL;
+
+	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
+		goto allow;
+
+	/* in VLAN case, the mac header might not be set. */
+	skb_reset_mac_header(skb);
+
+	if (bla_process_claim(bat_priv, skb))
+		goto handled;
+
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+
+	if (unlikely(atomic_read(&bat_priv->bla_num_requests)))
+		/* don't allow broadcasts while requests are in flight */
+		if (is_multicast_ether_addr(ethhdr->h_dest))
+			goto handled;
+
+	memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN);
+	search_claim.vid = vid;
+
+	bat_dbg(DBG_BLA, bat_priv,
+		"bla_tx(): checked for claims, now starting ..."
+		"%pM -> %pM [%04x], vid %d\n",
+		ethhdr->h_source, ethhdr->h_dest,
+		ntohs(ethhdr->h_proto), search_claim.vid);
+	claim = claim_hash_find(bat_priv, &search_claim);
+
+	/* if no claim exists, allow it. */
+	if (!claim)
+		goto allow;
+
+	/* check if we are responsible. */
+	if (compare_eth(claim->backbone_gw->orig, bat_priv->own_orig)) {
+		/* if yes, the client has roamed and we have
+		 * to unclaim it. */
+		handle_unclaim(bat_priv, bat_priv->own_orig,
+				ethhdr->h_source, vid);
+		goto allow;
+	}
+
+	/* check if it is a multicast/broadcast frame */
+	if (is_multicast_ether_addr(ethhdr->h_dest)) {
+		/* drop it. the responsible gateway has forwarded it into
+		 * the backbone network. */
+		goto handled;
+	} else {
+		/* we must allow it. at least if we are
+		 * responsible for the DESTINATION. */
+		goto allow;
+	}
+allow:
+	bla_update_own_backbone_gw(bat_priv, vid);
+	if (claim)
+		claim_free_ref(claim);
+	return 0;
+handled:
+	if (claim)
+		claim_free_ref(claim);
+	return 1;
+}
diff --git a/bridge_loop_avoidance.h b/bridge_loop_avoidance.h
new file mode 100644
index 0000000..8df5036
--- /dev/null
+++ b/bridge_loop_avoidance.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 B.A.T.M.A.N. contributors:
+ *
+ * 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
+ *
+ */
+
+int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
+int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid);
+int bla_is_backbone_gw(struct sk_buff *skb,
+		struct orig_node *orig_node, int hdr_size);
+void bla_update_orig_address(struct bat_priv *bat_priv, uint8_t *newaddr);
+int bla_init(struct bat_priv *bat_priv);
+void bla_free(struct bat_priv *bat_priv);
+
+#define BLA_CRC_INIT	0
diff --git a/compat.c b/compat.c
index 4c12468..5b389b2 100644
--- a/compat.c
+++ b/compat.c
@@ -28,4 +28,12 @@ void free_rcu_tt_local_entry(struct rcu_head *rcu)
 	kfree(tt_local_entry);
 }
 
+void free_rcu_backbone_gw(struct rcu_head *rcu)
+{
+	struct backbone_gw *backbone_gw;
+
+	backbone_gw = container_of(rcu, struct backbone_gw, rcu);
+	kfree(backbone_gw);
+}
+
 #endif /* < KERNEL_VERSION(3, 0, 0) */
diff --git a/compat.h b/compat.h
index 531ba85..41655a6 100644
--- a/compat.h
+++ b/compat.h
@@ -65,10 +65,12 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
 
 #define kfree_rcu(ptr, rcu_head) call_rcu(&ptr->rcu_head, free_rcu_##ptr)
+#define vlan_insert_tag(skb, vid) __vlan_put_tag(skb, vid)
 
 void free_rcu_gw_node(struct rcu_head *rcu);
 void free_rcu_neigh_node(struct rcu_head *rcu);
 void free_rcu_tt_local_entry(struct rcu_head *rcu);
+void free_rcu_backbone_gw(struct rcu_head *rcu);
 
 #endif /* < KERNEL_VERSION(3, 0, 0) */
 
diff --git a/hard-interface.c b/hard-interface.c
index 7704df4..f64adff 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -29,6 +29,7 @@
 #include "originator.h"
 #include "hash.h"
 #include "bat_ogm.h"
+#include "bridge_loop_avoidance.h"
 
 #include <linux/if_arp.h>
 
@@ -123,6 +124,11 @@ static void primary_if_update_addr(struct bat_priv *bat_priv)
 	memcpy(vis_packet->sender_orig,
 	       primary_if->net_dev->dev_addr, ETH_ALEN);
 
+	/* before updating bat_priv->own_orig,
+	 * change own addresses in backbone gw */
+	bla_update_orig_address(bat_priv, primary_if->net_dev->dev_addr);
+	memcpy(bat_priv->own_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
+
 out:
 	if (primary_if)
 		hardif_free_ref(primary_if);
@@ -634,7 +640,7 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	case BAT_TT_QUERY:
 		ret = recv_tt_query(skb, hard_iface);
 		break;
-		/* Roaming advertisement */
+		/* bridge roop avoidance query */
 	case BAT_ROAM_ADV:
 		ret = recv_roam_adv(skb, hard_iface);
 		break;
diff --git a/main.c b/main.c
index 36661b4..85cb79b 100644
--- a/main.c
+++ b/main.c
@@ -30,6 +30,7 @@
 #include "translation-table.h"
 #include "hard-interface.h"
 #include "gateway_client.h"
+#include "bridge_loop_avoidance.h"
 #include "vis.h"
 #include "hash.h"
 
@@ -109,6 +110,9 @@ int mesh_init(struct net_device *soft_iface)
 	if (vis_init(bat_priv) < 1)
 		goto err;
 
+	if (bla_init(bat_priv) < 1)
+		goto err;
+
 	atomic_set(&bat_priv->gw_reselect, 0);
 	atomic_set(&bat_priv->mesh_state, MESH_ACTIVE);
 	goto end;
@@ -136,6 +140,8 @@ void mesh_free(struct net_device *soft_iface)
 
 	tt_free(bat_priv);
 
+	bla_free(bat_priv);
+
 	atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
 }
 
diff --git a/main.h b/main.h
index b395c7b..1bd41f1 100644
--- a/main.h
+++ b/main.h
@@ -79,6 +79,9 @@
 #define MAX_AGGREGATION_BYTES 512
 #define MAX_AGGREGATION_MS 100
 
+#define BLA_PERIOD_LENGTH	10000	/* 10 seconds */
+#define BLA_BACKBONE_TIMEOUT	(BLA_PERIOD_LENGTH * 3)
+#define BLA_CLAIM_TIMEOUT	(BLA_PERIOD_LENGTH * 10)
 /* don't reset again within 30 seconds */
 #define RESET_PROTECTION_MS 30000
 #define EXPECTED_SEQNO_RANGE	65536
@@ -118,7 +121,8 @@ enum dbg_level {
 	DBG_BATMAN = 1 << 0,
 	DBG_ROUTES = 1 << 1, /* route added / changed / deleted */
 	DBG_TT	   = 1 << 2, /* translation table operations */
-	DBG_ALL    = 7
+	DBG_BLA    = 1 << 3, /* bridge loop avoidance */
+	DBG_ALL    = 15
 };
 
 
diff --git a/originator.c b/originator.c
index a9c8b66..52e778a 100644
--- a/originator.c
+++ b/originator.c
@@ -28,6 +28,7 @@
 #include "hard-interface.h"
 #include "unicast.h"
 #include "soft-interface.h"
+#include "bridge_loop_avoidance.h"
 
 static void purge_orig(struct work_struct *work);
 
diff --git a/packet.h b/packet.h
index 4d9e54c..48c7b74 100644
--- a/packet.h
+++ b/packet.h
@@ -90,6 +90,22 @@ enum tt_client_flags {
 	TT_CLIENT_PENDING = 1 << 10
 };
 
+/* claim frame types for the bridge loop avoidance */
+enum bla_claimframe {
+	CLAIM_TYPE_ADD		= 0x00,
+	CLAIM_TYPE_DEL		= 0x01,
+	CLAIM_TYPE_ANNOUNCE	= 0x02,
+	CLAIM_TYPE_REQUEST	= 0x03
+};
+
+/* the destination hardware field in the ARP frame is used to
+ * transport the claim type and the group id */
+struct bla_claim_dst {
+	uint8_t magic[3];	/* FF:43:05 */
+	uint8_t type;		/* bla_claimframe */
+	uint16_t group;		/* group id */
+} __packed;
+
 struct batman_ogm_packet {
 	uint8_t  packet_type;
 	uint8_t  version;  /* batman version field */
diff --git a/routing.c b/routing.c
index ef24a72..8050fb2 100644
--- a/routing.c
+++ b/routing.c
@@ -30,6 +30,7 @@
 #include "vis.h"
 #include "unicast.h"
 #include "bat_ogm.h"
+#include "bridge_loop_avoidance.h"
 
 void slide_own_bcast_window(struct hard_iface *hard_iface)
 {
@@ -1074,6 +1075,11 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	/* rebroadcast packet */
 	add_bcast_packet_to_list(bat_priv, skb, 1);
 
+	/* don't hand the broadcast up if it is from an originator
+	 * from the same backbone. */
+	if (bla_is_backbone_gw(skb, orig_node, hdr_size))
+		goto out;
+
 	/* broadcast for me */
 	interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
 	ret = NET_RX_SUCCESS;
diff --git a/soft-interface.c b/soft-interface.c
index 4806deb..46dd328 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -36,6 +36,7 @@
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
 #include "unicast.h"
+#include "bridge_loop_avoidance.h"
 
 
 static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
@@ -151,6 +152,9 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 		goto dropped;
 	}
 
+	if (bla_tx(bat_priv, skb, vid))
+		goto dropped;
+
 	/* Register the client MAC in the transtable */
 	tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
 
@@ -286,6 +290,11 @@ void interface_rx(struct net_device *soft_iface,
 	if (is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
 		goto dropped;
 
+	/* Let the bridge loop avoidance check the packet. If will
+	 * not handle it, we can safely push it up. */
+	if (bla_rx(bat_priv, skb, vid))
+		goto out;
+
 	netif_rx(skb);
 	goto out;
 
@@ -355,6 +364,7 @@ struct net_device *softif_create(const char *name)
 
 	atomic_set(&bat_priv->aggregated_ogms, 1);
 	atomic_set(&bat_priv->bonding, 0);
+	atomic_set(&bat_priv->bridge_loop_avoidance, 1);
 	atomic_set(&bat_priv->ap_isolation, 0);
 	atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
 	atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
@@ -372,6 +382,7 @@ struct net_device *softif_create(const char *name)
 	atomic_set(&bat_priv->ttvn, 0);
 	atomic_set(&bat_priv->tt_local_changes, 0);
 	atomic_set(&bat_priv->tt_ogm_append_cnt, 0);
+	atomic_set(&bat_priv->bla_num_requests, 0);
 
 	bat_priv->tt_buff = NULL;
 	bat_priv->tt_buff_len = 0;
diff --git a/types.h b/types.h
index db6ae2b..3cffe8d 100644
--- a/types.h
+++ b/types.h
@@ -147,6 +147,7 @@ struct bat_priv {
 	atomic_t bonding;		/* boolean */
 	atomic_t fragmentation;		/* boolean */
 	atomic_t ap_isolation;		/* boolean */
+	atomic_t bridge_loop_avoidance;	/* boolean */
 	atomic_t vis_mode;		/* VIS_TYPE_* */
 	atomic_t gw_mode;		/* GW_MODE_* */
 	atomic_t gw_sel_class;		/* uint */
@@ -160,6 +161,7 @@ struct bat_priv {
 	atomic_t ttvn; /* translation table version number */
 	atomic_t tt_ogm_append_cnt;
 	atomic_t tt_local_changes; /* changes registered in a OGM interval */
+	atomic_t bla_num_requests; /* number of bla requests in flight */
 	/* The tt_poss_change flag is used to detect an ongoing roaming phase.
 	 * If true, then I received a Roaming_adv and I have to inspect every
 	 * packet directed to me to check whether I am still the true
@@ -178,6 +180,8 @@ struct bat_priv {
 	struct hashtable_t *orig_hash;
 	struct hashtable_t *tt_local_hash;
 	struct hashtable_t *tt_global_hash;
+	struct hashtable_t *claim_hash;
+	struct hashtable_t *backbone_hash;
 	struct list_head tt_req_list; /* list of pending tt_requests */
 	struct list_head tt_roam_list;
 	struct hashtable_t *vis_hash;
@@ -198,10 +202,12 @@ struct bat_priv {
 	struct delayed_work tt_work;
 	struct delayed_work orig_work;
 	struct delayed_work vis_work;
+	struct delayed_work bla_work;
 	struct gw_node __rcu *curr_gw;  /* rcu protected pointer */
 	atomic_t gw_reselect;
 	struct hard_iface __rcu *primary_if;  /* rcu protected pointer */
 	struct vis_info *my_vis_info;
+	uint8_t own_orig[6];		/* cache primary hardifs address */
 };
 
 struct socket_client {
@@ -239,6 +245,28 @@ struct tt_global_entry {
 	struct rcu_head rcu;
 };
 
+struct backbone_gw {
+	uint8_t orig[ETH_ALEN];
+	short vid;		/* used VLAN ID */
+	struct hlist_node hash_entry;
+	struct bat_priv *bat_priv;
+	unsigned long lasttime;	/* last time we heard of this backbone gw */
+	atomic_t request_sent;
+	atomic_t refcount;
+	struct rcu_head rcu;
+	uint16_t crc;		/* crc checksum over all claims */
+} __packed;
+
+struct claim {
+	uint8_t addr[ETH_ALEN];
+	short vid;
+	struct backbone_gw *backbone_gw;
+	unsigned long lasttime;	/* last time we heard of claim (locals only) */
+	struct rcu_head rcu;
+	atomic_t refcount;
+	struct hlist_node hash_entry;
+} __packed;
+
 struct tt_change_node {
 	struct list_head list;
 	struct tt_change change;
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 01/11] batman-adv: remove old bridge loop avoidance code
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich
In-Reply-To: <1320015072-10313-1-git-send-email-siwu@hrz.tu-chemnitz.de>

The functionality is to be replaced by an improved implementation,
so first clean up.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

---
[2011-10-30] Changes:
 * remove obsolete softfif_batman_recv() function

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 bat_debugfs.c    |    8 -
 compat.c         |    8 -
 compat.h         |    1 -
 main.c           |    5 -
 main.h           |    2 -
 originator.c     |    2 -
 soft-interface.c |  477 +-----------------------------------------------------
 soft-interface.h |    2 -
 types.h          |   21 ---
 9 files changed, 1 insertions(+), 525 deletions(-)

diff --git a/bat_debugfs.c b/bat_debugfs.c
index d0af9bf..492eec7 100644
--- a/bat_debugfs.c
+++ b/bat_debugfs.c
@@ -233,12 +233,6 @@ static int gateways_open(struct inode *inode, struct file *file)
 	return single_open(file, gw_client_seq_print_text, net_dev);
 }
 
-static int softif_neigh_open(struct inode *inode, struct file *file)
-{
-	struct net_device *net_dev = (struct net_device *)inode->i_private;
-	return single_open(file, softif_neigh_seq_print_text, net_dev);
-}
-
 static int transtable_global_open(struct inode *inode, struct file *file)
 {
 	struct net_device *net_dev = (struct net_device *)inode->i_private;
@@ -276,7 +270,6 @@ struct bat_debuginfo bat_debuginfo_##_name = {	\
 
 static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
 static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
-static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open);
 static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
 static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
 static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
@@ -284,7 +277,6 @@ static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
 static struct bat_debuginfo *mesh_debuginfos[] = {
 	&bat_debuginfo_originators,
 	&bat_debuginfo_gateways,
-	&bat_debuginfo_softif_neigh,
 	&bat_debuginfo_transtable_global,
 	&bat_debuginfo_transtable_local,
 	&bat_debuginfo_vis_data,
diff --git a/compat.c b/compat.c
index 1793904..4c12468 100644
--- a/compat.c
+++ b/compat.c
@@ -20,14 +20,6 @@ void free_rcu_neigh_node(struct rcu_head *rcu)
 	kfree(neigh_node);
 }
 
-void free_rcu_softif_neigh(struct rcu_head *rcu)
-{
-	struct softif_neigh *softif_neigh;
-
-	softif_neigh = container_of(rcu, struct softif_neigh, rcu);
-	kfree(softif_neigh);
-}
-
 void free_rcu_tt_local_entry(struct rcu_head *rcu)
 {
 	struct tt_local_entry *tt_local_entry;
diff --git a/compat.h b/compat.h
index 964c066..531ba85 100644
--- a/compat.h
+++ b/compat.h
@@ -68,7 +68,6 @@
 
 void free_rcu_gw_node(struct rcu_head *rcu);
 void free_rcu_neigh_node(struct rcu_head *rcu);
-void free_rcu_softif_neigh(struct rcu_head *rcu);
 void free_rcu_tt_local_entry(struct rcu_head *rcu);
 
 #endif /* < KERNEL_VERSION(3, 0, 0) */
diff --git a/main.c b/main.c
index fb87bdc..36661b4 100644
--- a/main.c
+++ b/main.c
@@ -90,13 +90,10 @@ int mesh_init(struct net_device *soft_iface)
 	spin_lock_init(&bat_priv->gw_list_lock);
 	spin_lock_init(&bat_priv->vis_hash_lock);
 	spin_lock_init(&bat_priv->vis_list_lock);
-	spin_lock_init(&bat_priv->softif_neigh_lock);
-	spin_lock_init(&bat_priv->softif_neigh_vid_lock);
 
 	INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
 	INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
 	INIT_HLIST_HEAD(&bat_priv->gw_list);
-	INIT_HLIST_HEAD(&bat_priv->softif_neigh_vids);
 	INIT_LIST_HEAD(&bat_priv->tt_changes_list);
 	INIT_LIST_HEAD(&bat_priv->tt_req_list);
 	INIT_LIST_HEAD(&bat_priv->tt_roam_list);
@@ -139,8 +136,6 @@ void mesh_free(struct net_device *soft_iface)
 
 	tt_free(bat_priv);
 
-	softif_neigh_purge(bat_priv);
-
 	atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
 }
 
diff --git a/main.h b/main.h
index 53e5d9f..b395c7b 100644
--- a/main.h
+++ b/main.h
@@ -79,8 +79,6 @@
 #define MAX_AGGREGATION_BYTES 512
 #define MAX_AGGREGATION_MS 100
 
-#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */
-
 /* don't reset again within 30 seconds */
 #define RESET_PROTECTION_MS 30000
 #define EXPECTED_SEQNO_RANGE	65536
diff --git a/originator.c b/originator.c
index 0bc2045..a9c8b66 100644
--- a/originator.c
+++ b/originator.c
@@ -380,8 +380,6 @@ static void _purge_orig(struct bat_priv *bat_priv)
 
 	gw_node_purge(bat_priv);
 	gw_election(bat_priv);
-
-	softif_neigh_purge(bat_priv);
 }
 
 static void purge_orig(struct work_struct *work)
diff --git a/soft-interface.c b/soft-interface.c
index 45297c8..4806deb 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -73,440 +73,6 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len)
 	return 0;
 }
 
-static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
-{
-	if (atomic_dec_and_test(&softif_neigh->refcount))
-		kfree_rcu(softif_neigh, rcu);
-}
-
-static void softif_neigh_vid_free_rcu(struct rcu_head *rcu)
-{
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct softif_neigh *softif_neigh;
-	struct hlist_node *node, *node_tmp;
-	struct bat_priv *bat_priv;
-
-	softif_neigh_vid = container_of(rcu, struct softif_neigh_vid, rcu);
-	bat_priv = softif_neigh_vid->bat_priv;
-
-	spin_lock_bh(&bat_priv->softif_neigh_lock);
-	hlist_for_each_entry_safe(softif_neigh, node, node_tmp,
-				  &softif_neigh_vid->softif_neigh_list, list) {
-		hlist_del_rcu(&softif_neigh->list);
-		softif_neigh_free_ref(softif_neigh);
-	}
-	spin_unlock_bh(&bat_priv->softif_neigh_lock);
-
-	kfree(softif_neigh_vid);
-}
-
-static void softif_neigh_vid_free_ref(struct softif_neigh_vid *softif_neigh_vid)
-{
-	if (atomic_dec_and_test(&softif_neigh_vid->refcount))
-		call_rcu(&softif_neigh_vid->rcu, softif_neigh_vid_free_rcu);
-}
-
-static struct softif_neigh_vid *softif_neigh_vid_get(struct bat_priv *bat_priv,
-						     short vid)
-{
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct hlist_node *node;
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(softif_neigh_vid, node,
-				 &bat_priv->softif_neigh_vids, list) {
-		if (softif_neigh_vid->vid != vid)
-			continue;
-
-		if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
-			continue;
-
-		goto out;
-	}
-
-	softif_neigh_vid = kzalloc(sizeof(*softif_neigh_vid), GFP_ATOMIC);
-	if (!softif_neigh_vid)
-		goto out;
-
-	softif_neigh_vid->vid = vid;
-	softif_neigh_vid->bat_priv = bat_priv;
-
-	/* initialize with 2 - caller decrements counter by one */
-	atomic_set(&softif_neigh_vid->refcount, 2);
-	INIT_HLIST_HEAD(&softif_neigh_vid->softif_neigh_list);
-	INIT_HLIST_NODE(&softif_neigh_vid->list);
-	spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
-	hlist_add_head_rcu(&softif_neigh_vid->list,
-			   &bat_priv->softif_neigh_vids);
-	spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
-
-out:
-	rcu_read_unlock();
-	return softif_neigh_vid;
-}
-
-static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv,
-					     const uint8_t *addr, short vid)
-{
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct softif_neigh *softif_neigh = NULL;
-	struct hlist_node *node;
-
-	softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
-	if (!softif_neigh_vid)
-		goto out;
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(softif_neigh, node,
-				 &softif_neigh_vid->softif_neigh_list,
-				 list) {
-		if (!compare_eth(softif_neigh->addr, addr))
-			continue;
-
-		if (!atomic_inc_not_zero(&softif_neigh->refcount))
-			continue;
-
-		softif_neigh->last_seen = jiffies;
-		goto unlock;
-	}
-
-	softif_neigh = kzalloc(sizeof(*softif_neigh), GFP_ATOMIC);
-	if (!softif_neigh)
-		goto unlock;
-
-	memcpy(softif_neigh->addr, addr, ETH_ALEN);
-	softif_neigh->last_seen = jiffies;
-	/* initialize with 2 - caller decrements counter by one */
-	atomic_set(&softif_neigh->refcount, 2);
-
-	INIT_HLIST_NODE(&softif_neigh->list);
-	spin_lock_bh(&bat_priv->softif_neigh_lock);
-	hlist_add_head_rcu(&softif_neigh->list,
-			   &softif_neigh_vid->softif_neigh_list);
-	spin_unlock_bh(&bat_priv->softif_neigh_lock);
-
-unlock:
-	rcu_read_unlock();
-out:
-	if (softif_neigh_vid)
-		softif_neigh_vid_free_ref(softif_neigh_vid);
-	return softif_neigh;
-}
-
-static struct softif_neigh *softif_neigh_get_selected(
-				struct softif_neigh_vid *softif_neigh_vid)
-{
-	struct softif_neigh *softif_neigh;
-
-	rcu_read_lock();
-	softif_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
-
-	if (softif_neigh && !atomic_inc_not_zero(&softif_neigh->refcount))
-		softif_neigh = NULL;
-
-	rcu_read_unlock();
-	return softif_neigh;
-}
-
-static struct softif_neigh *softif_neigh_vid_get_selected(
-						struct bat_priv *bat_priv,
-						short vid)
-{
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct softif_neigh *softif_neigh = NULL;
-
-	softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
-	if (!softif_neigh_vid)
-		goto out;
-
-	softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
-out:
-	if (softif_neigh_vid)
-		softif_neigh_vid_free_ref(softif_neigh_vid);
-	return softif_neigh;
-}
-
-static void softif_neigh_vid_select(struct bat_priv *bat_priv,
-				    struct softif_neigh *new_neigh,
-				    short vid)
-{
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct softif_neigh *curr_neigh;
-
-	softif_neigh_vid = softif_neigh_vid_get(bat_priv, vid);
-	if (!softif_neigh_vid)
-		goto out;
-
-	spin_lock_bh(&bat_priv->softif_neigh_lock);
-
-	if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
-		new_neigh = NULL;
-
-	curr_neigh = rcu_dereference_protected(softif_neigh_vid->softif_neigh,
-					       1);
-	rcu_assign_pointer(softif_neigh_vid->softif_neigh, new_neigh);
-
-	if ((curr_neigh) && (!new_neigh))
-		bat_dbg(DBG_ROUTES, bat_priv,
-			"Removing mesh exit point on vid: %d (prev: %pM).\n",
-			vid, curr_neigh->addr);
-	else if ((curr_neigh) && (new_neigh))
-		bat_dbg(DBG_ROUTES, bat_priv,
-			"Changing mesh exit point on vid: %d from %pM "
-			"to %pM.\n", vid, curr_neigh->addr, new_neigh->addr);
-	else if ((!curr_neigh) && (new_neigh))
-		bat_dbg(DBG_ROUTES, bat_priv,
-			"Setting mesh exit point on vid: %d to %pM.\n",
-			vid, new_neigh->addr);
-
-	if (curr_neigh)
-		softif_neigh_free_ref(curr_neigh);
-
-	spin_unlock_bh(&bat_priv->softif_neigh_lock);
-
-out:
-	if (softif_neigh_vid)
-		softif_neigh_vid_free_ref(softif_neigh_vid);
-}
-
-static void softif_neigh_vid_deselect(struct bat_priv *bat_priv,
-				      struct softif_neigh_vid *softif_neigh_vid)
-{
-	struct softif_neigh *curr_neigh;
-	struct softif_neigh *softif_neigh = NULL, *softif_neigh_tmp;
-	struct hard_iface *primary_if = NULL;
-	struct hlist_node *node;
-
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
-	/* find new softif_neigh immediately to avoid temporary loops */
-	rcu_read_lock();
-	curr_neigh = rcu_dereference(softif_neigh_vid->softif_neigh);
-
-	hlist_for_each_entry_rcu(softif_neigh_tmp, node,
-				 &softif_neigh_vid->softif_neigh_list,
-				 list) {
-		if (softif_neigh_tmp == curr_neigh)
-			continue;
-
-		/* we got a neighbor but its mac is 'bigger' than ours  */
-		if (memcmp(primary_if->net_dev->dev_addr,
-			   softif_neigh_tmp->addr, ETH_ALEN) < 0)
-			continue;
-
-		if (!atomic_inc_not_zero(&softif_neigh_tmp->refcount))
-			continue;
-
-		softif_neigh = softif_neigh_tmp;
-		goto unlock;
-	}
-
-unlock:
-	rcu_read_unlock();
-out:
-	softif_neigh_vid_select(bat_priv, softif_neigh, softif_neigh_vid->vid);
-
-	if (primary_if)
-		hardif_free_ref(primary_if);
-	if (softif_neigh)
-		softif_neigh_free_ref(softif_neigh);
-}
-
-int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
-{
-	struct net_device *net_dev = (struct net_device *)seq->private;
-	struct bat_priv *bat_priv = netdev_priv(net_dev);
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct softif_neigh *softif_neigh;
-	struct hard_iface *primary_if;
-	struct hlist_node *node, *node_tmp;
-	struct softif_neigh *curr_softif_neigh;
-	int ret = 0, last_seen_secs, last_seen_msecs;
-
-	primary_if = 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 != IF_ACTIVE) {
-		ret = seq_printf(seq, "BATMAN mesh %s "
-				 "disabled - primary interface not active\n",
-				 net_dev->name);
-		goto out;
-	}
-
-	seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name);
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(softif_neigh_vid, node,
-				 &bat_priv->softif_neigh_vids, list) {
-		seq_printf(seq, "     %-15s %s on vid: %d\n",
-			   "Originator", "last-seen", softif_neigh_vid->vid);
-
-		curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
-
-		hlist_for_each_entry_rcu(softif_neigh, node_tmp,
-					 &softif_neigh_vid->softif_neigh_list,
-					 list) {
-			last_seen_secs = jiffies_to_msecs(jiffies -
-						softif_neigh->last_seen) / 1000;
-			last_seen_msecs = jiffies_to_msecs(jiffies -
-						softif_neigh->last_seen) % 1000;
-			seq_printf(seq, "%s %pM  %3i.%03is\n",
-				   curr_softif_neigh == softif_neigh
-				   ? "=>" : "  ", softif_neigh->addr,
-				   last_seen_secs, last_seen_msecs);
-		}
-
-		if (curr_softif_neigh)
-			softif_neigh_free_ref(curr_softif_neigh);
-
-		seq_printf(seq, "\n");
-	}
-	rcu_read_unlock();
-
-out:
-	if (primary_if)
-		hardif_free_ref(primary_if);
-	return ret;
-}
-
-void softif_neigh_purge(struct bat_priv *bat_priv)
-{
-	struct softif_neigh *softif_neigh, *curr_softif_neigh;
-	struct softif_neigh_vid *softif_neigh_vid;
-	struct hlist_node *node, *node_tmp, *node_tmp2;
-	int do_deselect;
-
-	rcu_read_lock();
-	hlist_for_each_entry_rcu(softif_neigh_vid, node,
-				 &bat_priv->softif_neigh_vids, list) {
-		if (!atomic_inc_not_zero(&softif_neigh_vid->refcount))
-			continue;
-
-		curr_softif_neigh = softif_neigh_get_selected(softif_neigh_vid);
-		do_deselect = 0;
-
-		spin_lock_bh(&bat_priv->softif_neigh_lock);
-		hlist_for_each_entry_safe(softif_neigh, node_tmp, node_tmp2,
-					  &softif_neigh_vid->softif_neigh_list,
-					  list) {
-			if ((!time_after(jiffies, softif_neigh->last_seen +
-				msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) &&
-			    (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE))
-				continue;
-
-			if (curr_softif_neigh == softif_neigh) {
-				bat_dbg(DBG_ROUTES, bat_priv,
-					"Current mesh exit point on vid: %d "
-					"'%pM' vanished.\n",
-					softif_neigh_vid->vid,
-					softif_neigh->addr);
-				do_deselect = 1;
-			}
-
-			hlist_del_rcu(&softif_neigh->list);
-			softif_neigh_free_ref(softif_neigh);
-		}
-		spin_unlock_bh(&bat_priv->softif_neigh_lock);
-
-		/* soft_neigh_vid_deselect() needs to acquire the
-		 * softif_neigh_lock */
-		if (do_deselect)
-			softif_neigh_vid_deselect(bat_priv, softif_neigh_vid);
-
-		if (curr_softif_neigh)
-			softif_neigh_free_ref(curr_softif_neigh);
-
-		softif_neigh_vid_free_ref(softif_neigh_vid);
-	}
-	rcu_read_unlock();
-
-	spin_lock_bh(&bat_priv->softif_neigh_vid_lock);
-	hlist_for_each_entry_safe(softif_neigh_vid, node, node_tmp,
-				  &bat_priv->softif_neigh_vids, list) {
-		if (!hlist_empty(&softif_neigh_vid->softif_neigh_list))
-			continue;
-
-		hlist_del_rcu(&softif_neigh_vid->list);
-		softif_neigh_vid_free_ref(softif_neigh_vid);
-	}
-	spin_unlock_bh(&bat_priv->softif_neigh_vid_lock);
-
-}
-
-static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
-			       short vid)
-{
-	struct bat_priv *bat_priv = netdev_priv(dev);
-	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
-	struct batman_ogm_packet *batman_ogm_packet;
-	struct softif_neigh *softif_neigh = NULL;
-	struct hard_iface *primary_if = NULL;
-	struct softif_neigh *curr_softif_neigh = NULL;
-
-	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
-		batman_ogm_packet = (struct batman_ogm_packet *)
-					(skb->data + ETH_HLEN + VLAN_HLEN);
-	else
-		batman_ogm_packet = (struct batman_ogm_packet *)
-							(skb->data + ETH_HLEN);
-
-	if (batman_ogm_packet->version != COMPAT_VERSION)
-		goto out;
-
-	if (batman_ogm_packet->packet_type != BAT_OGM)
-		goto out;
-
-	if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
-		goto out;
-
-	if (is_my_mac(batman_ogm_packet->orig))
-		goto out;
-
-	softif_neigh = softif_neigh_get(bat_priv, batman_ogm_packet->orig, vid);
-	if (!softif_neigh)
-		goto out;
-
-	curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
-	if (curr_softif_neigh == softif_neigh)
-		goto out;
-
-	primary_if = primary_if_get_selected(bat_priv);
-	if (!primary_if)
-		goto out;
-
-	/* we got a neighbor but its mac is 'bigger' than ours  */
-	if (memcmp(primary_if->net_dev->dev_addr,
-		   softif_neigh->addr, ETH_ALEN) < 0)
-		goto out;
-
-	/* close own batX device and use softif_neigh as exit node */
-	if (!curr_softif_neigh) {
-		softif_neigh_vid_select(bat_priv, softif_neigh, vid);
-		goto out;
-	}
-
-	/* switch to new 'smallest neighbor' */
-	if (memcmp(softif_neigh->addr, curr_softif_neigh->addr, ETH_ALEN) < 0)
-		softif_neigh_vid_select(bat_priv, softif_neigh, vid);
-
-out:
-	kfree_skb(skb);
-	if (softif_neigh)
-		softif_neigh_free_ref(softif_neigh);
-	if (curr_softif_neigh)
-		softif_neigh_free_ref(curr_softif_neigh);
-	if (primary_if)
-		hardif_free_ref(primary_if);
-	return;
-}
-
 static int interface_open(struct net_device *dev)
 {
 	netif_start_queue(dev);
@@ -562,7 +128,6 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 	struct hard_iface *primary_if = NULL;
 	struct bcast_packet *bcast_packet;
 	struct vlan_ethhdr *vhdr;
-	struct softif_neigh *curr_softif_neigh = NULL;
 	unsigned int header_len = 0;
 	int data_len = skb->len, ret;
 	short vid = -1;
@@ -583,17 +148,8 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 
 		/* fall through */
 	case ETH_P_BATMAN:
-		softif_batman_recv(skb, soft_iface, vid);
-		goto end;
-	}
-
-	/**
-	 * if we have a another chosen mesh exit node in range
-	 * it will transport the packets to the mesh
-	 */
-	curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
-	if (curr_softif_neigh)
 		goto dropped;
+	}
 
 	/* Register the client MAC in the transtable */
 	tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
@@ -675,8 +231,6 @@ dropped:
 dropped_freed:
 	bat_priv->stats.tx_dropped++;
 end:
-	if (curr_softif_neigh)
-		softif_neigh_free_ref(curr_softif_neigh);
 	if (primary_if)
 		hardif_free_ref(primary_if);
 	return NETDEV_TX_OK;
@@ -687,12 +241,9 @@ void interface_rx(struct net_device *soft_iface,
 		  int hdr_size)
 {
 	struct bat_priv *bat_priv = netdev_priv(soft_iface);
-	struct unicast_packet *unicast_packet;
 	struct ethhdr *ethhdr;
 	struct vlan_ethhdr *vhdr;
-	struct softif_neigh *curr_softif_neigh = NULL;
 	short vid = -1;
-	int ret;
 
 	/* check if enough space is available for pulling, and pull */
 	if (!pskb_may_pull(skb, hdr_size))
@@ -716,30 +267,6 @@ void interface_rx(struct net_device *soft_iface,
 		goto dropped;
 	}
 
-	/**
-	 * if we have a another chosen mesh exit node in range
-	 * it will transport the packets to the non-mesh network
-	 */
-	curr_softif_neigh = softif_neigh_vid_get_selected(bat_priv, vid);
-	if (curr_softif_neigh) {
-		skb_push(skb, hdr_size);
-		unicast_packet = (struct unicast_packet *)skb->data;
-
-		if ((unicast_packet->packet_type != BAT_UNICAST) &&
-		    (unicast_packet->packet_type != BAT_UNICAST_FRAG))
-			goto dropped;
-
-		skb_reset_mac_header(skb);
-
-		memcpy(unicast_packet->dest,
-		       curr_softif_neigh->addr, ETH_ALEN);
-		ret = route_unicast_packet(skb, recv_if);
-		if (ret == NET_RX_DROP)
-			goto dropped;
-
-		goto out;
-	}
-
 	/* skb->dev & skb->pkt_type are set here */
 	if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
 		goto dropped;
@@ -765,8 +292,6 @@ void interface_rx(struct net_device *soft_iface,
 dropped:
 	kfree_skb(skb);
 out:
-	if (curr_softif_neigh)
-		softif_neigh_free_ref(curr_softif_neigh);
 	return;
 }
 
diff --git a/soft-interface.h b/soft-interface.h
index 001546f..694f0f6 100644
--- a/soft-interface.h
+++ b/soft-interface.h
@@ -23,8 +23,6 @@
 #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
 
 int my_skb_head_push(struct sk_buff *skb, unsigned int len);
-int softif_neigh_seq_print_text(struct seq_file *seq, void *offset);
-void softif_neigh_purge(struct bat_priv *bat_priv);
 void interface_rx(struct net_device *soft_iface,
 		  struct sk_buff *skb, struct hard_iface *recv_if,
 		  int hdr_size);
diff --git a/types.h b/types.h
index ab8d0fe..db6ae2b 100644
--- a/types.h
+++ b/types.h
@@ -173,7 +173,6 @@ struct bat_priv {
 	struct hlist_head forw_bat_list;
 	struct hlist_head forw_bcast_list;
 	struct hlist_head gw_list;
-	struct hlist_head softif_neigh_vids;
 	struct list_head tt_changes_list; /* tracks changes in a OGM int */
 	struct list_head vis_send_list;
 	struct hashtable_t *orig_hash;
@@ -190,8 +189,6 @@ struct bat_priv {
 	spinlock_t gw_list_lock; /* protects gw_list and curr_gw */
 	spinlock_t vis_hash_lock; /* protects vis_hash */
 	spinlock_t vis_list_lock; /* protects vis_info::recv_list */
-	spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */
-	spinlock_t softif_neigh_vid_lock; /* protects soft-interface vid list */
 	atomic_t num_local_tt;
 	/* Checksum of the local table, recomputed before sending a new OGM */
 	atomic_t tt_crc;
@@ -325,22 +322,4 @@ struct recvlist_node {
 	uint8_t mac[ETH_ALEN];
 };
 
-struct softif_neigh_vid {
-	struct hlist_node list;
-	struct bat_priv *bat_priv;
-	short vid;
-	atomic_t refcount;
-	struct softif_neigh __rcu *softif_neigh;
-	struct rcu_head rcu;
-	struct hlist_head softif_neigh_list;
-};
-
-struct softif_neigh {
-	struct hlist_node list;
-	uint8_t addr[ETH_ALEN];
-	unsigned long last_seen;
-	atomic_t refcount;
-	struct rcu_head rcu;
-};
-
 #endif /* _NET_BATMAN_ADV_TYPES_H_ */
-- 
1.7.7.1


^ permalink raw reply related

* [B.A.T.M.A.N.] [RFC 00/11] bridge loop avoidance II
From: Simon Wunderlich @ 2011-10-30 22:51 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Simon Wunderlich

This series of patches is a request for comments on the redesigned
bridge loop avoidance. The general concept is described in the wiki
[1]. I've already performed a few testcases [2] which worked fine in
my kvm environment. No crashes while running or unloading the 
extension either.

The last patch in the series uses the cached address of the primary
interface (the originator address known through the mesh) to save some
code at various positions, there may be side effects I don't see
however (e.g. implicit checking whether the module was configured
correctly was removed).

Marek already pointed quite a few issues out, these changes are
reflected in the respective commit logs. These commit comments will
be removed in the final version.

Any comments and suggestions are appreciated. 

Thanks
    Simon

[1] http://www.open-mesh.org/wiki/batman-adv/Bridge-loop-avoidance-II
[2] http://www.open-mesh.org/wiki/batman-adv/Bridge-loop-avoidance-Testcases

Simon Wunderlich (11):
  batman-adv: remove old bridge loop avoidance code
  batman-adv: add basic bridge loop avoidance code
  batman-adv: make bridge loop avoidance switchable
  batman-adv: export claim tables through debugfs
  batman-adv: allow multiple entries in tt_global_entries
  batman-adv: don't let backbone gateways exchange tt entries
  batman-adv: add broadcast duplicate check
  batman-adv: drop STP over batman
  batman-adv: form groups in the bridge loop avoidance
  batman-adv: Update README and sysfs description
  [RFC] batman-adv: get primaries address through bat_priv->own_orig

 Makefile.kbuild         |    1 +
 README                  |   28 +-
 bat_debugfs.c           |   18 +-
 bat_sysfs.c             |    4 +-
 bridge_loop_avoidance.c | 1509 +++++++++++++++++++++++++++++++++++++++++++++++
 bridge_loop_avoidance.h |   34 ++
 compat.c                |   16 +-
 compat.h                |    3 +-
 hard-interface.c        |    8 +-
 icmp_socket.c           |   12 +-
 main.c                  |    9 +-
 main.h                  |    9 +-
 originator.c            |    3 +-
 packet.h                |   16 +
 routing.c               |   41 +-
 soft-interface.c        |  490 +---------------
 soft-interface.h        |    2 -
 sysfs-class-net-mesh    |    9 +
 translation-table.c     |  366 ++++++++----
 types.h                 |   70 ++-
 unicast.c               |    9 +-
 vis.c                   |   20 +-
 22 files changed, 1965 insertions(+), 712 deletions(-)
 create mode 100644 bridge_loop_avoidance.c
 create mode 100644 bridge_loop_avoidance.h

-- 
1.7.7.1


^ permalink raw reply

* [Xenomai-help] which skin to use
From: Łukasz Sacha @ 2011-10-30 22:47 UTC (permalink / raw)
  To: xenomai

Hi,
I'm working on a device that will process several input signals (2
analog, about 4 digital and 1 over serial interface) do some
calculations and control 4 uarts. It will also write some log data to
a file on an sd card.
It will probably be a single process working in an infinite loop,
regularly, say 50 times per second or more.
I'm a total beginner as it comes to RT and xenomai. I have some
experience in wrinting programs in C/C++ for linux.
Which API should do you think will be good for me to start with?
Which would be better for the application that I want to write?

Thanks,
--
Łukasz Dragilla Sacha


^ permalink raw reply

* Re: [Qemu-devel] Patch for ui/cocoa.m
From: Andreas Färber @ 2011-10-30 22:45 UTC (permalink / raw)
  To: Juan Pineda; +Cc: aliguori, qemu-devel
In-Reply-To: <0B40C867-80E6-4FE1-A346-CAA807378745@logician.com>

Am 18.10.2011 16:35, schrieb Juan Pineda:
>>> What command line do you use? If using the right arguments you
>>> shouldn't see a window at all. Are you maybe using -drive instead of
>>> -hda and that is not yet handled correctly?
> 
> The boot volume dialog appears only when a hard disk file is not supplied on the command line. I would think the failure of the dialog to close is not unique to Lion. However in prior OS releases it probably does not present a problem as the main window can be raised above the dialog.

If that were the case I would see it as worth fixing there, too. :)

>>> Apart from this issue, is it working correctly for you?

> However building the main branch (with flags as above) does not work. The build fails with error about redefinition of uint16 in fpu/softfloat.h. If that is fixed the build completes. But trying to run qemu-system-i386 quits:
> 
>> $ i386-softmmu/qemu-system-i386 -hda ~/Downloads/linux-0.2.img
>>
>> GThread-ERROR **: GThread system may only be initialized once.
>> aborting...
>> Abort trap: 6

That's what I'm seeing, too, so I don't feel comfortable committing this
patch now. It compiles file, but it crashes either way with a message
similar to the above, so I don't see an improvement (yet).

If you could pinpoint where this error stems from (e.g., single-stepping
in gdb) that might help getting it fixed.

Thanks,
Andreas

^ permalink raw reply

* [PATCH] Numerous typo/grammatical/URL fixes to Yocto Quick Start guide.
From: Robert P. J. Day @ 2011-10-30 22:44 UTC (permalink / raw)
  To: Yocto discussion list


A number of cosmetic fixes for the Yocto Quick Start Guide:

  * spelling/grammar fixes
  * Updating URLs to point at new location of downloads/toolchains.
  * Correct name of toolchains, prefix of "yocto" -> "poky"

... and more.

Signed-off-by: Robert P. J. Day <rpjday@crashcourse.ca>

---

  Not quite done with the QS guide, more cosmetic cleanup coming
shortly but it would be nice if Scott could apply this stuff unless
someone has objections.

  I made it as far as the kernel section -- that's going to need a
bit of tidying up as well.


diff --git a/documentation/yocto-project-qs/yocto-project-qs.xml b/documentation/yocto-project-qs/yocto-project-qs.xml
index 41da903..6c140e0 100644
--- a/documentation/yocto-project-qs/yocto-project-qs.xml
+++ b/documentation/yocto-project-qs/yocto-project-qs.xml
@@ -130,7 +130,7 @@
             <para>A host system running a supported Linux distribution (i.e. recent releases of
                 Fedora, openSUSE, Debian, and Ubuntu).
                 If the host system supports multiple cores and threads, you can configure the
-                Yocto Project build system to increase the time needed to build images
+                Yocto Project build system to reduce the time needed to build images
                 significantly.
             </para>
         </listitem>
@@ -149,7 +149,7 @@
             The Yocto Project team is continually verifying more and more Linux
             distributions with each release.
             In general, if you have the current release minus one of the following
-            distributions you should no problems.
+            distributions you should have no problems.
             <itemizedlist>
                 <listitem><para>Ubuntu</para></listitem>
                 <listitem><para>Fedora</para></listitem>
@@ -275,10 +275,10 @@

     <itemizedlist>
         <listitem>
-            <para>Build an image and run it in the QEMU emulator</para>
+            <para>Build an image and run it in the QEMU emulator, or</para>
         </listitem>
         <listitem>
-            <para>Or, use a pre-built image and run it in the QEMU emulator</para>
+            <para>Use a pre-built image and run it in the QEMU emulator.</para>
         </listitem>
     </itemizedlist>

@@ -323,7 +323,7 @@

          <para>
              <literallayout class='monospaced'>
-     $ wget http://www.yoctoproject.org/downloads/poky/poky-edison-6.0.tar.bz2
+     $ wget http://downloads.yoctoproject.org/releases/yocto/yocto-1.1/poky-edison-6.0.tar.bz2
      $ tar xjf poky-edison-6.0.tar.bz2
      $ source poky-edison-6.0/oe-init-build-env edison-6.0-build
              </literallayout>
@@ -331,9 +331,8 @@

          <tip><para>
              To help conserve disk space during builds, you can add the following statement
-             to your <filename>local.conf</filename> file in the Yocto Project build
-             directory, which for this example
-             is <filename>edison-6.0-build</filename>.
+             to your project's configuration file, which for this example
+             is <filename>edison-6.0-build/conf/local.conf</filename>.
              Adding this statement deletes the work directory used for building a package
              once the package is built.
              <literallayout class='monospaced'>
@@ -342,15 +341,14 @@
          </para></tip>

          <itemizedlist>
-             <listitem><para>The first command retrieves the Yocto Project release tarball from the
-                 source repositories.
-                 Notice, the example uses the <filename>wget</filename> shell command.
-                 Alternatively, you can go to the
-                 <ulink url='http://www.yoctoproject.org'>Yocto Project website</ulink> downloads
-                 area to retrieve the tarball.</para></listitem>
-             <listitem><para>The second command extracts the files from the tarball and places
-                 them into a directory named <filename>poky-edison-6.0</filename> in the current
-                 directory.
+             <listitem><para>The first command above retrieves the Yocto Project
+                 release tarball from the source repositories using the
+                 <filename>wget</filename> command.  Alternatively, you can go to the
+                 <ulink url='http://downloads.yoctoproject.org'>Yocto Project website
+                 downloads area</ulink> to retrieve the tarball.</para></listitem>
+             <listitem><para>The second command extracts the files from the tarball
+                 and places them into a directory named <filename>poky-edison-6.0</filename>
+                 in the current directory.
                </para></listitem>
              <listitem><para>The third command runs the Yocto Project environment setup script.
                  Running this script defines Yocto Project build environment settings needed to
@@ -364,19 +362,18 @@
                  </para></listitem>
          </itemizedlist>
          <para>
-             Take some time to examine your <filename>conf/local.conf</filename> file found in the
-             Yocto Project build directory.
-             The defaults in the <filename>local.conf</filename> should work fine.
-             However, there are some variables of interest at which you might look.
+             Take some time to examine the <filename>local.conf</filename> file
+             in your project's configuration directory.
+             The defaults in that file should work fine;
+             however, there are some variables of interest at which you might look.
          </para>

          <para>
              By default, the target architecture for the build is <filename>qemux86</filename>,
-             which is an image that can be used in the QEMU emulator and is targeted for an
-             <trademark class='registered'>Intel</trademark> 32-bit based architecture.
-             To change this default, edit the value of the <filename>MACHINE</filename> variable in the
-             <filename>conf/local.conf</filename> file in the build directory before
-             launching the build.
+             which produces an image that can be used in the QEMU emulator and is targeted at an
+             <trademark class='registered'>Intel</trademark> 32-bit architecture.
+             To change this default, edit the value of the <filename>MACHINE</filename>
+             variable in that file before launching the build.
          </para>

          <para>
@@ -384,12 +381,12 @@
              <ulink url='http://www.yoctoproject.org/docs/1.1/poky-ref-manual/poky-ref-manual.html#var-BB_NUMBER_THREADS'><filename>BB_NUMBER_THREADS</filename></ulink> and the
              <ulink url='http://www.yoctoproject.org/docs/1.1/poky-ref-manual/poky-ref-manual.html#var-PARALLEL_MAKE'><filename>PARALLEL_MAKE</filename></ulink> variables.
              By default, these variables are commented out.
-             However, if you have a multi-core CPU you might want to remove the comment
-             and set the variable
+             However, if you have a multi-core CPU you might want to uncomment
+             these lines and set the variable
              <filename>BB_NUMBER_THREADS</filename> equal to twice the number of your
              host's processor cores.
-             Also, you could set the variable <filename>PARALLEL_MAKE</filename> equal to the number
-             of processor cores.
+             Also, you could set the variable <filename>PARALLEL_MAKE</filename> equal
+             to 1.5 * the number of processor cores.
              Setting these variables can significantly shorten your build time.
          </para>

@@ -471,10 +468,10 @@
             <title>Installing the Toolchain</title>
             <para>
                 You can download the pre-built toolchain, which includes the <filename>runqemu</filename>
-                script and support files, from
-                <ulink url='http://yoctoproject.org/downloads/yocto-1.1/toolchain/'></ulink>.
+                script and support files, from the appropriate directory under
+                <ulink url='http://downloads.yoctoproject.org/releases/yocto/yocto-1.1/toolchain/'></ulink>.
                 Toolchains are available for 32-bit and 64-bit development systems from the
-                <filename>i686</filename> and <filename>x86_64</filename> folders, respectively.
+                <filename>i686</filename> and <filename>x86_64</filename> directories, respectively.
                 Each type of development system supports five target architectures.
                 The tarball files are named such that a string representing the host system appears
                 first in the filename and then is immediately followed by a string representing
@@ -482,7 +479,7 @@
             </para>

             <literallayout class='monospaced'>
-     yocto-eglibc&lt;<emphasis>host_system</emphasis>&gt;-&lt;<emphasis>arch</emphasis>&gt;-toolchain-gmae-&lt;<emphasis>release</emphasis>&gt;.tar.bz2
+     poky-eglibc-&lt;<emphasis>host_system</emphasis>&gt;-&lt;<emphasis>arch</emphasis>&gt;-toolchain-gmae-&lt;<emphasis>release</emphasis>&gt;.tar.bz2

      Where:
          &lt;<emphasis>host_system</emphasis>&gt; is a string representing your development system:
@@ -500,7 +497,7 @@
             </para>

             <literallayout class='monospaced'>
-     yocto-eglibc-x86_64-i586-toolchain-gmae-1.1.tar.bz2
+     poky-eglibc-x86_64-i586-toolchain-gmae-1.1.tar.bz2
             </literallayout>

             <para>
@@ -513,7 +510,7 @@
             <para>
                 <literallayout class='monospaced'>
      $ cd /
-     $ sudo tar -xvjf ~/toolchains/yocto-eglibc-x86_64-i586-toolchain-gmae-1.1.tar.bz2
+     $ sudo tar -xvjf ~/toolchains/poky-eglibc-x86_64-i586-toolchain-gmae-1.1.tar.bz2
                 </literallayout>
             </para>

@@ -522,7 +519,7 @@
                 "<ulink url='http://www.yoctoproject.org/docs/1.1/adt-manual/adt-manual.html#using-an-existing-toolchain-tarball'>Using a Cross-Toolchain Tarball</ulink>" and
                 "<ulink url='http://www.yoctoproject.org/docs/1.1/adt-manual/adt-manual.html#using-the-toolchain-from-within-the-build-tree'>Using BitBake and the Yocto Project Build Tree</ulink>" sections in
                 <ulink url='http://www.yoctoproject.org/docs/1.1/adt-manual/adt-manual.html'>The Yocto Project
-                Application Development Toolkit (ADT) Development Manual</ulink>.
+                Application Development Toolkit (ADT) User's Guide</ulink>.
             </para>
         </section>


-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================


^ permalink raw reply related

* [GIT PULL] GIC DT binding support
From: Arnd Bergmann @ 2011-10-30 22:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4EAB1BFF.3070406@gmail.com>

On Friday 28 October 2011, Rob Herring wrote:
> Here's an updated pull request to fix missing export.h include. Now it's
> also dependent on module.h clean-up branch:
> 
> git://openlinux.windriver.com/people/paulg/linux-next for-sfr
> 
> 
> The following changes since commit fa1d6d372245a160eecf5f57d64d2b21ea248e08:
> 
>   Merge branch 'for-sfr' of
> git://openlinux.windriver.com/people/paulg/linux-next into HEAD
> (2011-10-28 15:51:07 -0500)
> 
> are available in the git repository at:
> 
>   git://sources.calxeda.com/kernel/linux.git gic-dt

I've pulled it and am now trying to clean up the mess resulting from
having the previous version in a number of branches already.

Can you check that the highbank/soc branch is ok this time?

	Arnd

^ permalink raw reply

* (unknown), 
From: Mrs Mellisa Lewis. @ 2011-10-30 22:33 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm@fengv.com) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* (unknown), 
From: Mrs Mellisa Lewis. @ 2011-10-30 22:33 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm-N/I+a4o3xEsAvxtiuMwx3w@public.gmane.org) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* (no subject)
From: Mrs Mellisa Lewis. @ 2011-10-30 22:33 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm@fengv.com) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* (unknown), 
From: Mrs Mellisa Lewis. @ 2011-10-30 22:33 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm@fengv.com) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* Re: [PATCH v2] GIO bus support for SGI IP22/28
From: Thomas Bogendoerfer @ 2011-10-30 22:34 UTC (permalink / raw)
  To: Joshua Kinard; +Cc: linux-mips, linux-fbdev, ralf, FlorianSchandinat
In-Reply-To: <4EADB701.9040506@gentoo.org>

On Sun, Oct 30, 2011 at 04:43:45PM -0400, Joshua Kinard wrote:
> Does this handle any glue logic for add-on NIC cards found for Indy and I2?

no, but it will make live a lot easier, because address and interrupts don't
need to be probed by the driver. Right now interrupts are on my todo, since
there is some weirdness between guiness and fullhouse boxes...

>  I have a G130 Phobus and a rare ThunderLAN card in my Indy.  The Phobus has
> an Altera GIO/PCI glue chip.  Not sure about the ThunderLAN.  Both have
> normal driver support in the kernel (Phobus is just a Tulip chip).

it still needs something to setup the PCI bus on the card and issue
the probing. The problem with the Tulip Phobos cards is, that they
messed up the endianess, so that none of the Linux Tulip drivers will
work out of the box...

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply

* Re: [PATCH v2] GIO bus support for SGI IP22/28
From: Thomas Bogendoerfer @ 2011-10-30 22:34 UTC (permalink / raw)
  To: Joshua Kinard; +Cc: linux-mips, linux-fbdev, ralf, FlorianSchandinat
In-Reply-To: <4EADB701.9040506@gentoo.org>

On Sun, Oct 30, 2011 at 04:43:45PM -0400, Joshua Kinard wrote:
> Does this handle any glue logic for add-on NIC cards found for Indy and I2?

no, but it will make live a lot easier, because address and interrupts don't
need to be probed by the driver. Right now interrupts are on my todo, since
there is some weirdness between guiness and fullhouse boxes...

>  I have a G130 Phobus and a rare ThunderLAN card in my Indy.  The Phobus has
> an Altera GIO/PCI glue chip.  Not sure about the ThunderLAN.  Both have
> normal driver support in the kernel (Phobus is just a Tulip chip).

it still needs something to setup the PCI bus on the card and issue
the probing. The problem with the Tulip Phobos cards is, that they
messed up the endianess, so that none of the Linux Tulip drivers will
work out of the box...

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply

* where does that "50G" disk space figure come from in QS guide?
From: Robert P. J. Day @ 2011-10-30 22:33 UTC (permalink / raw)
  To: Yocto discussion list


  QS guide suggests build process using sato will use about 50G of
disk space.  where does that figure come from?  i just did a configure
and build of core-image-sato for beagleboard on my 64-bit ubuntu 11.10
system and it cost me about 3.5G for the tarball download directory,
and just under 28G for the entire build directory.  so where does 50G
come from?  and that was *without* economizing using "INHERIT +=
rm_work".

rday

p.s.  followup to post earlier this week, building for beagleboard on
64-bit ubuntu 11.10 seems to work just fine.  cranking up the
parallelism did a full build in less than 2 hours, given that
all tarballs were already downloaded.

p.p.s.  what is the process for validating a new distro/version?  i
have lots of spare cycles, i can run through a few builds on my
system.


^ permalink raw reply

* Re: Re: HT (Hyper Threading) aware process scheduling doesn't work as it should
From: Artem S. Tashkinov @ 2011-10-30 22:29 UTC (permalink / raw)
  To: arjan; +Cc: linux-kernel
In-Reply-To: <20111030151256.27b2b20e@infradead.org>

> On Oct 31, 2011, Arjan van de Ven wrote:
>
> On Sun, 30 Oct 2011 19:57:12 +0000 (GMT)
> "Artem S. Tashkinov" wrote:
>
> > Hello,
> >
> > It's known that if you want to reach maximum performance on HT
> > enabled Intel CPUs you should distribute the load evenly between
> > physical cores, and when you have loaded all of them you should then
> > load the remaining virtual cores.
>
> this is a bold statement, and patently false if you have to threads of
> one process that heavily share data between eachother...
> (but true for more independent workloads)

In my initial message I was talking about completely unrelated tasks/
processes which share no data/instructions/whatever else. You don't
need to trust my test case as you can carry out this test on your own.

I have asked quite a lot of people to do that and a lot of them see this
unfortunate pattern. 

^ permalink raw reply

* Re: [dm-crypt] please HELP - can't acces encrypted LVM after linux reinstallation.
From: Jonas Meurer @ 2011-10-30 22:25 UTC (permalink / raw)
  To: dm-crypt
In-Reply-To: <CAP8O3oMseYV46HOg1Uu3L7hb3NFZWf-j10cCqyHUki4K-Ns2Sw@mail.gmail.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Aleksander,

Am 30.10.2011 19:56, schrieb Aleksander Swirski:
> I will also try to push this info to the debian devs. I'm not sure
> how to do that properly (hint appreciated). I know, that the route
> of installation I took is not a common one, but a simple warning
> would suffice to avoid this kind of trouble. After all my encrypted
> LVM and specifically the /home partition within LVM wasn't listed
> among those, which are to be erased at any point during the
> installation. (I marked them with - K - keep the data)

I guess that you selected to configure the device which contained the
LVM volume group as new encrypted device. Then you where asked for the
new passphrase twice, and a new LUKS header was written to the device,
overwriting the old LUKS header. That way you shredded all the
encrypted data on that device, regardless what it was.

The partitions you marked as "keep the data" weren't overwritten, just
the LUKS header of underlying device was overwritten.

I agree, that a warning in the Debian Installer is a good idea, but to
be honest, there's already a big fat warning:

> _Description: Really erase the data on ${DEVICE}? The data on
> ${DEVICE} will be overwritten with random data. It can no longer be
> recovered after this step has completed. This is the last 
> opportunity to abort the erase.

(from
http://anonscm.debian.org/gitweb/?p=d-i/partman-crypto.git;a=blob;f=debian/partman-crypto.templates)

If you like to propose changes to the (warnings in the) process of
configuring encrypted volumes during installation of Debian, feel free
to discuss this on debian-boot@lists.debian.org. You might as well
take a look at the following page:
http://wiki.debian.org/DebianInstaller/PartmanCrypto

Greetings,
 jonas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJOrc7tAAoJEFJi5/9JEEn+bo4P/0vX3AxnpXzWO3NUvYW2wh6H
k7v8Dhx6Rw5HXttHuF8JSypkvcHuLfWyGLq0J4qlsw4GvK/cPtwdCuSe//uJvqSB
4Z6qj55E/3/M+aEBMzT9oBeZ5DVGPp0+76VWFNijGzHYMoT4YYm0pZBsmfZ7U2RJ
+7xFyGP0d7oXJIqoW8aUyufgdYnRNdcZdJtY27XHgKW1m9ytllIuK0h7hl410/L0
vy2t4IqSlO5Uko1/bOf3FETNkBRTUl4T2jWMP3dEpNMRobB1ZH5I5menXWSwzgR9
c2QWRkwQ8iUsAdakofnl9O1jhtw3Z9MKxHQbnxh32oNuS5Aaf5xxfiI7jXf3yY/L
GUKyIOa5nGtNtwUt4l0RTJAKoyY2J2KtBJm+JL51tQ3q/iyZsfRLVmyczlkzKUhj
vMKgSzhV8/IyQ/snqftAMqmRXYgaOE3qDCe8MR+EChIFwX2Zr+eRWdRzVFDjQ0kP
Cyc6Yw3TrthD8GuWWxU93tE3YMVxgI76+lDk/LBLZjviMTEfkR5e+gmuoff+Xdta
aBYek7loOjkqb+gJ6qeqAKuDLAZnw/BmHfgpYQpatdSeiV6jpGPkGMbYTwDHLlXR
rE72FJe1emdcDWQ6TE8SP+6KW22HirBPD5q6DPqJ2Oxcxx+AotXeLvDpnhd9S5b2
fDNHacCUklPyCeH81nsH
=PLsS
-----END PGP SIGNATURE-----

^ permalink raw reply

* (unknown), 
From: Mrs Mellisa Lewis. @ 2011-10-30 22:24 UTC (permalink / raw)




Contact My Lawyer For More Details,!! Barr jay mchenry for  
$14,258,000.00 tell him that i have will this money to  
you.Ref:(JJ/MMS/953/5015/GwrI/316us/uk For charity organization in  
your country.Email:(bjmfirm@fengv.com) Tel: +44703 183 9543,God Bless  
You Mrs Mellisa Lewis.

^ permalink raw reply

* [U-Boot] [PATCH 12/18] GCC4.6: Squash warnings in smsc95xx.c
From: Marek Vasut @ 2011-10-30 22:19 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <20111030220344.79B83180985A@gemini.denx.de>

> Dear Marek Vasut,
> 
> In message <201110302148.50367.marek.vasut@gmail.com> you wrote:
> > > > -	addr_lo = cpu_to_le32(*((u32 *)eth->enetaddr));
> > > > +	addr_lo = cpu_to_le32(*eth->enetaddr);
> > > 
> > > pretty sure this is wrong.  enetaddr is a uchar[], so your code now
> > > reads only 1 byte instead of 4.
> > > 
> > > that said, this code also seems to not be endian safe ...
> > > -mike
> > 
> > It's good anyone actually cares to properly review. Anyway, why does
> > noone actually care to fix all the damn warnings in their drivers before
> > submitting them in the first place ?!
> 
> GCC 4.6 has not been around that long.  Many people use less
> bleading-edge tool chains - for a good reason.

The problem is I saw this warning with gcc 4.2 too :-(

Cheers

^ permalink raw reply

* Re: [PATCH 00/13]  DocG3 fixes and write support
From: Marek Vasut @ 2011-10-30 22:18 UTC (permalink / raw)
  To: Mike Dunn
  Cc: dedekind1, dwmw2, tcech, linux-kernel, linux-mtd, Robert Jarzmik
In-Reply-To: <4EADC4F5.2050201@newsguy.com>

> Hi guys,
> 
> On 10/30/2011 02:04 AM, Robert Jarzmik wrote:
> > Marek Vasut <marek.vasut@gmail.com> writes:
> >> Hi,
> >> 
> >> can you sum up the situation about the another (docg4) driver for us not
> >> watching this too tightly? Was there any improvement/progress/... ?
> > 
> > The review is underway, my comments should be dealt with, and a V2 of the
> > patch should be sent. It's not in my hands.
> 
> I've been busy working on this, and should post a patch within the next few
> days.  Progress has been very good.  I still want to run the mtd tests in
> the kernel before posting the patch (except the torture test - I'm not
> ready to sacrifice my development Treo), but it continues to pass the
> nandtest userspace utility (part of mtd-utils) flawlessly, and a ubifs
> still appears to be working well.  The code is now in a much cleaner
> state.

CCing Tomas Cech, we might be able to get you a spare device if really 
necessary.
> 
> > The global view we have with Mike is that chips are different, and each
> > one deserves its own driver. Several registers are common, and the
> > docg3.h could become common.
> 
> Actually, I'm open on this.  My opinion is that they should share a header
> file for sure, because the register set largely overlaps.  To that end, my
> upcoming patch will adopt Robert's register #defines, with just a few
> additional ones that are G4 specific.
> 
> On the broader question of combined or separate drivers... a combined
> driver is certainly doable.  Each device would have to use its own set of
> low-level functions, but I think there's merit in combining them because
> it would provide a consistent interface with the mtd nand infrastructure
> code, which is rather messy.  But before that discussion can take place,
> the more fundamental question of whether or not the drivers should use the
> nand interface needs to be resolved.  I used the nand interface when I
> started on the G4 driver, because it *is* a nand device, and the legacy
> diskonchip.c driver was updated not long ago from a stand-alone driver to
> the nand interface.  I'm not knowledgeable enough of the mtd subsystem to
> argue for or against the nand interface, but the end result (once I
> invested the time slogging through nand_base.c) is fairly clean, with just
> a couple minor hacks to get around the fact that it doesnt have a
> "standard" nand controller.
> 
> Hopefully some mtd experts can share an opinion on this.
> 
> Thanks,
> Mike

^ permalink raw reply

* Re: [PATCH 00/13]  DocG3 fixes and write support
From: Marek Vasut @ 2011-10-30 22:18 UTC (permalink / raw)
  To: Mike Dunn
  Cc: Robert Jarzmik, linux-mtd, dwmw2, dedekind1, linux-kernel, tcech
In-Reply-To: <4EADC4F5.2050201@newsguy.com>

> Hi guys,
> 
> On 10/30/2011 02:04 AM, Robert Jarzmik wrote:
> > Marek Vasut <marek.vasut@gmail.com> writes:
> >> Hi,
> >> 
> >> can you sum up the situation about the another (docg4) driver for us not
> >> watching this too tightly? Was there any improvement/progress/... ?
> > 
> > The review is underway, my comments should be dealt with, and a V2 of the
> > patch should be sent. It's not in my hands.
> 
> I've been busy working on this, and should post a patch within the next few
> days.  Progress has been very good.  I still want to run the mtd tests in
> the kernel before posting the patch (except the torture test - I'm not
> ready to sacrifice my development Treo), but it continues to pass the
> nandtest userspace utility (part of mtd-utils) flawlessly, and a ubifs
> still appears to be working well.  The code is now in a much cleaner
> state.

CCing Tomas Cech, we might be able to get you a spare device if really 
necessary.
> 
> > The global view we have with Mike is that chips are different, and each
> > one deserves its own driver. Several registers are common, and the
> > docg3.h could become common.
> 
> Actually, I'm open on this.  My opinion is that they should share a header
> file for sure, because the register set largely overlaps.  To that end, my
> upcoming patch will adopt Robert's register #defines, with just a few
> additional ones that are G4 specific.
> 
> On the broader question of combined or separate drivers... a combined
> driver is certainly doable.  Each device would have to use its own set of
> low-level functions, but I think there's merit in combining them because
> it would provide a consistent interface with the mtd nand infrastructure
> code, which is rather messy.  But before that discussion can take place,
> the more fundamental question of whether or not the drivers should use the
> nand interface needs to be resolved.  I used the nand interface when I
> started on the G4 driver, because it *is* a nand device, and the legacy
> diskonchip.c driver was updated not long ago from a stand-alone driver to
> the nand interface.  I'm not knowledgeable enough of the mtd subsystem to
> argue for or against the nand interface, but the end result (once I
> invested the time slogging through nand_base.c) is fairly clean, with just
> a couple minor hacks to get around the fact that it doesnt have a
> "standard" nand controller.
> 
> Hopefully some mtd experts can share an opinion on this.
> 
> Thanks,
> Mike

^ permalink raw reply

* Re: Unable to restart reshape
From: Michael Busby @ 2011-10-30 22:15 UTC (permalink / raw)
  To: Alexander Kühn; +Cc: linux-raid
In-Reply-To: <20111030230215.Horde.zF2Mdpk8pphOrclnrmpTWiA@cakebox.homeunix.net>

>>>>>> I have a system the was doing a reshape from RAID5 to 6, the system
>>>>>> had to be powered off this morning and moved, upon restarting the
>>>>>> server i issued the following command to continue the reshape
>>>>>>
>>>>>>  mdadm -A /dev/md0 --backup-file=/home/md.backup
>>>>>>
>>>>>> i get back to following error
>>>>>>
>>>>>> mdadm: Failed to restore critical section for reshape, sorry.
>>>>>>
>>>>>> any idea why?
>>>>>>
>>>>>> before shutting down cat /proc/mdstat showed
>>>>>>
>>>>>> Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5]
>>>>>> [raid4] [raid10]
>>>>>> md0 : active raid6 sdf[0] sdb[6](S) sda[4] sdc[3] sde[2] sdd[1]
>>>>>>     7814055936 blocks super 1.0 level 6, 512k chunk, algorithm 18
>>>>>> [6/5] [UUUUU_]
>>>>>>     [==============>......]  reshape = 70.8% (1384415232/1953513984)
>>>>>> finish=3658.6min speed=2592K/sec
>>>>>>
>>>>>> but now it shows
>>>>>>
>>>>>> Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5]
>>>>>> [raid4] [raid10]
>>>>>> md0 : inactive sdc[3] sdb[6](S) sde[2] sdd[1] sdf[0]
>>>>>>      9767572240 blocks super 1.0
>>>>>>
>>>>>> i am totally confused, it seems to have lost a drive from the raid,
>>>>>> and the number of blocks is incorrect
>>>>>>
>>>>>
>>>>> issuing the following
>>>>>
>>>>>  mdadm -Avv --backup-file=/home/md.backup /dev/md0
>>>>>
>>>>> returns
>>>>>
>>>>>
>>>>> mdadm: looking for devices for /dev/md0
>>>>> mdadm: cannot open device /dev/sda5: Device or resource busy
>>>>> mdadm: /dev/sda5 has wrong uuid.
>>>>> mdadm: no RAID superblock on /dev/sda2
>>>>> mdadm: /dev/sda2 has wrong uuid.
>>>>> mdadm: cannot open device /dev/sda1: Device or resource busy
>>>>> mdadm: /dev/sda1 has wrong uuid.
>>>>> mdadm: cannot open device /dev/sda: Device or resource busy
>>>>> mdadm: /dev/sda has wrong uuid.
>>>>> mdadm: /dev/sdg is identified as a member of /dev/md0, slot -1.
>>>>> mdadm: /dev/sdf is identified as a member of /dev/md0, slot 4.
>>>>> mdadm: /dev/sdd is identified as a member of /dev/md0, slot 2.
>>>>> mdadm: /dev/sde is identified as a member of /dev/md0, slot 0.
>>>>> mdadm: /dev/sdc is identified as a member of /dev/md0, slot 1.
>>>>> mdadm: /dev/sdb is identified as a member of /dev/md0, slot 3.
>>>>> mdadm:/dev/md0 has an active reshape - checking if critical section
>>>>> needs to be restored
>>>>> mdadm: backup-metadata found on /home/md.backup but is not needed
>>>>> mdadm: Failed to find backup of critical section
>>>>> mdadm: Failed to restore critical section for reshape, sorry.
>>>>>
>>>>
>>>> seem the above was trying at use the wrong disks to assemble, so using
>>>> the following
>>>>
>>>> mdadm -Avv /dev/md0 --backup-file=/home/md.backup /dev/sd[abcdef]
>>>>
>>>>  mdadm: looking for devices for /dev/md0
>>>> mdadm: /dev/sda is identified as a member of /dev/md0, slot 4.
>>>> mdadm: /dev/sdb is identified as a member of /dev/md0, slot -1.
>>>> mdadm: /dev/sdc is identified as a member of /dev/md0, slot 3.
>>>> mdadm: /dev/sdd is identified as a member of /dev/md0, slot 1.
>>>> mdadm: /dev/sde is identified as a member of /dev/md0, slot 2.
>>>> mdadm: /dev/sdf is identified as a member of /dev/md0, slot 0.
>>>> mdadm:/dev/md0 has an active reshape - checking if critical section
>>>> needs to be restored
>>>> mdadm: backup-metadata found on /home/md.backup but is not needed
>>>> mdadm: Failed to find backup of critical section
>>>> mdadm: Failed to restore critical section for reshape, sorry.
>>>>
>>>
>>> have now upgraded to mdadm 3.2.2
>>>
>>> and get a little more info
>>>
>>> mdadm -Avv /dev/md0 --backup-file=/home/md.backup /dev/sd[abcdef]
>>>
>>> mdadm: looking for devices for /dev/md0
>>> mdadm: /dev/sda is identified as a member of /dev/md0, slot 4.
>>> mdadm: /dev/sdb is identified as a member of /dev/md0, slot -1.
>>> mdadm: /dev/sdc is identified as a member of /dev/md0, slot 3.
>>> mdadm: /dev/sdd is identified as a member of /dev/md0, slot 1.
>>> mdadm: /dev/sde is identified as a member of /dev/md0, slot 2.
>>> mdadm: /dev/sdf is identified as a member of /dev/md0, slot 0.
>>> mdadm: device 6 in /dev/md0 has wrong state in superblock, but /dev/sdb
>>> seems ok
>>> mdadm:/dev/md0 has an active reshape - checking if critical section
>>> needs to be restored
>>> mdadm: backup-metadata found on /home/md.backup but is not needed
>>> mdadm: Failed to find backup of critical section
>>> mdadm: Failed to restore critical section for reshape, sorry.
>>>
>>
>>
>> Ok, i dont know if this is the right thing to have done
>>
>> ~# mdadm -Avv --force /dev/md0 --backup-file=/home/md.backup
>> /dev/sd[abcdef]
>>
>> mdadm: looking for devices for /dev/md0
>> mdadm: /dev/sda is identified as a member of /dev/md0, slot 4.
>> mdadm: /dev/sdb is identified as a member of /dev/md0, slot -1.
>> mdadm: /dev/sdc is identified as a member of /dev/md0, slot 3.
>> mdadm: /dev/sdd is identified as a member of /dev/md0, slot 1.
>> mdadm: /dev/sde is identified as a member of /dev/md0, slot 2.
>> mdadm: /dev/sdf is identified as a member of /dev/md0, slot 0.
>> mdadm: clearing FAULTY flag for device 1 in /dev/md0 for /dev/sdb
>> mdadm: Marking array /dev/md0 as 'clean'
>> mdadm:/dev/md0 has an active reshape - checking if critical section
>> needs to be restored
>> mdadm: backup-metadata found on /home/md.backup but is not needed
>> mdadm: Failed to find backup of critical section
>> mdadm: Failed to restore critical section for reshape, sorry.
>>
>>
>> ~# mdadm -Avv /dev/md0 --backup-file=/home/md.backup /dev/sd[abcdef]
>>
>> mdadm: looking for devices for /dev/md0
>> mdadm: /dev/sda is identified as a member of /dev/md0, slot 4.
>> mdadm: /dev/sdb is identified as a member of /dev/md0, slot -1.
>> mdadm: /dev/sdc is identified as a member of /dev/md0, slot 3.
>> mdadm: /dev/sdd is identified as a member of /dev/md0, slot 1.
>> mdadm: /dev/sde is identified as a member of /dev/md0, slot 2.
>> mdadm: /dev/sdf is identified as a member of /dev/md0, slot 0.
>> mdadm:/dev/md0 has an active reshape - checking if critical section
>> needs to be restored
>> mdadm: restoring critical section
>> mdadm: added /dev/sdd to /dev/md0 as 1
>> mdadm: added /dev/sde to /dev/md0 as 2
>> mdadm: added /dev/sdc to /dev/md0 as 3
>> mdadm: added /dev/sda to /dev/md0 as 4
>> mdadm: no uptodate device for slot 5 of /dev/md0
>> mdadm: added /dev/sdb to /dev/md0 as -1
>> mdadm: added /dev/sdf to /dev/md0 as 0
>> mdadm: /dev/md0 has been started with 4 drives (out of 6) and 1 spare.
>>
>> ~# cat /proc/mdstat
>>
>> Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5]
>> [raid4] [raid10]
>> md0 : active raid6 sdf[0] sdb[6](S) sdc[3] sde[2] sdd[1]
>>      7814055936 blocks super 1.0 level 6, 512k chunk, algorithm 18
>> [6/4] [UUUU__]
>>      [==============>......]  reshape = 74.3% (1452929024/1953513984)
>> finish=2545.2min speed=3276K/sec
>>
>> unused devices: <none>
>>
>> so looks like its carrying on now but with 4 disks and a spare, maybe
>> i can add the other disk once the reshape has finished
>
> It generally helps to include/examine "mdadm -E /dev/sdX" of all devices
> involved in your mail(s) and also "mdadm -Q --detail /dev/md0".
> After the reshape is done it will automatically rebuild using the spare.
> Then you can have a close look which of your devices arent used, clear the
> metadate from the device and add it as well to regain full redundancy.
> You'll have plenty hours of fun watching /proc/mdstat. ;)
> Alex.
>

Thanks for the response Alex, the reshape has got about 2400mins left
to run and no idea how long the rebuild will take..

I will check out those commands once i am back up and running, i am
fairly new to mdadm so still finding out all the useful commands when
trouble shooting issues, thanks for pointing these out to me
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* LVM2/man lvcreate.8.in
From: zkabelac @ 2011-10-30 22:08 UTC (permalink / raw)
  To: lvm-devel

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac at sourceware.org	2011-10-30 22:08:21

Modified files:
	man            : lvcreate.8.in 

Log message:
	More updates for lvcreate manpage

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvcreate.8.in.diff?cvsroot=lvm2&r1=1.28&r2=1.29

--- LVM2/man/lvcreate.8.in	2011/10/28 20:36:05	1.28
+++ LVM2/man/lvcreate.8.in	2011/10/30 22:08:21	1.29
@@ -42,7 +42,7 @@
 .RB [ \-R | \-\-regionsize
 .IR MirrorLogRegionSize ]]
 .RB [ \-n | \-\-name
-.IR LogicalVolumeName ]
+.IR LogicalVolumeName [ Path ]]
 .RB [ \-p | \-\-permission
 .RI { r | rw }]
 .RB [ \-r | \-\-readahead
@@ -53,11 +53,10 @@
 .RB [ \-v | \-\-verbose ]
 .RB [ \-Z | \-\-zero
 .RI { y | n }]
-.IR VolumeGroupName
+.IR VolumeGroupName [ Path ]
 .RI [ PhysicalVolumePath [ :PE [ -PE ]]...]
 .br
 
-.br
 .B lvcreate
 .RB { \-l | \-\-extents
 .IR LogicalExtentsNumber [ % { VG | FREE | ORIGIN }]
@@ -70,13 +69,13 @@
 .RB [ \-\-ignoremonitoring ]
 .RB [ \-\-monitor " {" \fIy | \fIn }]
 .RB [ \-n | \-\-name
-.IR SnapshotLogicalVolumeName ]
+.IR SnapshotLogicalVolumeName [ Path ]]
 .BR \-s | \-\-snapshot
-.RI [ OriginalLogicalVolumePath
+.RI [ OriginalLogicalVolume [ Path ]
 |
-.IR VolumeGroupName
+.IR VolumeGroupName [ Path ]
 .BR \-V | \-\-virtualsize
-.IR VirtualSize ]
+.IR VirtualSize [ bBsSkKmMgGtTpPeE ]]
 .br
 
 .B lvcreate
@@ -282,7 +281,7 @@
 .BR \-\-thinpool " " \fIThinPoolLogicalVolumeName
 Specifies the thin pool logical volume.
 .TP
-.BR \-V ", " \-\-virtualsize " " \fIVirtualSize
+.IR \fB\-V ", " \fB\-\-virtualsize " " VirtualSize [ bBsSkKmMgGtTpPeE ]
 Create a sparse device of the given size (in MB by default) using a snapshot
 or thinly provisioned device when thin pool is specified.
 Anything written to the device will be returned when reading from it.



^ permalink raw reply

* Re: HT (Hyper Threading) aware process scheduling doesn't work as it should
From: Arjan van de Ven @ 2011-10-30 22:12 UTC (permalink / raw)
  To: Artem S. Tashkinov; +Cc: linux-kernel
In-Reply-To: <269467866.49093.1320004632156.JavaMail.mail@webmail17>

On Sun, 30 Oct 2011 19:57:12 +0000 (GMT)
"Artem S. Tashkinov" <t.artem@lycos.com> wrote:

> Hello,
> 
> It's known that if you want to reach maximum performance on HT
> enabled Intel CPUs you should distribute the load evenly between
> physical cores, and when you have loaded all of them you should then
> load the remaining virtual cores.

this is a bold statement, and patently false if you have to threads of
one process that heavily share data between eachother...
(but true for more independent workloads)


-- 
Arjan van de Ven 	Intel Open Source Technology Centre
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org

^ permalink raw reply

* LVM2 lib/metadata/lv_manip.c tools/lvchange.c ...
From: zkabelac @ 2011-10-30 22:07 UTC (permalink / raw)
  To: lvm-devel

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac at sourceware.org	2011-10-30 22:07:38

Modified files:
	lib/metadata   : lv_manip.c 
	tools          : lvchange.c vgchange.c 

Log message:
	Thin creation without activation
	
	All thins are created with the next activation and VG is updated
	without messages. Only some basic commands works.
	(i.e. lvcreate -an  -V10 -T mvg/pool)
	There can be some combination to confuse this system.
	
	This functionality for snapshots is going to be interesting.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.315&r2=1.316
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvchange.c.diff?cvsroot=lvm2&r1=1.132&r2=1.133
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgchange.c.diff?cvsroot=lvm2&r1=1.126&r2=1.127

--- LVM2/lib/metadata/lv_manip.c	2011/10/30 22:02:18	1.315
+++ LVM2/lib/metadata/lv_manip.c	2011/10/30 22:07:38	1.316
@@ -4194,8 +4194,12 @@
 
 	init_dmeventd_monitor(lp->activation_monitoring);
 
-	if (seg_is_thin_pool(lp) || seg_is_thin(lp)) {
-		if (!activate_lv_excl(cmd, lv)) {
+	if (seg_is_thin(lp)) {
+		if ((lp->activate == CHANGE_AY) ||
+		    (lp->activate == CHANGE_ALY))
+                        lp->activate = CHANGE_AE;
+		if ((lp->activate == CHANGE_AE) &&
+		    !activate_lv_excl(cmd, lv)) {
 			log_error("Aborting. Failed to activate thin %s.",
 				  lv->name);
 			goto deactivate_and_revert_new_lv;
@@ -4222,7 +4226,7 @@
 			  lp->snapshot ? "snapshot exception store" :
 					 "start of new LV");
 		goto deactivate_and_revert_new_lv;
-	} else if (seg_is_thin_volume(lp)) {
+	} else if (seg_is_thin_volume(lp) && (lp->activate == CHANGE_AE)) {
 		/* FIXME: for now we may drop any queued thin messages
 		 * since we are sure everything was activated already */
 		if (!detach_pool_messages(first_seg(lv)->pool_lv)) {
--- LVM2/tools/lvchange.c	2011/10/28 20:29:06	1.132
+++ LVM2/tools/lvchange.c	2011/10/30 22:07:38	1.133
@@ -142,6 +142,10 @@
 				    "exclusively", lv->name);
 			if (!activate_lv_excl(cmd, lv))
 				return_0;
+			/* Drop any left thin messages after activation */
+			if (lv_is_thin_volume(lv) &&
+			    !detach_pool_messages(first_seg(lv)->pool_lv))
+				return_0;
 		} else if (activate == CHANGE_ALY) {
 			log_verbose("Activating logical volume \"%s\" locally",
 				    lv->name);
--- LVM2/tools/vgchange.c	2011/10/28 20:29:06	1.126
+++ LVM2/tools/vgchange.c	2011/10/30 22:07:38	1.127
@@ -157,6 +157,12 @@
 				stack;
 				continue;
 			}
+			/* Drop any left thin messages after activation */
+			if (lv_is_thin_volume(lv) &&
+			    !detach_pool_messages(first_seg(lv)->pool_lv)) {
+				stack;
+				continue;
+			}
 		} else if (activate == CHANGE_ALY) {
 			if (!activate_lv_local(cmd, lv)) {
 				stack;



^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.