Commit 74833608 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge

Included changes:

* an improvement to avoid to linearise the whole received packet when not needed
* an improvement for client traffic rerouting after roaming
* a fix for the local translation table state-machine
* minor cleanups and fixes
parents c597f665 521251f2
[state: 21-08-2011]
BATMAN-ADV BATMAN-ADV
---------- ----------
...@@ -68,10 +66,11 @@ All mesh wide settings can be found in batman's own interface ...@@ -68,10 +66,11 @@ All mesh wide settings can be found in batman's own interface
folder: folder:
# ls /sys/class/net/bat0/mesh/ # ls /sys/class/net/bat0/mesh/
# aggregated_ogms fragmentation hop_penalty # aggregated_ogms gw_bandwidth log_level
# ap_isolation gw_bandwidth log_level # ap_isolation gw_mode orig_interval
# bonding gw_mode orig_interval # bonding gw_sel_class routing_algo
# bridge_loop_avoidance gw_sel_class vis_mode # bridge_loop_avoidance hop_penalty vis_mode
# fragmentation
There is a special folder for debugging information: There is a special folder for debugging information:
......
...@@ -43,7 +43,6 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface, ...@@ -43,7 +43,6 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface,
goto out; goto out;
INIT_LIST_HEAD(&neigh_node->bonding_list); INIT_LIST_HEAD(&neigh_node->bonding_list);
spin_lock_init(&neigh_node->tq_lock);
neigh_node->orig_node = orig_neigh; neigh_node->orig_node = orig_neigh;
neigh_node->if_incoming = hard_iface; neigh_node->if_incoming = hard_iface;
...@@ -637,12 +636,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, ...@@ -637,12 +636,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
if (is_duplicate) if (is_duplicate)
continue; continue;
spin_lock_bh(&tmp_neigh_node->tq_lock); spin_lock_bh(&tmp_neigh_node->lq_update_lock);
ring_buffer_set(tmp_neigh_node->tq_recv, ring_buffer_set(tmp_neigh_node->tq_recv,
&tmp_neigh_node->tq_index, 0); &tmp_neigh_node->tq_index, 0);
tmp_neigh_node->tq_avg = tmp_neigh_node->tq_avg =
ring_buffer_avg(tmp_neigh_node->tq_recv); ring_buffer_avg(tmp_neigh_node->tq_recv);
spin_unlock_bh(&tmp_neigh_node->tq_lock); spin_unlock_bh(&tmp_neigh_node->lq_update_lock);
} }
if (!neigh_node) { if (!neigh_node) {
...@@ -668,12 +667,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, ...@@ -668,12 +667,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
orig_node->flags = batman_ogm_packet->flags; orig_node->flags = batman_ogm_packet->flags;
neigh_node->last_seen = jiffies; neigh_node->last_seen = jiffies;
spin_lock_bh(&neigh_node->tq_lock); spin_lock_bh(&neigh_node->lq_update_lock);
ring_buffer_set(neigh_node->tq_recv, ring_buffer_set(neigh_node->tq_recv,
&neigh_node->tq_index, &neigh_node->tq_index,
batman_ogm_packet->tq); batman_ogm_packet->tq);
neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv);
spin_unlock_bh(&neigh_node->tq_lock); spin_unlock_bh(&neigh_node->lq_update_lock);
if (!is_duplicate) { if (!is_duplicate) {
orig_node->last_ttl = batman_ogm_packet->header.ttl; orig_node->last_ttl = batman_ogm_packet->header.ttl;
......
...@@ -173,9 +173,9 @@ static void check_known_mac_addr(const struct net_device *net_dev) ...@@ -173,9 +173,9 @@ static void check_known_mac_addr(const struct net_device *net_dev)
net_dev->dev_addr)) net_dev->dev_addr))
continue; continue;
pr_warning("The newly added mac address (%pM) already exists on: %s\n", pr_warn("The newly added mac address (%pM) already exists on: %s\n",
net_dev->dev_addr, hard_iface->net_dev->name); net_dev->dev_addr, hard_iface->net_dev->name);
pr_warning("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
} }
rcu_read_unlock(); rcu_read_unlock();
} }
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define DRIVER_DEVICE "batman-adv" #define DRIVER_DEVICE "batman-adv"
#ifndef SOURCE_VERSION #ifndef SOURCE_VERSION
#define SOURCE_VERSION "2012.1.0" #define SOURCE_VERSION "2012.2.0"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
......
...@@ -99,6 +99,7 @@ struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface, ...@@ -99,6 +99,7 @@ struct neigh_node *batadv_neigh_node_new(struct hard_iface *hard_iface,
INIT_HLIST_NODE(&neigh_node->list); INIT_HLIST_NODE(&neigh_node->list);
memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); memcpy(neigh_node->addr, neigh_addr, ETH_ALEN);
spin_lock_init(&neigh_node->lq_update_lock);
/* extra reference for return */ /* extra reference for return */
atomic_set(&neigh_node->refcount, 2); atomic_set(&neigh_node->refcount, 2);
......
...@@ -234,17 +234,14 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff, ...@@ -234,17 +234,14 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
{ {
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) || if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) ||
(seq_num_diff >= EXPECTED_SEQNO_RANGE)) { (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
if (has_timed_out(*last_reset, RESET_PROTECTION_MS)) { if (!has_timed_out(*last_reset, RESET_PROTECTION_MS))
*last_reset = jiffies;
bat_dbg(DBG_BATMAN, bat_priv,
"old packet received, start protection\n");
return 0;
} else {
return 1; return 1;
}
*last_reset = jiffies;
bat_dbg(DBG_BATMAN, bat_priv,
"old packet received, start protection\n");
} }
return 0; return 0;
} }
...@@ -916,12 +913,20 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv, ...@@ -916,12 +913,20 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
/* Check whether I have to reroute the packet */ /* Check whether I have to reroute the packet */
if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) { if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) {
/* Linearize the skb before accessing it */ /* check if there is enough data before accessing it */
if (skb_linearize(skb) < 0) if (pskb_may_pull(skb, sizeof(struct unicast_packet) +
ETH_HLEN) < 0)
return 0; return 0;
ethhdr = (struct ethhdr *)(skb->data + ethhdr = (struct ethhdr *)(skb->data +
sizeof(struct unicast_packet)); sizeof(struct unicast_packet));
/* we don't have an updated route for this client, so we should
* not try to reroute the packet!!
*/
if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
return 1;
orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest); orig_node = transtable_search(bat_priv, NULL, ethhdr->h_dest);
if (!orig_node) { if (!orig_node) {
......
...@@ -45,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface, ...@@ -45,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
goto send_skb_err; goto send_skb_err;
if (!(hard_iface->net_dev->flags & IFF_UP)) { if (!(hard_iface->net_dev->flags & IFF_UP)) {
pr_warning("Interface %s is not up - can't send packet via that interface!\n", pr_warn("Interface %s is not up - can't send packet via that interface!\n",
hard_iface->net_dev->name); hard_iface->net_dev->name);
goto send_skb_err; goto send_skb_err;
} }
......
...@@ -206,6 +206,8 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr, ...@@ -206,6 +206,8 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (tt_local_entry) { if (tt_local_entry) {
tt_local_entry->last_seen = jiffies; tt_local_entry->last_seen = jiffies;
/* possibly unset the TT_CLIENT_PENDING flag */
tt_local_entry->common.flags &= ~TT_CLIENT_PENDING;
goto out; goto out;
} }
...@@ -2117,3 +2119,22 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, ...@@ -2117,3 +2119,22 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
} }
} }
} }
/* returns true whether we know that the client has moved from its old
* originator to another one. This entry is kept is still kept for consistency
* purposes
*/
bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr)
{
struct tt_global_entry *tt_global_entry;
bool ret = false;
tt_global_entry = tt_global_hash_find(bat_priv, addr);
if (!tt_global_entry)
goto out;
ret = tt_global_entry->common.flags & TT_CLIENT_ROAM;
tt_global_entry_free_ref(tt_global_entry);
out:
return ret;
}
...@@ -53,5 +53,7 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); ...@@ -53,5 +53,7 @@ bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst);
void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node, void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, uint8_t tt_num_changes, const unsigned char *tt_buff, uint8_t tt_num_changes,
uint8_t ttvn, uint16_t tt_crc); uint8_t ttvn, uint16_t tt_crc);
bool tt_global_client_is_roaming(struct bat_priv *bat_priv, uint8_t *addr);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
...@@ -137,7 +137,7 @@ struct neigh_node { ...@@ -137,7 +137,7 @@ struct neigh_node {
struct rcu_head rcu; struct rcu_head rcu;
struct orig_node *orig_node; struct orig_node *orig_node;
struct hard_iface *if_incoming; struct hard_iface *if_incoming;
spinlock_t tq_lock; /* protects: tq_recv, tq_index */ spinlock_t lq_update_lock; /* protects: tq_recv, tq_index */
}; };
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
......
...@@ -331,6 +331,14 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) ...@@ -331,6 +331,14 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
unicast_packet->ttvn = unicast_packet->ttvn =
(uint8_t)atomic_read(&orig_node->last_ttvn); (uint8_t)atomic_read(&orig_node->last_ttvn);
/* inform the destination node that we are still missing a correct route
* for this client. The destination will receive this packet and will
* try to reroute it because the ttvn contained in the header is less
* than the current one
*/
if (tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
unicast_packet->ttvn = unicast_packet->ttvn - 1;
if (atomic_read(&bat_priv->fragmentation) && if (atomic_read(&bat_priv->fragmentation) &&
data_len + sizeof(*unicast_packet) > data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) { neigh_node->if_incoming->net_dev->mtu) {
......
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