Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e35fd5ec authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Greg Kroah-Hartman
Browse files

Staging: batman-adv: Add bonding functionality



This patch introduces bonding functionality to batman-advanced, targeted
for the 0.3 release. As we are able to route the payload traffic as we
want, we may use multiple interfaces on multihomed hosts to transfer data
to achieve higher bandwidth. This can be considered as "light Multi Path
Routing" for single hop connections.

To detect which interfaces of a peer node belong to the same host, a
new flag PRIMARIES_FIRST_HOP is introduced. This flag is set on the first hop
of OGMs of the primary (first) interface, which is broadcasted on all
interfaces. When receiving such an OGM, we can learn which interfaces
belong to the same host (by assigning them to the primary originator).

Bonding works by sending packets in a round-robin fashion to the available
interfaces of a neighbor host, if multiple interfaces are available. The
neighbor interfaces should be almost equally good to reach.

To avoid interferences (i.e. sending on the same channel), only neighbor
interfaces with different mac addresses and different outgoing interfaces
are considered as candidates.

Bonding is deactivated by default, and can be activated by

echo 1 > /sys/class/net/bat0/mesh/bonding

for each individual node.

Signed-off-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
[sven.eckelmann@gmx.de: Rework on top of current version]
Signed-off-by: default avatarSven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent cf2d72ec
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -84,6 +84,55 @@ static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr,
	return count;
}

static ssize_t show_bond(struct kobject *kobj, struct attribute *attr,
			     char *buff)
{
	struct device *dev = to_dev(kobj->parent);
	struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev));
	int bond_status = atomic_read(&bat_priv->bonding_enabled);

	return sprintf(buff, "%s\n",
		       bond_status == 0 ? "disabled" : "enabled");
}

static ssize_t store_bond(struct kobject *kobj, struct attribute *attr,
			  char *buff, size_t count)
{
	struct device *dev = to_dev(kobj->parent);
	struct net_device *net_dev = to_net_dev(dev);
	struct bat_priv *bat_priv = netdev_priv(net_dev);
	int bonding_enabled_tmp = -1;

	if (((count == 2) && (buff[0] == '1')) ||
	    (strncmp(buff, "enable", 6) == 0))
		bonding_enabled_tmp = 1;

	if (((count == 2) && (buff[0] == '0')) ||
	    (strncmp(buff, "disable", 7) == 0))
		bonding_enabled_tmp = 0;

	if (bonding_enabled_tmp < 0) {
		if (buff[count - 1] == '\n')
			buff[count - 1] = '\0';

		printk(KERN_ERR "batman-adv:Invalid parameter for 'bonding' setting on mesh %s received: %s\n",
		       net_dev->name, buff);
		return -EINVAL;
	}

	if (atomic_read(&bat_priv->bonding_enabled) == bonding_enabled_tmp)
		return count;

	printk(KERN_INFO "batman-adv:Changing bonding from: %s to: %s on mesh: %s\n",
	       atomic_read(&bat_priv->bonding_enabled) == 1 ?
	       "enabled" : "disabled",
	       bonding_enabled_tmp == 1 ? "enabled" : "disabled",
	       net_dev->name);

	atomic_set(&bat_priv->bonding_enabled, (unsigned)bonding_enabled_tmp);
	return count;
}

static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr,
			     char *buff)
{
@@ -182,12 +231,14 @@ static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr,

static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR,
		show_aggr_ogms, store_aggr_ogms);
static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond);
static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR,
		show_orig_interval, store_orig_interval);

static struct bat_attribute *mesh_attrs[] = {
	&bat_attr_aggregated_ogms,
	&bat_attr_bonding,
	&bat_attr_vis_mode,
	&bat_attr_orig_interval,
	NULL,
@@ -203,6 +254,7 @@ int sysfs_add_meshif(struct net_device *dev)
	/* FIXME: should be done in the general mesh setup
		  routine as soon as we have it */
	atomic_set(&bat_priv->aggregation_enabled, 1);
	atomic_set(&bat_priv->bonding_enabled, 0);
	atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE);
	atomic_set(&bat_priv->orig_interval, 1000);
	bat_priv->primary_if = NULL;
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ static void set_primary_if(struct bat_priv *bat_priv,
	set_main_if_addr(batman_if->net_dev->dev_addr);

	batman_packet = (struct batman_packet *)(batman_if->packet_buff);
	batman_packet->flags = 0;
	batman_packet->flags = PRIMARIES_FIRST_HOP;
	batman_packet->ttl = TTL;

	/***
+5 −0
Original line number Diff line number Diff line
@@ -59,6 +59,11 @@

#define VIS_INTERVAL 5000	/* 5 seconds */

/* how much worse secondary interfaces may be to
 * to be considered as bonding candidates */

#define BONDING_TQ_THRESHOLD	50

#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
				   * change the size of
				   * forw_packet->direct_link_flags */
+7 −1
Original line number Diff line number Diff line
@@ -226,6 +226,8 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,

static bool purge_orig_node(struct orig_node *orig_node)
{
	/* FIXME: each batman_if will be attached to a softif */
	struct bat_priv *bat_priv = netdev_priv(soft_device);
	struct neigh_node *best_neigh_node;

	if (time_after(jiffies,
@@ -237,10 +239,14 @@ static bool purge_orig_node(struct orig_node *orig_node)
			orig_node->orig, (orig_node->last_valid / HZ));
		return true;
	} else {
		if (purge_orig_neighbors(orig_node, &best_neigh_node))
		if (purge_orig_neighbors(orig_node, &best_neigh_node)) {
			update_routes(orig_node, best_neigh_node,
				      orig_node->hna_buff,
				      orig_node->hna_buff_len);
			/* update bonding candidates, we could have lost
			 * some candidates. */
			update_bonding_candidates(bat_priv, orig_node);
		}
	}

	return false;
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#define COMPAT_VERSION 11
#define DIRECTLINK 0x40
#define VIS_SERVER 0x20
#define PRIMARIES_FIRST_HOP 0x10

/* ICMP message types */
#define ECHO_REPLY 0
Loading