Skip to content

Commit

Permalink
batman-adv: split tq information in neigh_node struct
Browse files Browse the repository at this point in the history
For the network wide multi interface optimization it is required to save
metrics per outgoing interface in one neighbor. Therefore a new type is
introduced to keep interface-specific information. This also requires
some changes in access and list management.

The compare and equiv_or_better API calls are changed to take the
outgoing interface into consideration.

Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
  • Loading branch information
Simon Wunderlich authored and Antonio Quartulli committed Jan 12, 2014
1 parent f6c8b71 commit 8965233
Show file tree
Hide file tree
Showing 9 changed files with 588 additions and 114 deletions.
267 changes: 212 additions & 55 deletions net/batman-adv/bat_iv_ogm.c

Large diffs are not rendered by default.

75 changes: 66 additions & 9 deletions net/batman-adv/gateway_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ static struct batadv_gw_node *
batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
{
struct batadv_neigh_node *router;
struct batadv_neigh_ifinfo *router_ifinfo;
struct batadv_gw_node *gw_node, *curr_gw = NULL;
uint32_t max_gw_factor = 0, tmp_gw_factor = 0;
uint32_t gw_divisor;
Expand All @@ -149,10 +150,15 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
if (!router)
continue;

router_ifinfo = batadv_neigh_ifinfo_get(router,
BATADV_IF_DEFAULT);
if (!router_ifinfo)
goto next;

if (!atomic_inc_not_zero(&gw_node->refcount))
goto next;

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

switch (atomic_read(&bat_priv->gw_sel_class)) {
case 1: /* fast connection */
Expand Down Expand Up @@ -197,6 +203,8 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)

next:
batadv_neigh_node_free_ref(router);
if (router_ifinfo)
batadv_neigh_ifinfo_free_ref(router_ifinfo);
}
rcu_read_unlock();

Expand Down Expand Up @@ -239,6 +247,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
{
struct batadv_gw_node *curr_gw = NULL, *next_gw = NULL;
struct batadv_neigh_node *router = NULL;
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
char gw_addr[18] = { '\0' };

if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT)
Expand All @@ -262,6 +271,13 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
batadv_gw_reselect(bat_priv);
goto out;
}

router_ifinfo = batadv_neigh_ifinfo_get(router,
BATADV_IF_DEFAULT);
if (!router_ifinfo) {
batadv_gw_reselect(bat_priv);
goto out;
}
}

if ((curr_gw) && (!next_gw)) {
Expand All @@ -276,7 +292,8 @@ 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->bat_iv.tq_avg);
next_gw->bandwidth_up % 10,
router_ifinfo->bat_iv.tq_avg);
batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD,
gw_addr);
} else {
Expand All @@ -286,7 +303,8 @@ 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->bat_iv.tq_avg);
next_gw->bandwidth_up % 10,
router_ifinfo->bat_iv.tq_avg);
batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE,
gw_addr);
}
Expand All @@ -300,11 +318,15 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
batadv_gw_node_free_ref(next_gw);
if (router)
batadv_neigh_node_free_ref(router);
if (router_ifinfo)
batadv_neigh_ifinfo_free_ref(router_ifinfo);
}

void batadv_gw_check_election(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node)
{
struct batadv_neigh_ifinfo *router_orig_tq = NULL;
struct batadv_neigh_ifinfo *router_gw_tq = NULL;
struct batadv_orig_node *curr_gw_orig;
struct batadv_neigh_node *router_gw = NULL, *router_orig = NULL;
uint8_t gw_tq_avg, orig_tq_avg;
Expand All @@ -317,6 +339,11 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
if (!router_gw)
goto reselect;

router_gw_tq = batadv_neigh_ifinfo_get(router_gw,
BATADV_IF_DEFAULT);
if (!router_gw_tq)
goto reselect;

/* this node already is the gateway */
if (curr_gw_orig == orig_node)
goto out;
Expand All @@ -325,8 +352,13 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
if (!router_orig)
goto out;

gw_tq_avg = router_gw->bat_iv.tq_avg;
orig_tq_avg = router_orig->bat_iv.tq_avg;
router_orig_tq = batadv_neigh_ifinfo_get(router_orig,
BATADV_IF_DEFAULT);
if (!router_orig_tq)
goto out;

gw_tq_avg = router_gw_tq->bat_iv.tq_avg;
orig_tq_avg = router_orig_tq->bat_iv.tq_avg;

/* the TQ value has to be better */
if (orig_tq_avg < gw_tq_avg)
Expand All @@ -352,6 +384,10 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
batadv_neigh_node_free_ref(router_gw);
if (router_orig)
batadv_neigh_node_free_ref(router_orig);
if (router_gw_tq)
batadv_neigh_ifinfo_free_ref(router_gw_tq);
if (router_orig_tq)
batadv_neigh_ifinfo_free_ref(router_orig_tq);

return;
}
Expand Down Expand Up @@ -537,28 +573,36 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
{
struct batadv_gw_node *curr_gw;
struct batadv_neigh_node *router;
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
int ret = -1;

router = batadv_orig_node_get_router(gw_node->orig_node);
if (!router)
goto out;

router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
if (!router_ifinfo)
goto out;

curr_gw = batadv_gw_get_selected_gw_node(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->bat_iv.tq_avg, router->addr,
router_ifinfo->bat_iv.tq_avg, router->addr,
router->if_incoming->net_dev->name,
gw_node->bandwidth_down / 10,
gw_node->bandwidth_down % 10,
gw_node->bandwidth_up / 10,
gw_node->bandwidth_up % 10);

batadv_neigh_node_free_ref(router);
if (curr_gw)
batadv_gw_node_free_ref(curr_gw);
out:
if (router_ifinfo)
batadv_neigh_ifinfo_free_ref(router_ifinfo);
if (router)
batadv_neigh_node_free_ref(router);
return ret;
}

