mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 20:23:57 +08:00
Included changes:
- hash computation improvements - Bridge Loop Avoidance set-up phase optimisations - Roaming handling code redesign - some code cleanups -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlCj+LkACgkQpGgxIkP9cwdrJwCdF4IscHc1bVWCYdUZ39jPwM82 3IcAn0BlPsO7cUXsNIGz3ZJZnK+ccnfq =a5hZ -----END PGP SIGNATURE----- Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge Included changes: - hash computation improvements - Bridge Loop Avoidance set-up phase optimisations - Roaming handling code redesign - some code cleanups Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
702ed3c1a9
@ -40,15 +40,11 @@ static void batadv_bla_send_announce(struct batadv_priv *bat_priv,
|
||||
/* return the index of the claim */
|
||||
static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
|
||||
{
|
||||
const unsigned char *key = data;
|
||||
struct batadv_claim *claim = (struct batadv_claim *)data;
|
||||
uint32_t hash = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
|
||||
hash += key[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
|
||||
hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
|
||||
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
@ -61,15 +57,11 @@ static inline uint32_t batadv_choose_claim(const void *data, uint32_t size)
|
||||
static inline uint32_t batadv_choose_backbone_gw(const void *data,
|
||||
uint32_t size)
|
||||
{
|
||||
const unsigned char *key = data;
|
||||
struct batadv_claim *claim = (struct batadv_claim *)data;
|
||||
uint32_t hash = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN + sizeof(short); i++) {
|
||||
hash += key[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash = batadv_hash_bytes(hash, &claim->addr, sizeof(claim->addr));
|
||||
hash = batadv_hash_bytes(hash, &claim->vid, sizeof(claim->vid));
|
||||
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
@ -362,7 +354,7 @@ out:
|
||||
*/
|
||||
static struct batadv_backbone_gw *
|
||||
batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
|
||||
short vid)
|
||||
short vid, bool own_backbone)
|
||||
{
|
||||
struct batadv_backbone_gw *entry;
|
||||
struct batadv_orig_node *orig_node;
|
||||
@ -386,6 +378,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
|
||||
entry->crc = BATADV_BLA_CRC_INIT;
|
||||
entry->bat_priv = bat_priv;
|
||||
atomic_set(&entry->request_sent, 0);
|
||||
atomic_set(&entry->wait_periods, 0);
|
||||
memcpy(entry->orig, orig, ETH_ALEN);
|
||||
|
||||
/* one for the hash, one for returning */
|
||||
@ -409,6 +402,16 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, uint8_t *orig,
|
||||
"became a backbone gateway");
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
}
|
||||
|
||||
if (own_backbone) {
|
||||
batadv_bla_send_announce(bat_priv, entry);
|
||||
|
||||
/* this will be decreased in the worker thread */
|
||||
atomic_inc(&entry->request_sent);
|
||||
atomic_set(&entry->wait_periods, BATADV_BLA_WAIT_PERIODS);
|
||||
atomic_inc(&bat_priv->bla.num_requests);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -424,7 +427,7 @@ batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,
|
||||
|
||||
backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
|
||||
primary_if->net_dev->dev_addr,
|
||||
vid);
|
||||
vid, true);
|
||||
if (unlikely(!backbone_gw))
|
||||
return;
|
||||
|
||||
@ -632,7 +635,8 @@ static int batadv_handle_announce(struct batadv_priv *bat_priv,
|
||||
if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
|
||||
return 0;
|
||||
|
||||
backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
|
||||
backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
|
||||
false);
|
||||
|
||||
if (unlikely(!backbone_gw))
|
||||
return 1;
|
||||
@ -730,7 +734,8 @@ static int batadv_handle_claim(struct batadv_priv *bat_priv,
|
||||
|
||||
/* register the gateway if not yet available, and add the claim. */
|
||||
|
||||
backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
|
||||
backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid,
|
||||
false);
|
||||
|
||||
if (unlikely(!backbone_gw))
|
||||
return 1;
|
||||
@ -1140,6 +1145,24 @@ static void batadv_bla_periodic_work(struct work_struct *work)
|
||||
backbone_gw->lasttime = jiffies;
|
||||
|
||||
batadv_bla_send_announce(bat_priv, backbone_gw);
|
||||
|
||||
/* request_sent is only set after creation to avoid
|
||||
* problems when we are not yet known as backbone gw
|
||||
* in the backbone.
|
||||
*
|
||||
* We can reset this now after we waited some periods
|
||||
* to give bridge forward delays and bla group forming
|
||||
* some grace time.
|
||||
*/
|
||||
|
||||
if (atomic_read(&backbone_gw->request_sent) == 0)
|
||||
continue;
|
||||
|
||||
if (!atomic_dec_and_test(&backbone_gw->wait_periods))
|
||||
continue;
|
||||
|
||||
atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
|
||||
atomic_set(&backbone_gw->request_sent, 0);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -59,6 +59,45 @@ out:
|
||||
return hard_iface;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_is_on_batman_iface - check if a device is a batman iface descendant
|
||||
* @net_dev: the device to check
|
||||
*
|
||||
* If the user creates any virtual device on top of a batman-adv interface, it
|
||||
* is important to prevent this new interface to be used to create a new mesh
|
||||
* network (this behaviour would lead to a batman-over-batman configuration).
|
||||
* This function recursively checks all the fathers of the device passed as
|
||||
* argument looking for a batman-adv soft interface.
|
||||
*
|
||||
* Returns true if the device is descendant of a batman-adv mesh interface (or
|
||||
* if it is a batman-adv interface itself), false otherwise
|
||||
*/
|
||||
static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
|
||||
{
|
||||
struct net_device *parent_dev;
|
||||
bool ret;
|
||||
|
||||
/* check if this is a batman-adv mesh interface */
|
||||
if (batadv_softif_is_valid(net_dev))
|
||||
return true;
|
||||
|
||||
/* no more parents..stop recursion */
|
||||
if (net_dev->iflink == net_dev->ifindex)
|
||||
return false;
|
||||
|
||||
/* recurse over the parent device */
|
||||
parent_dev = dev_get_by_index(&init_net, net_dev->iflink);
|
||||
/* if we got a NULL parent_dev there is something broken.. */
|
||||
if (WARN(!parent_dev, "Cannot find parent device"))
|
||||
return false;
|
||||
|
||||
ret = batadv_is_on_batman_iface(parent_dev);
|
||||
|
||||
if (parent_dev)
|
||||
dev_put(parent_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int batadv_is_valid_iface(const struct net_device *net_dev)
|
||||
{
|
||||
if (net_dev->flags & IFF_LOOPBACK)
|
||||
@ -71,7 +110,7 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
|
||||
return 0;
|
||||
|
||||
/* no batman over batman */
|
||||
if (batadv_softif_is_valid(net_dev))
|
||||
if (batadv_is_on_batman_iface(net_dev))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -81,6 +81,28 @@ static inline void batadv_hash_delete(struct batadv_hashtable *hash,
|
||||
batadv_hash_destroy(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hash_bytes - hash some bytes and add them to the previous hash
|
||||
* @hash: previous hash value
|
||||
* @data: data to be hashed
|
||||
* @size: number of bytes to be hashed
|
||||
*
|
||||
* Returns the new hash value.
|
||||
*/
|
||||
static inline uint32_t batadv_hash_bytes(uint32_t hash, void *data,
|
||||
uint32_t size)
|
||||
{
|
||||
const unsigned char *key = data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
hash += key[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_hash_add - adds data to the hashtable
|
||||
* @hash: storage hash table
|
||||
|
@ -95,6 +95,7 @@
|
||||
#define BATADV_BLA_PERIOD_LENGTH 10000 /* 10 seconds */
|
||||
#define BATADV_BLA_BACKBONE_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 3)
|
||||
#define BATADV_BLA_CLAIM_TIMEOUT (BATADV_BLA_PERIOD_LENGTH * 10)
|
||||
#define BATADV_BLA_WAIT_PERIODS 3
|
||||
|
||||
#define BATADV_DUPLIST_SIZE 16
|
||||
#define BATADV_DUPLIST_TIMEOUT 500 /* 500 ms */
|
||||
|
@ -221,7 +221,6 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
|
||||
atomic_set(&orig_node->refcount, 2);
|
||||
|
||||
orig_node->tt_initialised = false;
|
||||
orig_node->tt_poss_change = false;
|
||||
orig_node->bat_priv = bat_priv;
|
||||
memcpy(orig_node->orig, addr, ETH_ALEN);
|
||||
batadv_dat_init_orig_node_addr(orig_node);
|
||||
|
@ -711,12 +711,6 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
|
||||
BATADV_TT_CLIENT_ROAM,
|
||||
atomic_read(&orig_node->last_ttvn) + 1);
|
||||
|
||||
/* Roaming phase starts: I have new information but the ttvn has not
|
||||
* been incremented yet. This flag will make me check all the incoming
|
||||
* packets for the correct destination.
|
||||
*/
|
||||
bat_priv->tt.poss_change = true;
|
||||
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
out:
|
||||
/* returning NET_RX_DROP will make the caller function kfree the skb */
|
||||
@ -899,14 +893,67 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_reroute_unicast_packet - update the unicast header for re-routing
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @unicast_packet: the unicast header to be updated
|
||||
* @dst_addr: the payload destination
|
||||
*
|
||||
* Search the translation table for dst_addr and update the unicast header with
|
||||
* the new corresponding information (originator address where the destination
|
||||
* client currently is and its known TTVN)
|
||||
*
|
||||
* Returns true if the packet header has been updated, false otherwise
|
||||
*/
|
||||
static bool
|
||||
batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
|
||||
struct batadv_unicast_packet *unicast_packet,
|
||||
uint8_t *dst_addr)
|
||||
{
|
||||
struct batadv_orig_node *orig_node = NULL;
|
||||
struct batadv_hard_iface *primary_if = NULL;
|
||||
bool ret = false;
|
||||
uint8_t *orig_addr, orig_ttvn;
|
||||
|
||||
if (batadv_is_my_client(bat_priv, dst_addr)) {
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
if (!primary_if)
|
||||
goto out;
|
||||
orig_addr = primary_if->net_dev->dev_addr;
|
||||
orig_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
|
||||
} else {
|
||||
orig_node = batadv_transtable_search(bat_priv, NULL, dst_addr);
|
||||
if (!orig_node)
|
||||
goto out;
|
||||
|
||||
if (batadv_compare_eth(orig_node->orig, unicast_packet->dest))
|
||||
goto out;
|
||||
|
||||
orig_addr = orig_node->orig;
|
||||
orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
|
||||
}
|
||||
|
||||
/* update the packet header */
|
||||
memcpy(unicast_packet->dest, orig_addr, ETH_ALEN);
|
||||
unicast_packet->ttvn = orig_ttvn;
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
if (primary_if)
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb) {
|
||||
uint8_t curr_ttvn;
|
||||
uint8_t curr_ttvn, old_ttvn;
|
||||
struct batadv_orig_node *orig_node;
|
||||
struct ethhdr *ethhdr;
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct batadv_unicast_packet *unicast_packet;
|
||||
bool tt_poss_change;
|
||||
int is_old_ttvn;
|
||||
|
||||
/* check if there is enough data before accessing it */
|
||||
@ -918,65 +965,89 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
|
||||
return 0;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
ethhdr = (struct ethhdr *)(skb->data + sizeof(*unicast_packet));
|
||||
|
||||
if (batadv_is_my_mac(unicast_packet->dest)) {
|
||||
tt_poss_change = bat_priv->tt.poss_change;
|
||||
curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
|
||||
} else {
|
||||
/* check if the destination client was served by this node and it is now
|
||||
* roaming. In this case, it means that the node has got a ROAM_ADV
|
||||
* message and that it knows the new destination in the mesh to re-route
|
||||
* the packet to
|
||||
*/
|
||||
if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest)) {
|
||||
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
|
||||
ethhdr->h_dest))
|
||||
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT,
|
||||
bat_priv,
|
||||
"Rerouting unicast packet to %pM (dst=%pM): Local Roaming\n",
|
||||
unicast_packet->dest,
|
||||
ethhdr->h_dest);
|
||||
/* at this point the mesh destination should have been
|
||||
* substituted with the originator address found in the global
|
||||
* table. If not, let the packet go untouched anyway because
|
||||
* there is nothing the node can do
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* retrieve the TTVN known by this node for the packet destination. This
|
||||
* value is used later to check if the node which sent (or re-routed
|
||||
* last time) the packet had an updated information or not
|
||||
*/
|
||||
curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
|
||||
if (!batadv_is_my_mac(unicast_packet->dest)) {
|
||||
orig_node = batadv_orig_hash_find(bat_priv,
|
||||
unicast_packet->dest);
|
||||
|
||||
/* if it is not possible to find the orig_node representing the
|
||||
* destination, the packet can immediately be dropped as it will
|
||||
* not be possible to deliver it
|
||||
*/
|
||||
if (!orig_node)
|
||||
return 0;
|
||||
|
||||
curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
|
||||
tt_poss_change = orig_node->tt_poss_change;
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
}
|
||||
|
||||
/* Check whether I have to reroute the packet */
|
||||
/* check if the TTVN contained in the packet is fresher than what the
|
||||
* node knows
|
||||
*/
|
||||
is_old_ttvn = batadv_seq_before(unicast_packet->ttvn, curr_ttvn);
|
||||
if (is_old_ttvn || tt_poss_change) {
|
||||
/* check if there is enough data before accessing it */
|
||||
if (pskb_may_pull(skb, sizeof(struct batadv_unicast_packet) +
|
||||
ETH_HLEN) < 0)
|
||||
return 0;
|
||||
|
||||
ethhdr = (struct ethhdr *)(skb->data + sizeof(*unicast_packet));
|
||||
|
||||
/* we don't have an updated route for this client, so we should
|
||||
* not try to reroute the packet!!
|
||||
*/
|
||||
if (batadv_tt_global_client_is_roaming(bat_priv,
|
||||
ethhdr->h_dest))
|
||||
return 1;
|
||||
|
||||
orig_node = batadv_transtable_search(bat_priv, NULL,
|
||||
ethhdr->h_dest);
|
||||
|
||||
if (!orig_node) {
|
||||
if (!batadv_is_my_client(bat_priv, ethhdr->h_dest))
|
||||
return 0;
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
if (!primary_if)
|
||||
return 0;
|
||||
memcpy(unicast_packet->dest,
|
||||
primary_if->net_dev->dev_addr, ETH_ALEN);
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
} else {
|
||||
memcpy(unicast_packet->dest, orig_node->orig,
|
||||
ETH_ALEN);
|
||||
curr_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
}
|
||||
if (!is_old_ttvn)
|
||||
return 1;
|
||||
|
||||
old_ttvn = unicast_packet->ttvn;
|
||||
/* the packet was forged based on outdated network information. Its
|
||||
* destination can possibly be updated and forwarded towards the new
|
||||
* target host
|
||||
*/
|
||||
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet,
|
||||
ethhdr->h_dest)) {
|
||||
net_ratelimited_function(batadv_dbg, BATADV_DBG_TT, bat_priv,
|
||||
"TTVN mismatch (old_ttvn %u new_ttvn %u)! Rerouting unicast packet (for %pM) to %pM\n",
|
||||
unicast_packet->ttvn, curr_ttvn,
|
||||
ethhdr->h_dest, unicast_packet->dest);
|
||||
|
||||
unicast_packet->ttvn = curr_ttvn;
|
||||
"Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
|
||||
unicast_packet->dest, ethhdr->h_dest,
|
||||
old_ttvn, curr_ttvn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* the packet has not been re-routed: either the destination is
|
||||
* currently served by this node or there is no destination at all and
|
||||
* it is possible to drop the packet
|
||||
*/
|
||||
if (!batadv_is_my_client(bat_priv, ethhdr->h_dest))
|
||||
return 0;
|
||||
|
||||
/* update the header in order to let the packet be delivered to this
|
||||
* node's soft interface
|
||||
*/
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
if (!primary_if)
|
||||
return 0;
|
||||
|
||||
memcpy(unicast_packet->dest, primary_if->net_dev->dev_addr, ETH_ALEN);
|
||||
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
|
||||
unicast_packet->ttvn = curr_ttvn;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -505,7 +505,6 @@ struct net_device *batadv_softif_create(const char *name)
|
||||
#endif
|
||||
bat_priv->tt.last_changeset = NULL;
|
||||
bat_priv->tt.last_changeset_len = 0;
|
||||
bat_priv->tt.poss_change = false;
|
||||
|
||||
bat_priv->primary_if = NULL;
|
||||
bat_priv->num_ifaces = 0;
|
||||
|
@ -688,7 +688,7 @@ int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
|
||||
enum batadv_uev_action action, const char *data)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
struct batadv_hard_iface *primary_if = NULL;
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct kobject *bat_kobj;
|
||||
char *uevent_env[4] = { NULL, NULL, NULL, NULL };
|
||||
|
||||
|
@ -238,92 +238,134 @@ static int batadv_tt_local_init(struct batadv_priv *bat_priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void batadv_tt_global_free(struct batadv_priv *bat_priv,
|
||||
struct batadv_tt_global_entry *tt_global,
|
||||
const char *message)
|
||||
{
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Deleting global tt entry %pM: %s\n",
|
||||
tt_global->common.addr, message);
|
||||
|
||||
batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
|
||||
batadv_choose_orig, tt_global->common.addr);
|
||||
batadv_tt_global_entry_free_ref(tt_global);
|
||||
|
||||
}
|
||||
|
||||
void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
||||
int ifindex)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
|
||||
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
||||
struct batadv_tt_global_entry *tt_global_entry = NULL;
|
||||
struct batadv_tt_local_entry *tt_local;
|
||||
struct batadv_tt_global_entry *tt_global;
|
||||
struct hlist_head *head;
|
||||
struct hlist_node *node;
|
||||
struct batadv_tt_orig_list_entry *orig_entry;
|
||||
int hash_added;
|
||||
bool roamed_back = false;
|
||||
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
||||
tt_local = batadv_tt_local_hash_find(bat_priv, addr);
|
||||
tt_global = batadv_tt_global_hash_find(bat_priv, addr);
|
||||
|
||||
if (tt_local_entry) {
|
||||
tt_local_entry->last_seen = jiffies;
|
||||
/* possibly unset the BATADV_TT_CLIENT_PENDING flag */
|
||||
tt_local_entry->common.flags &= ~BATADV_TT_CLIENT_PENDING;
|
||||
goto out;
|
||||
if (tt_local) {
|
||||
tt_local->last_seen = jiffies;
|
||||
if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Re-adding pending client %pM\n", addr);
|
||||
/* whatever the reason why the PENDING flag was set,
|
||||
* this is a client which was enqueued to be removed in
|
||||
* this orig_interval. Since it popped up again, the
|
||||
* flag can be reset like it was never enqueued
|
||||
*/
|
||||
tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
|
||||
goto add_event;
|
||||
}
|
||||
|
||||
if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Roaming client %pM came back to its original location\n",
|
||||
addr);
|
||||
/* the ROAM flag is set because this client roamed away
|
||||
* and the node got a roaming_advertisement message. Now
|
||||
* that the client popped up again at its original
|
||||
* location such flag can be unset
|
||||
*/
|
||||
tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
|
||||
roamed_back = true;
|
||||
}
|
||||
goto check_roaming;
|
||||
}
|
||||
|
||||
tt_local_entry = kmalloc(sizeof(*tt_local_entry), GFP_ATOMIC);
|
||||
if (!tt_local_entry)
|
||||
tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
|
||||
if (!tt_local)
|
||||
goto out;
|
||||
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Creating new local tt entry: %pM (ttvn: %d)\n", addr,
|
||||
(uint8_t)atomic_read(&bat_priv->tt.vn));
|
||||
|
||||
memcpy(tt_local_entry->common.addr, addr, ETH_ALEN);
|
||||
tt_local_entry->common.flags = BATADV_NO_FLAGS;
|
||||
memcpy(tt_local->common.addr, addr, ETH_ALEN);
|
||||
tt_local->common.flags = BATADV_NO_FLAGS;
|
||||
if (batadv_is_wifi_iface(ifindex))
|
||||
tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI;
|
||||
atomic_set(&tt_local_entry->common.refcount, 2);
|
||||
tt_local_entry->last_seen = jiffies;
|
||||
tt_local_entry->common.added_at = tt_local_entry->last_seen;
|
||||
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
|
||||
atomic_set(&tt_local->common.refcount, 2);
|
||||
tt_local->last_seen = jiffies;
|
||||
tt_local->common.added_at = tt_local->last_seen;
|
||||
|
||||
/* the batman interface mac address should never be purged */
|
||||
if (batadv_compare_eth(addr, soft_iface->dev_addr))
|
||||
tt_local_entry->common.flags |= BATADV_TT_CLIENT_NOPURGE;
|
||||
tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
|
||||
|
||||
/* The local entry has to be marked as NEW to avoid to send it in
|
||||
* a full table response going out before the next ttvn increment
|
||||
* (consistency check)
|
||||
*/
|
||||
tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW;
|
||||
tt_local->common.flags |= BATADV_TT_CLIENT_NEW;
|
||||
|
||||
hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
|
||||
batadv_choose_orig,
|
||||
&tt_local_entry->common,
|
||||
&tt_local_entry->common.hash_entry);
|
||||
batadv_choose_orig, &tt_local->common,
|
||||
&tt_local->common.hash_entry);
|
||||
|
||||
if (unlikely(hash_added != 0)) {
|
||||
/* remove the reference for the hash */
|
||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||
batadv_tt_local_entry_free_ref(tt_local);
|
||||
goto out;
|
||||
}
|
||||
|
||||
batadv_tt_local_event(bat_priv, addr, tt_local_entry->common.flags);
|
||||
add_event:
|
||||
batadv_tt_local_event(bat_priv, addr, tt_local->common.flags);
|
||||
|
||||
/* remove address from global hash if present */
|
||||
tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
|
||||
|
||||
/* Check whether it is a roaming! */
|
||||
if (tt_global_entry) {
|
||||
check_roaming:
|
||||
/* Check whether it is a roaming, but don't do anything if the roaming
|
||||
* process has already been handled
|
||||
*/
|
||||
if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
|
||||
/* These node are probably going to update their tt table */
|
||||
head = &tt_global_entry->orig_list;
|
||||
head = &tt_global->orig_list;
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(orig_entry, node, head, list) {
|
||||
orig_entry->orig_node->tt_poss_change = true;
|
||||
|
||||
batadv_send_roam_adv(bat_priv,
|
||||
tt_global_entry->common.addr,
|
||||
batadv_send_roam_adv(bat_priv, tt_global->common.addr,
|
||||
orig_entry->orig_node);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
/* The global entry has to be marked as ROAMING and
|
||||
* has to be kept for consistency purpose
|
||||
*/
|
||||
tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
|
||||
tt_global_entry->roam_at = jiffies;
|
||||
if (roamed_back) {
|
||||
batadv_tt_global_free(bat_priv, tt_global,
|
||||
"Roaming canceled");
|
||||
tt_global = NULL;
|
||||
} else {
|
||||
/* The global entry has to be marked as ROAMING and
|
||||
* has to be kept for consistency purpose
|
||||
*/
|
||||
tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
|
||||
tt_global->roam_at = jiffies;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (tt_local_entry)
|
||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||
if (tt_global_entry)
|
||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||
if (tt_local)
|
||||
batadv_tt_local_entry_free_ref(tt_local);
|
||||
if (tt_global)
|
||||
batadv_tt_global_entry_free_ref(tt_global);
|
||||
}
|
||||
|
||||
static void batadv_tt_realloc_packet_buff(unsigned char **packet_buff,
|
||||
@ -502,7 +544,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
||||
const uint8_t *addr, const char *message,
|
||||
bool roaming)
|
||||
{
|
||||
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
||||
struct batadv_tt_local_entry *tt_local_entry;
|
||||
uint16_t flags, curr_flags = BATADV_NO_FLAGS;
|
||||
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
||||
@ -512,10 +554,28 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
||||
curr_flags = tt_local_entry->common.flags;
|
||||
|
||||
flags = BATADV_TT_CLIENT_DEL;
|
||||
if (roaming)
|
||||
/* if this global entry addition is due to a roaming, the node has to
|
||||
* mark the local entry as "roamed" in order to correctly reroute
|
||||
* packets later
|
||||
*/
|
||||
if (roaming) {
|
||||
flags |= BATADV_TT_CLIENT_ROAM;
|
||||
/* mark the local client as ROAMed */
|
||||
tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
|
||||
}
|
||||
|
||||
batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
|
||||
if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
|
||||
batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
|
||||
message);
|
||||
goto out;
|
||||
}
|
||||
/* if this client has been added right now, it is possible to
|
||||
* immediately purge it
|
||||
*/
|
||||
batadv_tt_local_event(bat_priv, tt_local_entry->common.addr,
|
||||
curr_flags | BATADV_TT_CLIENT_DEL);
|
||||
hlist_del_rcu(&tt_local_entry->common.hash_entry);
|
||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||
|
||||
out:
|
||||
if (tt_local_entry)
|
||||
@ -724,13 +784,23 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||
const unsigned char *tt_addr, uint8_t flags,
|
||||
uint8_t ttvn)
|
||||
{
|
||||
struct batadv_tt_global_entry *tt_global_entry = NULL;
|
||||
struct batadv_tt_global_entry *tt_global_entry;
|
||||
struct batadv_tt_local_entry *tt_local_entry;
|
||||
int ret = 0;
|
||||
int hash_added;
|
||||
struct batadv_tt_common_entry *common;
|
||||
uint16_t local_flags;
|
||||
|
||||
tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
|
||||
|
||||
/* if the node already has a local client for this entry, it has to wait
|
||||
* for a roaming advertisement instead of manually messing up the global
|
||||
* table
|
||||
*/
|
||||
if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
|
||||
!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
|
||||
goto out;
|
||||
|
||||
if (!tt_global_entry) {
|
||||
tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
|
||||
@ -765,19 +835,31 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||
goto out_remove;
|
||||
}
|
||||
} else {
|
||||
common = &tt_global_entry->common;
|
||||
/* If there is already a global entry, we can use this one for
|
||||
* our processing.
|
||||
* But if we are trying to add a temporary client we can exit
|
||||
* directly because the temporary information should never
|
||||
* override any already known client state (whatever it is)
|
||||
* But if we are trying to add a temporary client then here are
|
||||
* two options at this point:
|
||||
* 1) the global client is not a temporary client: the global
|
||||
* client has to be left as it is, temporary information
|
||||
* should never override any already known client state
|
||||
* 2) the global client is a temporary client: purge the
|
||||
* originator list and add the new one orig_entry
|
||||
*/
|
||||
if (flags & BATADV_TT_CLIENT_TEMP)
|
||||
goto out;
|
||||
if (flags & BATADV_TT_CLIENT_TEMP) {
|
||||
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
|
||||
goto out;
|
||||
if (batadv_tt_global_entry_has_orig(tt_global_entry,
|
||||
orig_node))
|
||||
goto out_remove;
|
||||
batadv_tt_global_del_orig_list(tt_global_entry);
|
||||
goto add_orig_entry;
|
||||
}
|
||||
|
||||
/* if the client was temporary added before receiving the first
|
||||
* OGM announcing it, we have to clear the TEMP flag
|
||||
*/
|
||||
tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
|
||||
common->flags &= ~BATADV_TT_CLIENT_TEMP;
|
||||
|
||||
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
|
||||
* one originator left in the list and we previously received a
|
||||
@ -786,18 +868,19 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
|
||||
* We should first delete the old originator before adding the
|
||||
* new one.
|
||||
*/
|
||||
if (tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM) {
|
||||
if (common->flags & BATADV_TT_CLIENT_ROAM) {
|
||||
batadv_tt_global_del_orig_list(tt_global_entry);
|
||||
tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
|
||||
common->flags &= ~BATADV_TT_CLIENT_ROAM;
|
||||
tt_global_entry->roam_at = 0;
|
||||
}
|
||||
}
|
||||
add_orig_entry:
|
||||
/* add the new orig_entry (if needed) or update it */
|
||||
batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
|
||||
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Creating new global tt entry: %pM (via %pM)\n",
|
||||
tt_global_entry->common.addr, orig_node->orig);
|
||||
common->addr, orig_node->orig);
|
||||
ret = 1;
|
||||
|
||||
out_remove:
|
||||
@ -805,12 +888,20 @@ out_remove:
|
||||
/* remove address from local hash if present */
|
||||
local_flags = batadv_tt_local_remove(bat_priv, tt_addr,
|
||||
"global tt received",
|
||||
flags & BATADV_TT_CLIENT_ROAM);
|
||||
!!(flags & BATADV_TT_CLIENT_ROAM));
|
||||
tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
|
||||
|
||||
if (!(flags & BATADV_TT_CLIENT_ROAM))
|
||||
/* this is a normal global add. Therefore the client is not in a
|
||||
* roaming state anymore.
|
||||
*/
|
||||
tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
|
||||
|
||||
out:
|
||||
if (tt_global_entry)
|
||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||
if (tt_local_entry)
|
||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -928,21 +1019,6 @@ batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
|
||||
spin_unlock_bh(&tt_global_entry->list_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
|
||||
struct batadv_tt_global_entry *tt_global_entry,
|
||||
const char *message)
|
||||
{
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Deleting global tt entry %pM: %s\n",
|
||||
tt_global_entry->common.addr, message);
|
||||
|
||||
batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
|
||||
batadv_choose_orig, tt_global_entry->common.addr);
|
||||
batadv_tt_global_entry_free_ref(tt_global_entry);
|
||||
|
||||
}
|
||||
|
||||
/* If the client is to be deleted, we check if it is the last origantor entry
|
||||
* within tt_global entry. If yes, we set the BATADV_TT_CLIENT_ROAM flag and the
|
||||
* timer, otherwise we simply remove the originator scheduled for deletion.
|
||||
@ -991,7 +1067,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
|
||||
const unsigned char *addr,
|
||||
const char *message, bool roaming)
|
||||
{
|
||||
struct batadv_tt_global_entry *tt_global_entry = NULL;
|
||||
struct batadv_tt_global_entry *tt_global_entry;
|
||||
struct batadv_tt_local_entry *local_entry = NULL;
|
||||
|
||||
tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr);
|
||||
@ -1003,8 +1079,8 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
|
||||
orig_node, message);
|
||||
|
||||
if (hlist_empty(&tt_global_entry->orig_list))
|
||||
batadv_tt_global_del_struct(bat_priv, tt_global_entry,
|
||||
message);
|
||||
batadv_tt_global_free(bat_priv, tt_global_entry,
|
||||
message);
|
||||
|
||||
goto out;
|
||||
}
|
||||
@ -1027,7 +1103,7 @@ static void batadv_tt_global_del(struct batadv_priv *bat_priv,
|
||||
if (local_entry) {
|
||||
/* local entry exists, case 2: client roamed to us. */
|
||||
batadv_tt_global_del_orig_list(tt_global_entry);
|
||||
batadv_tt_global_del_struct(bat_priv, tt_global_entry, message);
|
||||
batadv_tt_global_free(bat_priv, tt_global_entry, message);
|
||||
} else
|
||||
/* no local entry exists, case 1: check for roaming */
|
||||
batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
|
||||
@ -1206,7 +1282,8 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
|
||||
|
||||
if (src && atomic_read(&bat_priv->ap_isolation)) {
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, src);
|
||||
if (!tt_local_entry)
|
||||
if (!tt_local_entry ||
|
||||
(tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1593,7 +1670,7 @@ static bool
|
||||
batadv_send_other_tt_response(struct batadv_priv *bat_priv,
|
||||
struct batadv_tt_query_packet *tt_request)
|
||||
{
|
||||
struct batadv_orig_node *req_dst_orig_node = NULL;
|
||||
struct batadv_orig_node *req_dst_orig_node;
|
||||
struct batadv_orig_node *res_dst_orig_node = NULL;
|
||||
struct batadv_neigh_node *neigh_node = NULL;
|
||||
struct batadv_hard_iface *primary_if = NULL;
|
||||
@ -1728,7 +1805,7 @@ static bool
|
||||
batadv_send_my_tt_response(struct batadv_priv *bat_priv,
|
||||
struct batadv_tt_query_packet *tt_request)
|
||||
{
|
||||
struct batadv_orig_node *orig_node = NULL;
|
||||
struct batadv_orig_node *orig_node;
|
||||
struct batadv_neigh_node *neigh_node = NULL;
|
||||
struct batadv_hard_iface *primary_if = NULL;
|
||||
uint8_t my_ttvn, req_ttvn, ttvn;
|
||||
@ -1894,7 +1971,7 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
|
||||
static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
|
||||
struct batadv_tt_query_packet *tt_response)
|
||||
{
|
||||
struct batadv_orig_node *orig_node = NULL;
|
||||
struct batadv_orig_node *orig_node;
|
||||
|
||||
orig_node = batadv_orig_hash_find(bat_priv, tt_response->src);
|
||||
if (!orig_node)
|
||||
@ -1936,7 +2013,7 @@ static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
|
||||
|
||||
bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
|
||||
{
|
||||
struct batadv_tt_local_entry *tt_local_entry = NULL;
|
||||
struct batadv_tt_local_entry *tt_local_entry;
|
||||
bool ret = false;
|
||||
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
||||
@ -1945,7 +2022,8 @@ bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr)
|
||||
/* Check if the client has been logically deleted (but is kept for
|
||||
* consistency purpose)
|
||||
*/
|
||||
if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
|
||||
if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
|
||||
(tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
|
||||
goto out;
|
||||
ret = true;
|
||||
out:
|
||||
@ -1996,10 +2074,6 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
|
||||
|
||||
/* Recalculate the CRC for this orig_node and store it */
|
||||
orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
|
||||
/* Roaming phase is over: tables are in sync again. I can
|
||||
* unset the flag
|
||||
*/
|
||||
orig_node->tt_poss_change = false;
|
||||
out:
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
@ -2290,7 +2364,6 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
|
||||
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
||||
"Local changes committed, updating to ttvn %u\n",
|
||||
(uint8_t)atomic_read(&bat_priv->tt.vn));
|
||||
bat_priv->tt.poss_change = false;
|
||||
|
||||
/* reset the sending counter */
|
||||
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
|
||||
@ -2402,11 +2475,6 @@ void batadv_tt_update_orig(struct batadv_priv *bat_priv,
|
||||
*/
|
||||
if (orig_node->tt_crc != tt_crc)
|
||||
goto request_table;
|
||||
|
||||
/* Roaming phase is over: tables are in sync again. I can
|
||||
* unset the flag
|
||||
*/
|
||||
orig_node->tt_poss_change = false;
|
||||
} else {
|
||||
/* if we missed more than one change or our tables are not
|
||||
* in sync anymore -> request fresh tt data
|
||||
@ -2445,6 +2513,32 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_tt_local_client_is_roaming - tells whether the client is roaming
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @addr: the MAC address of the local client to query
|
||||
*
|
||||
* Returns true if the local client is known to be roaming (it is not served by
|
||||
* this node anymore) or not. If yes, the client is still present in the table
|
||||
* to keep the latter consistent with the node TTVN
|
||||
*/
|
||||
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
|
||||
uint8_t *addr)
|
||||
{
|
||||
struct batadv_tt_local_entry *tt_local_entry;
|
||||
bool ret = false;
|
||||
|
||||
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
|
||||
if (!tt_local_entry)
|
||||
goto out;
|
||||
|
||||
ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
|
||||
batadv_tt_local_entry_free_ref(tt_local_entry);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
|
||||
struct batadv_orig_node *orig_node,
|
||||
const unsigned char *addr)
|
||||
|
@ -59,6 +59,8 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
|
||||
int packet_min_len);
|
||||
bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
|
||||
uint8_t *addr);
|
||||
bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
|
||||
uint8_t *addr);
|
||||
bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
|
||||
struct batadv_orig_node *orig_node,
|
||||
const unsigned char *addr);
|
||||
|
@ -101,13 +101,6 @@ struct batadv_orig_node {
|
||||
spinlock_t tt_buff_lock; /* protects tt_buff */
|
||||
atomic_t tt_size;
|
||||
bool tt_initialised;
|
||||
/* The tt_poss_change flag is used to detect an ongoing roaming phase.
|
||||
* If true, then I sent a Roaming_adv to this orig_node and I have to
|
||||
* inspect every packet directed to it to check whether it is still
|
||||
* the true destination or not. This flag will be reset to false as
|
||||
* soon as I receive a new TTVN from this orig_node
|
||||
*/
|
||||
bool tt_poss_change;
|
||||
uint32_t last_real_seqno;
|
||||
uint8_t last_ttl;
|
||||
DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
|
||||
@ -212,7 +205,6 @@ struct batadv_priv_tt {
|
||||
atomic_t vn;
|
||||
atomic_t ogm_append_cnt;
|
||||
atomic_t local_changes;
|
||||
bool poss_change;
|
||||
struct list_head changes_list;
|
||||
struct batadv_hashtable *local_hash;
|
||||
struct batadv_hashtable *global_hash;
|
||||
@ -303,7 +295,7 @@ struct batadv_priv {
|
||||
struct hlist_head forw_bcast_list;
|
||||
struct batadv_hashtable *orig_hash;
|
||||
spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
|
||||
spinlock_t forw_bcast_list_lock; /* protects */
|
||||
spinlock_t forw_bcast_list_lock; /* protects forw_bcast_list */
|
||||
struct delayed_work orig_work;
|
||||
struct batadv_hard_iface __rcu *primary_if; /* rcu protected pointer */
|
||||
struct batadv_algo_ops *bat_algo_ops;
|
||||
@ -369,6 +361,7 @@ struct batadv_backbone_gw {
|
||||
struct hlist_node hash_entry;
|
||||
struct batadv_priv *bat_priv;
|
||||
unsigned long lasttime; /* last time we heard of this backbone gw */
|
||||
atomic_t wait_periods;
|
||||
atomic_t request_sent;
|
||||
atomic_t refcount;
|
||||
struct rcu_head rcu;
|
||||
|
Loading…
Reference in New Issue
Block a user