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

Commit 0538f759 authored by Antonio Quartulli's avatar Antonio Quartulli Committed by Antonio Quartulli
Browse files

batman-adv: make struct batadv_neigh_node algorithm agnostic



some of the fields in struct batadv_neigh_node are strictly
related to the B.A.T.M.A.N. IV algorithm. In order to
make the struct usable by any routing algorithm it has to be
split and made more generic

Signed-off-by: default avatarAntonio Quartulli <antonio@open-mesh.com>
Signed-off-by: default avatarMarek Lindner <lindner_marek@yahoo.de>
parent 47d4ab91
Loading
Loading
Loading
Loading
+33 −27
Original line number Diff line number Diff line
@@ -93,16 +93,18 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
			struct batadv_orig_node *orig_node,
			struct batadv_orig_node *orig_neigh)
{
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_neigh_node *neigh_node;

	neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr);
	neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node);
	if (!neigh_node)
		goto out;

	INIT_LIST_HEAD(&neigh_node->bonding_list);
	spin_lock_init(&neigh_node->bat_iv.lq_update_lock);

	neigh_node->orig_node = orig_neigh;
	neigh_node->if_incoming = hard_iface;
	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
		   "Creating new neighbor %pM for orig_node %pM on interface %s\n",
		   neigh_addr, orig_node->orig, hard_iface->net_dev->name);

	spin_lock_bh(&orig_node->neigh_list_lock);
	hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
@@ -755,12 +757,12 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
		if (dup_status != BATADV_NO_DUP)
			continue;

		spin_lock_bh(&tmp_neigh_node->lq_update_lock);
		batadv_ring_buffer_set(tmp_neigh_node->tq_recv,
				       &tmp_neigh_node->tq_index, 0);
		tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv);
		tmp_neigh_node->tq_avg = tq_avg;
		spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
		spin_lock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
		batadv_ring_buffer_set(tmp_neigh_node->bat_iv.tq_recv,
				       &tmp_neigh_node->bat_iv.tq_index, 0);
		tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->bat_iv.tq_recv);
		tmp_neigh_node->bat_iv.tq_avg = tq_avg;
		spin_unlock_bh(&tmp_neigh_node->bat_iv.lq_update_lock);
	}

	if (!neigh_node) {
@@ -785,12 +787,13 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,

	neigh_node->last_seen = jiffies;

	spin_lock_bh(&neigh_node->lq_update_lock);
	batadv_ring_buffer_set(neigh_node->tq_recv,
			       &neigh_node->tq_index,
	spin_lock_bh(&neigh_node->bat_iv.lq_update_lock);
	batadv_ring_buffer_set(neigh_node->bat_iv.tq_recv,
			       &neigh_node->bat_iv.tq_index,
			       batadv_ogm_packet->tq);
	neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv);
	spin_unlock_bh(&neigh_node->lq_update_lock);
	tq_avg = batadv_ring_buffer_avg(neigh_node->bat_iv.tq_recv);
	neigh_node->bat_iv.tq_avg = tq_avg;
	spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock);

	if (dup_status == BATADV_NO_DUP) {
		orig_node->last_ttl = batadv_ogm_packet->header.ttl;
@@ -807,13 +810,13 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
		goto out;

	/* if this neighbor does not offer a better TQ we won't consider it */
	if (router && (router->tq_avg > neigh_node->tq_avg))
	if (router && (router->bat_iv.tq_avg > neigh_node->bat_iv.tq_avg))
		goto out;

	/* if the TQ is the same and the link not more symmetric we
	 * won't consider it either
	 */
	if (router && (neigh_node->tq_avg == router->tq_avg)) {
	if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) {
		orig_node_tmp = router->orig_node;
		spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
		if_num = router->if_incoming->if_num;
@@ -892,7 +895,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
	/* find packet count of corresponding one hop neighbor */
	spin_lock_bh(&orig_node->ogm_cnt_lock);
	orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num];
	neigh_rq_count = neigh_node->real_packet_count;
	neigh_rq_count = neigh_node->bat_iv.real_packet_count;
	spin_unlock_bh(&orig_node->ogm_cnt_lock);

	/* pay attention to not get a value bigger than 100 % */
@@ -975,6 +978,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
	uint32_t seqno = ntohl(batadv_ogm_packet->seqno);
	uint8_t *neigh_addr;
	uint8_t packet_count;
	unsigned long *bitmap;

	orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig);
	if (!orig_node)