Expand Down Expand Up @@ -746,6 +790,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
struct batadv_orig_node *orig_dst_node = NULL;
struct batadv_gw_node *gw_node = NULL, *curr_gw = NULL;
struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
bool out_of_range = false;
uint8_t curr_tq_avg;
Expand Down Expand Up @@ -787,7 +832,14 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
if (!neigh_curr)
goto out;

curr_tq_avg = neigh_curr->bat_iv.tq_avg;
curr_ifinfo = batadv_neigh_ifinfo_get(neigh_curr,
BATADV_IF_DEFAULT);
if (!curr_ifinfo)
goto out;

curr_tq_avg = curr_ifinfo->bat_iv.tq_avg;
batadv_neigh_ifinfo_free_ref(curr_ifinfo);

break;
case BATADV_GW_MODE_OFF:
default:
Expand All @@ -798,8 +850,13 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
if (!neigh_old)
goto out;

if (curr_tq_avg - neigh_old->bat_iv.tq_avg > BATADV_GW_THRESHOLD)
old_ifinfo = batadv_neigh_ifinfo_get(neigh_old, BATADV_IF_DEFAULT);
if (!old_ifinfo)
goto out;

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

out:
if (orig_dst_node)
Expand Down
17 changes: 17 additions & 0 deletions net/batman-adv/hard-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,30 @@ int batadv_hardif_min_mtu(struct net_device *soft_iface);
void batadv_update_min_mtu(struct net_device *soft_iface);
void batadv_hardif_free_rcu(struct rcu_head *rcu);

/**
* batadv_hardif_free_ref - decrement the hard interface refcounter and
* possibly free it
* @hard_iface: the hard interface to free
*/
static inline void
batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
{
if (atomic_dec_and_test(&hard_iface->refcount))
call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu);
}

/**
* batadv_hardif_free_ref_now - decrement the hard interface refcounter and
* possibly free it (without rcu callback)
* @hard_iface: the hard interface to free
*/
static inline void
batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface)
{
if (atomic_dec_and_test(&hard_iface->refcount))
batadv_hardif_free_rcu(&hard_iface->rcu);
}

static inline struct batadv_hard_iface *
batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
{
Expand Down
6 changes: 6 additions & 0 deletions net/batman-adv/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@

#define BATADV_NO_MARK 0

/* default interface for multi interface operation. The default interface is
* used for communication which originated locally (i.e. is not forwarded)
* or where special forwarding is not desired/necessary.
*/
#define BATADV_IF_DEFAULT ((struct batadv_hard_iface *)NULL)

#define BATADV_NUM_WORDS BITS_TO_LONGS(BATADV_TQ_LOCAL_WINDOW_SIZE)

#define BATADV_LOG_BUF_LEN 8192 /* has to be a power of 2 */
Expand Down
24 changes: 20 additions & 4 deletions net/batman-adv/network-coding.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,8 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
struct batadv_coded_packet *coded_packet;
struct batadv_neigh_node *neigh_tmp, *router_neigh;
struct batadv_neigh_node *router_coding = NULL;
struct batadv_neigh_ifinfo *router_neigh_ifinfo = NULL;
struct batadv_neigh_ifinfo *router_coding_ifinfo = NULL;
uint8_t *first_source, *first_dest, *second_source, *second_dest;
__be32 packet_id1, packet_id2;
size_t count;
Expand All @@ -1021,15 +1023,25 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
if (!router_neigh)
goto out;

router_neigh_ifinfo = batadv_neigh_ifinfo_get(router_neigh,
BATADV_IF_DEFAULT);
if (!router_neigh_ifinfo)
goto out;

neigh_tmp = nc_packet->neigh_node;
router_coding = batadv_orig_node_get_router(neigh_tmp->orig_node);
if (!router_coding)
goto out;

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;
router_coding_ifinfo = batadv_neigh_ifinfo_get(router_coding,
BATADV_IF_DEFAULT);
if (!router_coding_ifinfo)
goto out;

tq_tmp = router_neigh_ifinfo->bat_iv.tq_avg;
tq_weighted_neigh = batadv_nc_random_weight_tq(tq_tmp);
tq_tmp = router_coding_ifinfo->bat_iv.tq_avg;
tq_weighted_coding = batadv_nc_random_weight_tq(tq_tmp);

/* Select one destination for the MAC-header dst-field based on
* weighted TQ-values.
Expand Down Expand Up @@ -1153,6 +1165,10 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
batadv_neigh_node_free_ref(router_neigh);
if (router_coding)
batadv_neigh_node_free_ref(router_coding);
if (router_neigh_ifinfo)
batadv_neigh_ifinfo_free_ref(router_neigh_ifinfo);
if (router_coding_ifinfo)
batadv_neigh_ifinfo_free_ref(router_coding_ifinfo);
return res;
}

Expand Down
Loading

0 comments on commit 8965233

Please sign in to comment.