summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-15 02:15:33 +0400
committerDavid S. Miller <davem@davemloft.net>2012-05-15 02:15:33 +0400
commit748336087374ca7e5369f310745fa1d3b4a8cbf7 (patch)
treea13671709fa2cf67d7802526f2ebd4e282aa6010 /net
parentc597f6653d5734c11b1e3217c7619a37e96e5a1f (diff)
parent521251f2f5fa16747cc21e71580e404af855d140 (diff)
downloadlinux-748336087374ca7e5369f310745fa1d3b4a8cbf7.tar.xz
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
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/bat_iv_ogm.c9
-rw-r--r--net/batman-adv/hard-interface.c6
-rw-r--r--net/batman-adv/main.h2
-rw-r--r--net/batman-adv/originator.c1
-rw-r--r--net/batman-adv/routing.c27
-rw-r--r--net/batman-adv/send.c4
-rw-r--r--net/batman-adv/translation-table.c21
-rw-r--r--net/batman-adv/translation-table.h2
-rw-r--r--net/batman-adv/types.h2
-rw-r--r--net/batman-adv/unicast.c8
10 files changed, 59 insertions, 23 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index abd10c490fd9..dc53798ebb47 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -43,7 +43,6 @@ static struct neigh_node *bat_iv_ogm_neigh_new(struct hard_iface *hard_iface,
goto out;
INIT_LIST_HEAD(&neigh_node->bonding_list);
- spin_lock_init(&neigh_node->tq_lock);
neigh_node->orig_node = orig_neigh;
neigh_node->if_incoming = hard_iface;
@@ -637,12 +636,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
if (is_duplicate)
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,
&tmp_neigh_node->tq_index, 0);
tmp_neigh_node->tq_avg =
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) {
@@ -668,12 +667,12 @@ static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
orig_node->flags = batman_ogm_packet->flags;
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,
&neigh_node->tq_index,
batman_ogm_packet->tq);
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) {
orig_node->last_ttl = batman_ogm_packet->header.ttl;
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 0b84bb1b62c4..dc334fa89847 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -173,9 +173,9 @@ static void check_known_mac_addr(const struct net_device *net_dev)
net_dev->dev_addr))
continue;
- pr_warning("The newly added mac address (%pM) already exists on: %s\n",
- 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("The newly added mac address (%pM) already exists on: %s\n",
+ net_dev->dev_addr, hard_iface->net_dev->name);
+ pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n");
}
rcu_read_unlock();
}
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index fd83acd48b28..f4a3ec003479 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -28,7 +28,7 @@
#define DRIVER_DEVICE "batman-adv"
#ifndef SOURCE_VERSION
-#define SOURCE_VERSION "2012.1.0"
+#define SOURCE_VERSION "2012.2.0"
#endif
/* B.A.T.M.A.N. parameters */
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index f4b62011ca3f..41147942ba53 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -99,6 +99,7 @@ struct neigh_node *batadv_neigh_node_new(struct 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);
/* extra reference for return */
atomic_set(&neigh_node->refcount, 2);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 7ed9d8f92916..840e2c64a301 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -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) ||
(seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
- 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 {
+ if (!has_timed_out(*last_reset, RESET_PROTECTION_MS))
return 1;
- }
+
+ *last_reset = jiffies;
+ bat_dbg(DBG_BATMAN, bat_priv,
+ "old packet received, start protection\n");
}
+
return 0;
}
@@ -916,12 +913,20 @@ static int check_unicast_ttvn(struct bat_priv *bat_priv,
/* Check whether I have to reroute the packet */
if (seq_before(unicast_packet->ttvn, curr_ttvn) || tt_poss_change) {
- /* Linearize the skb before accessing it */
- if (skb_linearize(skb) < 0)
+ /* check if there is enough data before accessing it */
+ if (pskb_may_pull(skb, sizeof(struct unicast_packet) +
+ ETH_HLEN) < 0)
return 0;
ethhdr = (struct ethhdr *)(skb->data +
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);
if (!orig_node) {
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 8e74d9763be3..f47299f22c68 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -45,8 +45,8 @@ int send_skb_packet(struct sk_buff *skb, struct hard_iface *hard_iface,
goto send_skb_err;
if (!(hard_iface->net_dev->flags & IFF_UP)) {
- pr_warning("Interface %s is not up - can't send packet via that interface!\n",
- hard_iface->net_dev->name);
+ pr_warn("Interface %s is not up - can't send packet via that interface!\n",
+ hard_iface->net_dev->name);
goto send_skb_err;
}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 2cb46f0bb163..a66c2dcd1088 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -206,6 +206,8 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
if (tt_local_entry) {
tt_local_entry->last_seen = jiffies;
+ /* possibly unset the TT_CLIENT_PENDING flag */
+ tt_local_entry->common.flags &= ~TT_CLIENT_PENDING;
goto out;
}
@@ -2117,3 +2119,22 @@ request_table:
}
}
}
+
+/* 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;
+}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 593d1b31217c..c43374dc364d 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -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,
const unsigned char *tt_buff, uint8_t tt_num_changes,
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_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 66a3750aa9e7..61308e8016ff 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -137,7 +137,7 @@ struct neigh_node {
struct rcu_head rcu;
struct orig_node *orig_node;
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
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 676f6a626b2c..74175c210858 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -331,6 +331,14 @@ find_router:
unicast_packet->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) &&
data_len + sizeof(*unicast_packet) >
neigh_node->if_incoming->net_dev->mtu) {