@@ -995,7 +999,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
	hlist_for_each_entry_rcu(tmp_neigh_node,
				 &orig_node->neigh_list, list) {
		neigh_addr = tmp_neigh_node->addr;
		is_dup = batadv_test_bit(tmp_neigh_node->real_bits,
		is_dup = batadv_test_bit(tmp_neigh_node->bat_iv.real_bits,
					 orig_node->last_real_seqno,
					 seqno);

@@ -1011,13 +1015,13 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
		}

		/* if the window moved, set the update flag. */
		need_update |= batadv_bit_get_packet(bat_priv,
						     tmp_neigh_node->real_bits,
		bitmap = tmp_neigh_node->bat_iv.real_bits;
		need_update |= batadv_bit_get_packet(bat_priv, bitmap,
						     seq_diff, set_mark);

		packet_count = bitmap_weight(tmp_neigh_node->real_bits,
		packet_count = bitmap_weight(tmp_neigh_node->bat_iv.real_bits,
					     BATADV_TQ_LOCAL_WINDOW_SIZE);
		tmp_neigh_node->real_packet_count = packet_count;
		tmp_neigh_node->bat_iv.real_packet_count = packet_count;
	}
	rcu_read_unlock();

@@ -1041,7 +1045,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
{
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	struct batadv_hard_iface *hard_iface;
	struct batadv_orig_node *orig_neigh_node, *orig_node;
	struct batadv_orig_node *orig_neigh_node, *orig_node, *orig_node_tmp;
	struct batadv_neigh_node *router = NULL, *router_router = NULL;
	struct batadv_neigh_node *orig_neigh_router = NULL;
	int has_directlink_flag;
@@ -1192,10 +1196,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
	}

	router = batadv_orig_node_get_router(orig_node);
	if (router)
		router_router = batadv_orig_node_get_router(router->orig_node);
	if (router) {
		orig_node_tmp = router->orig_node;
		router_router = batadv_orig_node_get_router(orig_node_tmp);
	}

	if ((router && router->tq_avg != 0) &&
	if ((router && router->bat_iv.tq_avg != 0) &&
	    (batadv_compare_eth(router->addr, ethhdr->h_source)))
		is_from_best_next_hop = true;

+8 −8
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
		if (!atomic_inc_not_zero(&gw_node->refcount))
			goto next;

		tq_avg = router->tq_avg;
		tq_avg = router->bat_iv.tq_avg;

		switch (atomic_read(&bat_priv->gw_sel_class)) {
		case 1: /* fast connection */
@@ -256,7 +256,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
			   next_gw->bandwidth_down / 10,
			   next_gw->bandwidth_down % 10,
			   next_gw->bandwidth_up / 10,
			   next_gw->bandwidth_up % 10, router->tq_avg);
			   next_gw->bandwidth_up % 10, router->bat_iv.tq_avg);
		batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
				    gw_addr);
	} else {
@@ -266,7 +266,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
			   next_gw->bandwidth_down / 10,
			   next_gw->bandwidth_down % 10,
			   next_gw->bandwidth_up / 10,
			   next_gw->bandwidth_up % 10, router->tq_avg);
			   next_gw->bandwidth_up % 10, router->bat_iv.tq_avg);
		batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
				    gw_addr);
	}
@@ -305,8 +305,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
	if (!router_orig)
		goto out;

	gw_tq_avg = router_gw->tq_avg;
	orig_tq_avg = router_orig->tq_avg;
	gw_tq_avg = router_gw->bat_iv.tq_avg;
	orig_tq_avg = router_orig->bat_iv.tq_avg;

	/* the TQ value has to be better */
	if (orig_tq_avg < gw_tq_avg)
@@ -528,7 +528,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
	ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n",
			 (curr_gw == gw_node ? "=>" : "  "),
			 gw_node->orig_node->orig,
			 router->tq_avg, router->addr,
			 router->bat_iv.tq_avg, router->addr,
			 router->if_incoming->net_dev->name,
			 gw_node->bandwidth_down / 10,
			 gw_node->bandwidth_down % 10,
@@ -792,7 +792,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
		if (!neigh_curr)
			goto out;

		curr_tq_avg = neigh_curr->tq_avg;
		curr_tq_avg = neigh_curr->bat_iv.tq_avg;
		break;
	case BATADV_GW_MODE_OFF:
	default:
@@ -803,7 +803,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
	if (!neigh_old)
		goto out;

	if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD)
	if (curr_tq_avg - neigh_old->bat_iv.tq_avg > BATADV_GW_THRESHOLD)
		out_of_range = true;

