Commit 7351a482 authored by Simon Wunderlich's avatar Simon Wunderlich Committed by Antonio Quartulli

batman-adv: split out router from orig_node

For the network wide multi interface optimization there are different
routers for each outgoing interface (outgoing from the OGM perspective,
incoming for payload traffic). To reflect this, change the router and
associated data to a list of routers.

While at it, rename batadv_orig_node_get_router() to
batadv_orig_router_get() to follow the new naming scheme.
Signed-off-by: default avatarSimon Wunderlich <simon@open-mesh.com>
Signed-off-by: default avatarMarek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: default avatarAntonio Quartulli <antonio@meshcoding.com>
parent 89652331
This diff is collapsed.
......@@ -589,7 +589,8 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
if (cand[i].type == BATADV_DAT_CANDIDATE_NOT_FOUND)
continue;
neigh_node = batadv_orig_node_get_router(cand[i].orig_node);
neigh_node = batadv_orig_router_get(cand[i].orig_node,
BATADV_IF_DEFAULT);
if (!neigh_node)
goto free_orig;
......
......@@ -146,7 +146,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
continue;
orig_node = gw_node->orig_node;
router = batadv_orig_node_get_router(orig_node);
router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
if (!router)
continue;
......@@ -266,7 +266,8 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
if (next_gw) {
sprintf(gw_addr, "%pM", next_gw->orig_node->orig);
router = batadv_orig_node_get_router(next_gw->orig_node);
router = batadv_orig_router_get(next_gw->orig_node,
BATADV_IF_DEFAULT);
if (!router) {
batadv_gw_reselect(bat_priv);
goto out;
......@@ -335,7 +336,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
if (!curr_gw_orig)
goto reselect;
router_gw = batadv_orig_node_get_router(curr_gw_orig);
router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
if (!router_gw)
goto reselect;
......@@ -348,7 +349,7 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
if (curr_gw_orig == orig_node)
goto out;
router_orig = batadv_orig_node_get_router(orig_node);
router_orig = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
if (!router_orig)
goto out;
......@@ -576,7 +577,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv,
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
int ret = -1;
router = batadv_orig_node_get_router(gw_node->orig_node);
router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
if (!router)
goto out;
......
......@@ -215,7 +215,8 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
if (!orig_node)
goto dst_unreach;
neigh_node = batadv_orig_node_get_router(orig_node);
neigh_node = batadv_orig_router_get(orig_node,
BATADV_IF_DEFAULT);
if (!neigh_node)
goto dst_unreach;
......
......@@ -718,9 +718,21 @@ static bool batadv_can_nc_with_orig(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_ogm_packet *ogm_packet)
{
if (orig_node->last_real_seqno != ntohl(ogm_packet->seqno))
struct batadv_orig_ifinfo *orig_ifinfo;
uint32_t last_real_seqno;
uint8_t last_ttl;
orig_ifinfo = batadv_orig_ifinfo_get(orig_node, BATADV_IF_DEFAULT);
if (!orig_ifinfo)
return false;
if (orig_node->last_ttl != ogm_packet->ttl + 1)
last_ttl = orig_ifinfo->last_ttl;
last_real_seqno = orig_ifinfo->last_real_seqno;
batadv_orig_ifinfo_free_ref(orig_ifinfo);
if (last_real_seqno != ntohl(ogm_packet->seqno))
return false;
if (last_ttl != ogm_packet->ttl + 1)
return false;
if (!batadv_compare_eth(ogm_packet->orig, ogm_packet->prev_sender))
return false;
......@@ -1019,7 +1031,11 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
int coded_size = sizeof(*coded_packet);
int header_add = coded_size - unicast_size;
router_neigh = batadv_orig_node_get_router(neigh_node->orig_node);
/* TODO: do we need to consider the outgoing interface for
* coded packets?
*/
router_neigh = batadv_orig_router_get(neigh_node->orig_node,
BATADV_IF_DEFAULT);
if (!router_neigh)
goto out;
......@@ -1029,7 +1045,8 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv,
goto out;
neigh_tmp = nc_packet->neigh_node;
router_coding = batadv_orig_node_get_router(neigh_tmp->orig_node);
router_coding = batadv_orig_router_get(neigh_tmp->orig_node,
BATADV_IF_DEFAULT);
if (!router_coding)
goto out;
......
This diff is collapsed.
......@@ -34,7 +34,8 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
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);
batadv_orig_router_get(struct batadv_orig_node *orig_node,
const struct batadv_hard_iface *if_outgoing);
struct batadv_neigh_ifinfo *
batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
struct batadv_hard_iface *if_outgoing);
......@@ -42,6 +43,15 @@ struct batadv_neigh_ifinfo *
batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
struct batadv_hard_iface *if_outgoing);
void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo);
struct batadv_orig_ifinfo *
batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_outgoing);
struct batadv_orig_ifinfo *
batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_outgoing);
void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo);
int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
int max_if_num);
......
......@@ -33,13 +33,32 @@
static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
/**
* _batadv_update_route - set the router for this originator
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: orig node which is to be configured
* @recv_if: the receive interface for which this route is set
* @neigh_node: neighbor which should be the next router
*
* This function does not perform any error checks
*/
static void _batadv_update_route(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if,
struct batadv_neigh_node *neigh_node)
{
struct batadv_orig_ifinfo *orig_ifinfo;
struct batadv_neigh_node *curr_router;
curr_router = batadv_orig_node_get_router(orig_node);
orig_ifinfo = batadv_orig_ifinfo_get(orig_node, recv_if);
if (!orig_ifinfo)
return;
rcu_read_lock();
curr_router = rcu_dereference(orig_ifinfo->router);
if (curr_router && !atomic_inc_not_zero(&curr_router->refcount))
curr_router = NULL;
rcu_read_unlock();
/* route deleted */
if ((curr_router) && (!neigh_node)) {
......@@ -69,16 +88,25 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
neigh_node = NULL;
spin_lock_bh(&orig_node->neigh_list_lock);
rcu_assign_pointer(orig_node->router, neigh_node);
rcu_assign_pointer(orig_ifinfo->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_orig_ifinfo_free_ref(orig_ifinfo);
/* decrease refcount of previous best neighbor */
if (curr_router)
batadv_neigh_node_free_ref(curr_router);
}
/**
* batadv_update_route - set the router for this originator
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: orig node which is to be configured
* @recv_if: the receive interface for which this route is set
* @neigh_node: neighbor which should be the next router
*/
void batadv_update_route(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if,
struct batadv_neigh_node *neigh_node)
{
struct batadv_neigh_node *router = NULL;
......@@ -86,10 +114,10 @@ void batadv_update_route(struct batadv_priv *bat_priv,
if (!orig_node)
goto out;
router = batadv_orig_node_get_router(orig_node);
router = batadv_orig_router_get(orig_node, recv_if);
if (router != neigh_node)
_batadv_update_route(bat_priv, orig_node, neigh_node);
_batadv_update_route(bat_priv, orig_node, recv_if, neigh_node);
out:
if (router)
......@@ -406,7 +434,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
if (!orig_node)
return NULL;
router = batadv_orig_node_get_router(orig_node);
router = batadv_orig_router_get(orig_node, recv_if);
/* TODO: fill this later with new bonding mechanism */
......
......@@ -23,6 +23,7 @@ bool batadv_check_management_packet(struct sk_buff *skb,
int header_len);
void batadv_update_route(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if,
struct batadv_neigh_node *neigh_node);
int batadv_recv_icmp_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
......
......@@ -1400,7 +1400,8 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv,
head = &tt_global_entry->orig_list;
hlist_for_each_entry_rcu(orig_entry, head, list) {
router = batadv_orig_node_get_router(orig_entry->orig_node);
router = batadv_orig_router_get(orig_entry->orig_node,
BATADV_IF_DEFAULT);
if (!router)
continue;
......
......@@ -100,6 +100,28 @@ struct batadv_hard_iface {
struct work_struct cleanup_work;
};
/**
* struct batadv_orig_ifinfo - originator info per outgoing interface
* @list: list node for orig_node::ifinfo_list
* @if_outgoing: pointer to outgoing hard interface
* @router: router that should be used to reach this originator
* @last_real_seqno: last and best known sequence number
* @last_ttl: ttl of last received packet
* @batman_seqno_reset: time when the batman seqno window was reset
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
*/
struct batadv_orig_ifinfo {
struct hlist_node list;
struct batadv_hard_iface *if_outgoing;
struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
uint32_t last_real_seqno;
uint8_t last_ttl;
unsigned long batman_seqno_reset;
atomic_t refcount;
struct rcu_head rcu;
};
/**
* struct batadv_frag_table_entry - head in the fragment buffer table
* @head: head of list with fragments
......@@ -175,11 +197,10 @@ struct batadv_orig_bat_iv {
* struct batadv_orig_node - structure for orig_list maintaining nodes of mesh
* @orig: originator ethernet address
* @primary_addr: hosts primary interface address
* @router: router that should be used to reach this originator
* @ifinfo_list: list for routers per outgoing interface
* @batadv_dat_addr_t: address of the orig node in the distributed hash
* @last_seen: time when last packet from this node was received
* @bcast_seqno_reset: time when the broadcast seqno window was reset
* @batman_seqno_reset: time when the batman seqno window was reset
* @capabilities: announced capabilities of this originator
* @last_ttvn: last seen translation table version number
* @tt_buff: last tt changeset this node received from the orig node
......@@ -192,8 +213,6 @@ struct batadv_orig_bat_iv {
* made up by two operations (data structure update and metdata -CRC/TTVN-
* recalculation) and they have to be executed atomically in order to avoid
* another thread to read the table/metadata between those.
* @last_real_seqno: last and best known sequence number
* @last_ttl: ttl of last received packet
* @bcast_bits: bitfield containing the info which payload broadcast originated
* from this orig node this host already has seen (relative to
* last_bcast_seqno)
......@@ -218,13 +237,12 @@ struct batadv_orig_bat_iv {
struct batadv_orig_node {
uint8_t orig[ETH_ALEN];
uint8_t primary_addr[ETH_ALEN];
struct batadv_neigh_node __rcu *router; /* rcu protected pointer */
struct hlist_head ifinfo_list;
#ifdef CONFIG_BATMAN_ADV_DAT
batadv_dat_addr_t dat_addr;
#endif
unsigned long last_seen;
unsigned long bcast_seqno_reset;
unsigned long batman_seqno_reset;
uint8_t capabilities;
atomic_t last_ttvn;
unsigned char *tt_buff;
......@@ -233,8 +251,6 @@ struct batadv_orig_node {
bool tt_initialised;
/* prevents from changing the table while reading it */
spinlock_t tt_lock;
uint32_t last_real_seqno;
uint8_t last_ttl;
DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
uint32_t last_bcast_seqno;
struct hlist_head neigh_list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment