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

Commit 20ff9d59 authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Antonio Quartulli
Browse files

batman-adv: don't let backbone gateways exchange tt entries



As the backbone gateways are connected to the same backbone, they
should announce the same clients on the backbone non-exclusively.

Signed-off-by: default avatarSimon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
parent db08e6e5
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "hard-interface.h"
#include "originator.h"
#include "bridge_loop_avoidance.h"
#include "translation-table.h"
#include "send.h"

#include <linux/etherdevice.h>
@@ -359,6 +360,7 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
					       uint8_t *orig, short vid)
{
	struct backbone_gw *entry;
	struct orig_node *orig_node;
	int hash_added;

	entry = backbone_hash_find(bat_priv, orig, vid);
@@ -393,6 +395,13 @@ static struct backbone_gw *bla_get_backbone_gw(struct bat_priv *bat_priv,
		return NULL;
	}

	/* this is a gateway now, remove any tt entries */
	orig_node = orig_hash_find(bat_priv, orig);
	if (orig_node) {
		tt_global_del_orig(bat_priv, orig_node,
				   "became a backbone gateway");
		orig_node_free_ref(orig_node);
	}
	return entry;
}

@@ -1049,6 +1058,47 @@ int bla_init(struct bat_priv *bat_priv)
	return 1;
}

/**
 * @bat_priv: the bat priv with all the soft interface information
 * @orig: originator mac address
 *
 * check if the originator is a gateway for any VLAN ID.
 *
 * returns 1 if it is found, 0 otherwise
 *
 */

int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig)
{
	struct hashtable_t *hash = bat_priv->backbone_hash;
	struct hlist_head *head;
	struct hlist_node *node;
	struct backbone_gw *backbone_gw;
	int i;

	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
		return 0;

	if (!hash)
		return 0;

	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, orig)) {
				rcu_read_unlock();
				return 1;
			}
		}
		rcu_read_unlock();
	}

	return 0;
}


/**
 * @skb: the frame to be checked
 * @orig_node: the orig_node of the frame
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ 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);
int bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
int bla_is_backbone_gw_orig(struct bat_priv *bat_priv, uint8_t *orig);
void bla_update_orig_address(struct bat_priv *bat_priv,
			     struct hard_iface *primary_if,
			     struct hard_iface *oldif);
+7 −0
Original line number Diff line number Diff line
@@ -673,6 +673,13 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
	if (!is_my_mac(roam_adv_packet->dst))
		return route_unicast_packet(skb, recv_if);

	/* check if it is a backbone gateway. we don't accept
	 * roaming advertisement from it, as it has the same
	 * entries as we have.
	 */
	if (bla_is_backbone_gw_orig(bat_priv, roam_adv_packet->src))
		goto out;

	orig_node = orig_hash_find(bat_priv, roam_adv_packet->src);
	if (!orig_node)
		goto out;
+16 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "hash.h"
#include "originator.h"
#include "routing.h"
#include "bridge_loop_avoidance.h"

#include <linux/crc16.h>

@@ -1615,11 +1616,16 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
bool send_tt_response(struct bat_priv *bat_priv,
		      struct tt_query_packet *tt_request)
{
	if (is_my_mac(tt_request->dst))
	if (is_my_mac(tt_request->dst)) {
		/* don't answer backbone gws! */
		if (bla_is_backbone_gw_orig(bat_priv, tt_request->src))
			return true;

		return send_my_tt_response(bat_priv, tt_request);
	else
	} else {
		return send_other_tt_response(bat_priv, tt_request);
	}
}

static void _tt_update_changes(struct bat_priv *bat_priv,
			       struct orig_node *orig_node,
@@ -1722,6 +1728,10 @@ void handle_tt_response(struct bat_priv *bat_priv,
		tt_response->src, tt_response->ttvn, tt_response->tt_data,
		(tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));

	/* we should have never asked a backbone gw */
	if (bla_is_backbone_gw_orig(bat_priv, tt_response->src))
		goto out;

	orig_node = orig_hash_find(bat_priv, tt_response->src);
	if (!orig_node)
		goto out;
@@ -2052,6 +2062,10 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
	uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
	bool full_table = true;

	/* don't care about a backbone gateways updates. */
	if (bla_is_backbone_gw_orig(bat_priv, orig_node->orig))
		return;

	/* orig table not initialised AND first diff is in the OGM OR the ttvn
	 * increased by one -> we can apply the attached changes */
	if ((!orig_node->tt_initialised && ttvn == 1) ||