out:
+5 −3
Original line number Diff line number Diff line
@@ -1003,7 +1003,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
				   struct batadv_nc_packet *nc_packet,
				   struct batadv_neigh_node *neigh_node)
{
	uint8_t tq_weighted_neigh, tq_weighted_coding;
	uint8_t tq_weighted_neigh, tq_weighted_coding, tq_tmp;
	struct sk_buff *skb_dest, *skb_src;
	struct batadv_unicast_packet *packet1;
	struct batadv_unicast_packet *packet2;
@@ -1028,8 +1028,10 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
	if (!router_coding)
		goto out;

	tq_weighted_neigh = batadv_nc_random_weight_tq(router_neigh->tq_avg);
	tq_weighted_coding = batadv_nc_random_weight_tq(router_coding->tq_avg);
	tq_tmp = batadv_nc_random_weight_tq(router_neigh->bat_iv.tq_avg);
	tq_weighted_neigh = tq_tmp;
	tq_tmp = batadv_nc_random_weight_tq(router_coding->bat_iv.tq_avg);
	tq_weighted_coding = tq_tmp;

	/* Select one destination for the MAC-header dst-field based on
	 * weighted TQ-values.
+22 −11
Original line number Diff line number Diff line
@@ -172,11 +172,20 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
	return router;
}

/**
 * batadv_neigh_node_new - create and init a new neigh_node object
 * @hard_iface: the interface where the neighbour is connected to
 * @neigh_addr: the mac address of the neighbour interface
 * @orig_node: originator object representing the neighbour
 *
 * Allocates a new neigh_node object and initialises all the generic fields.
 * Returns the new object or NULL on failure.
 */
struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
		      const uint8_t *neigh_addr)
		      const uint8_t *neigh_addr,
		      struct batadv_orig_node *orig_node)
{
	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
	struct batadv_neigh_node *neigh_node;

	neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC);
@@ -186,15 +195,14 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
	INIT_HLIST_NODE(&neigh_node->list);

	memcpy(neigh_node->addr, neigh_addr, ETH_ALEN);
	spin_lock_init(&neigh_node->lq_update_lock);
	neigh_node->if_incoming = hard_iface;
	neigh_node->orig_node = orig_node;

	INIT_LIST_HEAD(&neigh_node->bonding_list);

	/* extra reference for return */
	atomic_set(&neigh_node->refcount, 2);

	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
		   "Creating new neighbor %pM on interface %s\n", neigh_addr,
		   hard_iface->net_dev->name);

out:
	return neigh_node;
}
@@ -401,6 +409,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
	bool neigh_purged = false;
	unsigned long last_seen;
	struct batadv_hard_iface *if_incoming;
	uint8_t best_metric = 0;

	*best_neigh_node = NULL;

@@ -436,8 +445,10 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
			batadv_neigh_node_free_ref(neigh_node);
		} else {
			if ((!*best_neigh_node) ||
			    (neigh_node->tq_avg > (*best_neigh_node)->tq_avg))
			    (neigh_node->bat_iv.tq_avg > best_metric)) {
				*best_neigh_node = neigh_node;
				best_metric = neigh_node->bat_iv.tq_avg;
			}
		}
	}

@@ -557,7 +568,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
			if (!neigh_node)
				continue;

			if (neigh_node->tq_avg == 0)
			if (neigh_node->bat_iv.tq_avg == 0)
				goto next;

			last_seen_jiffies = jiffies - orig_node->last_seen;
@@ -567,7 +578,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)

			seq_printf(seq, "%pM %4i.%03is   (%3i) %pM [%10s]:",
				   orig_node->orig, last_seen_secs,
				   last_seen_msecs, neigh_node->tq_avg,
				   last_seen_msecs, neigh_node->bat_iv.tq_avg,
				   neigh_node->addr,
				   neigh_node->if_incoming->net_dev->name);

@@ -575,7 +586,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
						 &orig_node->neigh_list, list) {
				seq_printf(seq, " %pM (%3i)",
					   neigh_node_tmp->addr,
					   neigh_node_tmp->tq_avg);
					   neigh_node_tmp->bat_iv.tq_avg);
			}

			seq_puts(seq, "\n");
+2 −1
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
					      const uint8_t *addr);
struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
		      const uint8_t *neigh_addr);
		      const uint8_t *neigh_addr,
		      struct batadv_orig_node *orig_node);
void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
struct batadv_neigh_node *
batadv_orig_node_get_router(struct batadv_orig_node *orig_node);
Loading