The following commit has been merged in the master branch:
commit b539e4cd3b08dddbaa2ba0f158eed3c7c2244eaf
Author: Marek Lindner <lindner_marek(a)yahoo.de>
Date: Sun Jun 26 21:15:13 2011 +0200
batman-adv: aggregation checks should use the primary_if pointer
The packet aggregation needs to ensure that only compatible packets
are aggregated. Some of the checks are based on the interface number
while assuming that the first interface also is the primary interface
which is not always the case.
This patch addresses the issue by using the primary_if pointer.
Reported-by: Antonio Quartulli <ordex(a)autistici.org>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index c583e04..69467fe 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -28,6 +28,7 @@
/* return true if new_packet can be aggregated with forw_packet */
static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
+ struct bat_priv *bat_priv,
int packet_len,
unsigned long send_time,
bool directlink,
@@ -37,6 +38,8 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
struct batman_packet *batman_packet =
(struct batman_packet *)forw_packet->skb->data;
int aggregated_bytes = forw_packet->packet_len + packet_len;
+ struct hard_iface *primary_if = NULL;
+ bool res = false;
/**
* we can aggregate the current packet to this aggregated packet
@@ -61,6 +64,10 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
* packet
*/
+ primary_if = primary_if_get_selected(bat_priv);
+ if (!primary_if)
+ goto out;
+
/* packets without direct link flag and high TTL
* are flooded through the net */
if ((!directlink) &&
@@ -70,8 +77,10 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
/* own packets originating non-primary
* interfaces leave only that interface */
((!forw_packet->own) ||
- (forw_packet->if_incoming->if_num == 0)))
- return true;
+ (forw_packet->if_incoming == primary_if))) {
+ res = true;
+ goto out;
+ }
/* if the incoming packet is sent via this one
* interface only - we still can aggregate */
@@ -84,11 +93,16 @@ static bool can_aggregate_with(const struct batman_packet *new_batman_packet,
* (= secondary interface packets in general) */
(batman_packet->flags & DIRECTLINK ||
(forw_packet->own &&
- forw_packet->if_incoming->if_num != 0)))
- return true;
+ forw_packet->if_incoming != primary_if))) {
+ res = true;
+ goto out;
+ }
}
- return false;
+out:
+ if (primary_if)
+ hardif_free_ref(primary_if);
+ return res;
}
/* create a new aggregated packet and add this packet to it */
@@ -210,6 +224,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
hlist_for_each_entry(forw_packet_pos, tmp_node,
&bat_priv->forw_bat_list, list) {
if (can_aggregate_with(batman_packet,
+ bat_priv,
packet_len,
send_time,
direct_link,
--
LinuxNextTracking
The following commit has been merged in the master branch:
commit f8bae99ee5030625a4e7f0d87784191882292f0e
Merge: 994635a137f637466d36a7c6272dae014a46a11c 44c4349a2a117b22a5c4087f2ac9faf10c575e17
Author: David S. Miller <davem(a)davemloft.net>
Date: Tue Jul 5 19:45:12 2011 -0700
Merge branch 'batman-adv/next' of git://git.open-mesh.org/linux-merge
--
LinuxNextTracking
The following commit has been merged in the master branch:
commit 8698529d209c43f6434592caf38733b84ccab5f3
Author: Antonio Quartulli <ordex(a)autistici.org>
Date: Sat Jun 25 19:09:12 2011 +0200
batman-adv: add_bcast_packet_to_list() takes the sending delay as parameter
In order to make possible to use the broadcast list for delayed sendings
the "delay" parameter is now provided instead of using 1 as hardcoded
value.
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 0ce090c..2cb98be 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1677,7 +1677,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
spin_unlock_bh(&orig_node->bcast_seqno_lock);
/* rebroadcast packet */
- add_bcast_packet_to_list(bat_priv, skb);
+ add_bcast_packet_to_list(bat_priv, skb, 1);
/* broadcast for me */
interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 7a2f082..2f62b2e 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -455,7 +455,7 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv,
* The skb is not consumed, so the caller should make sure that the
* skb is freed. */
int add_bcast_packet_to_list(struct bat_priv *bat_priv,
- const struct sk_buff *skb)
+ const struct sk_buff *skb, unsigned long delay)
{
struct hard_iface *primary_if = NULL;
struct forw_packet *forw_packet;
@@ -492,7 +492,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv,
/* how often did we send the bcast packet ? */
forw_packet->num_packets = 0;
- _add_bcast_packet_to_list(bat_priv, forw_packet, 1);
+ _add_bcast_packet_to_list(bat_priv, forw_packet, delay);
return NETDEV_TX_OK;
packet_free:
diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h
index 633224a..1f2d1e8 100644
--- a/net/batman-adv/send.h
+++ b/net/batman-adv/send.h
@@ -31,7 +31,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
int directlink,
struct hard_iface *if_outgoing);
int add_bcast_packet_to_list(struct bat_priv *bat_priv,
- const struct sk_buff *skb);
+ const struct sk_buff *skb, unsigned long delay);
void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(struct bat_priv *bat_priv,
const struct hard_iface *hard_iface);
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 2dcdbb7..3f20332 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -634,7 +634,7 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
bcast_packet->seqno =
htonl(atomic_inc_return(&bat_priv->bcast_seqno));
- add_bcast_packet_to_list(bat_priv, skb);
+ add_bcast_packet_to_list(bat_priv, skb, 1);
/* a copy is stored in the bcast list, therefore removing
* the original skb. */
--
LinuxNextTracking
The following commit has been merged in the master branch:
commit 5fbc1598c28555d2aa44bff0ac56ec3739401aff
Author: Antonio Quartulli <ordex(a)autistici.org>
Date: Fri Jun 17 16:11:27 2011 +0200
batman-adv: unify flags for tt_change/tt_local_entry/tt_global_entry
The tt_local_entry structure now has a 'flags' field. This helps to
unify the flags format to all the client related structures (tt_global_entry
and tt_change). The 'never_purge' field is now encoded in the 'flags' one.
To optimise the usage of this field, its length has been increased to 16bit
in order to use the eight leading bits (from 0 to 7) to store flags that
have to be sent on the wire, while the eight ending ones are used for local
computation only.
Moreover 'enum tt_change_flags' is now called 'enum tt_client_flags' and the
defined values apply to the tt_local_entry, tt_global_entry and the tt_change
'flags' field.
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index c5f081d..590e4a6 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -78,10 +78,13 @@ enum tt_query_flags {
TT_FULL_TABLE = 1 << 2
};
-/* TT_CHANGE flags */
-enum tt_change_flags {
- TT_CHANGE_DEL = 0x01,
- TT_CLIENT_ROAM = 0x02
+/* TT_CLIENT flags.
+ * Flags from 1 to 1 << 7 are sent on the wire, while flags from 1 << 8 to
+ * 1 << 15 are used for local computation only */
+enum tt_client_flags {
+ TT_CLIENT_DEL = 1 << 0,
+ TT_CLIENT_ROAM = 1 << 1,
+ TT_CLIENT_NOPURGE = 1 << 8
};
struct batman_packet {
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 5f1fcd5..4208dc7 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -211,13 +211,12 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr)
memcpy(tt_local_entry->addr, addr, ETH_ALEN);
tt_local_entry->last_seen = jiffies;
+ tt_local_entry->flags = NO_FLAGS;
atomic_set(&tt_local_entry->refcount, 2);
/* the batman interface mac address should never be purged */
if (compare_eth(addr, soft_iface->dev_addr))
- tt_local_entry->never_purge = 1;
- else
- tt_local_entry->never_purge = 0;
+ tt_local_entry->flags |= TT_CLIENT_NOPURGE;
hash_add(bat_priv->tt_local_hash, compare_ltt, choose_orig,
tt_local_entry, &tt_local_entry->hash_entry);
@@ -387,7 +386,7 @@ void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
if (!tt_local_entry)
goto out;
- tt_local_event(bat_priv, TT_CHANGE_DEL, tt_local_entry->addr, roaming);
+ tt_local_event(bat_priv, TT_CLIENT_DEL, tt_local_entry->addr, roaming);
tt_local_del(bat_priv, tt_local_entry, message);
out:
if (tt_local_entry)
@@ -410,14 +409,14 @@ static void tt_local_purge(struct bat_priv *bat_priv)
spin_lock_bh(list_lock);
hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
head, hash_entry) {
- if (tt_local_entry->never_purge)
+ if (tt_local_entry->flags & TT_CLIENT_NOPURGE)
continue;
if (!is_out_of_time(tt_local_entry->last_seen,
TT_LOCAL_TIMEOUT * 1000))
continue;
- tt_local_event(bat_priv, TT_CHANGE_DEL,
+ tt_local_event(bat_priv, TT_CLIENT_DEL,
tt_local_entry->addr, false);
atomic_dec(&bat_priv->num_local_tt);
bat_dbg(DBG_TT, bat_priv, "Deleting local "
@@ -1335,7 +1334,7 @@ static void _tt_update_changes(struct bat_priv *bat_priv,
int i;
for (i = 0; i < tt_num_changes; i++) {
- if ((tt_change + i)->flags & TT_CHANGE_DEL)
+ if ((tt_change + i)->flags & TT_CLIENT_DEL)
tt_global_del(bat_priv, orig_node,
(tt_change + i)->addr,
"tt removed by changes",
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 1cd2d39..460e583 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -30,8 +30,7 @@ void tt_local_add(struct net_device *soft_iface, const uint8_t *addr);
void tt_local_remove(struct bat_priv *bat_priv,
const uint8_t *addr, const char *message, bool roaming);
int tt_local_seq_print_text(struct seq_file *seq, void *offset);
-void tt_global_add_orig(struct bat_priv *bat_priv,
- struct orig_node *orig_node,
+void tt_global_add_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
const unsigned char *tt_buff, int tt_buff_len);
int tt_global_add(struct bat_priv *bat_priv,
struct orig_node *orig_node, const unsigned char *addr,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 85cf122..25bd1db3 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -224,7 +224,7 @@ struct socket_packet {
struct tt_local_entry {
uint8_t addr[ETH_ALEN];
unsigned long last_seen;
- char never_purge;
+ uint16_t flags;
atomic_t refcount;
struct rcu_head rcu;
struct hlist_node hash_entry;
@@ -234,7 +234,7 @@ struct tt_global_entry {
uint8_t addr[ETH_ALEN];
struct orig_node *orig_node;
uint8_t ttvn;
- uint8_t flags; /* only TT_GLOBAL_ROAM is used */
+ uint16_t flags; /* only TT_GLOBAL_ROAM is used */
unsigned long roam_at; /* time at which TT_GLOBAL_ROAM was set */
atomic_t refcount;
struct rcu_head rcu;
--
LinuxNextTracking