[B.A.T.M.A.N.] [RFC] batman-adv: create a unique entry point for unicast packets
by Antonio Quartulli
Right now in batman-adv we have several unicast packets 'subtypes' (UNICAST,
UNICAST_FRAG, TT_QUERY and ROAM_ADV) that in the initial part of the rx path
need the same treatment (e.g. size check, destination check, is_for_me? check,
etc.).
For this reason we would like to propose to unify the rx paths in this early
stage. This change would reduce code duplication and avoid introducing bugs
(e.g. it is easy to add a check for the TT_QUERY and forget to do the same for
the UNICAST packet).
It could be the case that to better address this issue we would need to slightly
redesign packet format. So we would probably need to wait until the next (and
hopefully last needed) compatibility breakage.
But for now you get this a proposal :-)
Reported-by: Martin Hundebøll <martin(a)hundeboll.net>
Reported-by: Marek Lindner <lindner_marek(a)yahoo.de>
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
main.c | 17 +++++++++-----
routing.c | 74 ++++++++++++++++++++++++++++++++-----------------------------
routing.h | 10 ++-------
3 files changed, 52 insertions(+), 49 deletions(-)
diff --git a/main.c b/main.c
index 13c88b2..da1b728 100644
--- a/main.c
+++ b/main.c
@@ -277,18 +277,23 @@ static void batadv_recv_handler_init(void)
/* batman icmp packet */
batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
- /* unicast packet */
- batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
- /* fragmented unicast packet */
- batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet;
/* broadcast packet */
batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
/* vis packet */
batadv_rx_handler[BATADV_VIS] = batadv_recv_vis_packet;
+
+ /* all the unicast packets have now a single entry point that will make
+ * all the common checks on the packets. It will then invoke the proper
+ * parser function based on the real packet type
+ */
+ /* unicast packet */
+ batadv_rx_handler[BATADV_UNICAST] = batadv_recv_generic_unicast;
+ /* fragmented unicast packet */
+ batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_generic_unicast;
/* Translation table query (request or response) */
- batadv_rx_handler[BATADV_TT_QUERY] = batadv_recv_tt_query;
+ batadv_rx_handler[BATADV_TT_QUERY] = batadv_recv_generic_unicast;
/* Roaming advertisement */
- batadv_rx_handler[BATADV_ROAM_ADV] = batadv_recv_roam_adv;
+ batadv_rx_handler[BATADV_ROAM_ADV] = batadv_recv_generic_unicast;
}
int
diff --git a/routing.c b/routing.c
index bc2b88b..25ee461 100644
--- a/routing.c
+++ b/routing.c
@@ -579,12 +579,12 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
return router;
}
-int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
+static int batadv_recv_tt_query(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_tt_query_packet *tt_query;
uint16_t tt_size;
- struct ethhdr *ethhdr;
char tt_flag;
size_t packet_size;
@@ -597,16 +597,6 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
if (skb_cow(skb, sizeof(struct batadv_tt_query_packet)) < 0)
goto out;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
-
- /* packet with unicast indication but broadcast recipient */
- if (is_broadcast_ether_addr(ethhdr->h_dest))
- goto out;
-
- /* packet with broadcast sender address */
- if (is_broadcast_ether_addr(ethhdr->h_source))
- goto out;
-
tt_query = (struct batadv_tt_query_packet *)skb->data;
switch (tt_query->flags & BATADV_TT_QUERY_TYPE_MASK) {
@@ -669,28 +659,18 @@ out:
return NET_RX_DROP;
}
-int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if)
+static int batadv_recv_roam_adv(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_roam_adv_packet *roam_adv_packet;
struct batadv_orig_node *orig_node;
- struct ethhdr *ethhdr;
/* drop packet if it has not necessary minimum size */
if (unlikely(!pskb_may_pull(skb,
sizeof(struct batadv_roam_adv_packet))))
goto out;
- ethhdr = (struct ethhdr *)skb_mac_header(skb);
-
- /* packet with unicast indication but broadcast recipient */
- if (is_broadcast_ether_addr(ethhdr->h_dest))
- goto out;
-
- /* packet with broadcast sender address */
- if (is_broadcast_ether_addr(ethhdr->h_source))
- goto out;
-
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data;
@@ -1008,21 +988,17 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
return 1;
}
-int batadv_recv_unicast_packet(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if)
+static int batadv_recv_unicast_packet(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_unicast_packet *unicast_packet;
int hdr_size = sizeof(*unicast_packet);
-
- if (batadv_check_unicast_packet(skb, hdr_size) < 0)
- return NET_RX_DROP;
+ unicast_packet = (struct batadv_unicast_packet *)skb->data;
if (!batadv_check_unicast_ttvn(bat_priv, skb))
return NET_RX_DROP;
- unicast_packet = (struct batadv_unicast_packet *)skb->data;
-
/* packet for me */
if (batadv_is_my_mac(unicast_packet->dest)) {
batadv_interface_rx(recv_if->soft_iface, skb, recv_if,
@@ -1033,8 +1009,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
return batadv_route_unicast_packet(skb, recv_if);
}
-int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if)
+static int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if)
{
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
struct batadv_unicast_frag_packet *unicast_packet;
@@ -1042,10 +1018,10 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
struct sk_buff *new_skb = NULL;
int ret;
- if (batadv_check_unicast_packet(skb, hdr_size) < 0)
+ if (!batadv_check_unicast_ttvn(bat_priv, skb))
return NET_RX_DROP;
- if (!batadv_check_unicast_ttvn(bat_priv, skb))
+ if (unlikely(!pskb_may_pull(skb, hdr_size)))
return NET_RX_DROP;
unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
@@ -1211,3 +1187,31 @@ int batadv_recv_vis_packet(struct sk_buff *skb,
*/
return NET_RX_DROP;
}
+
+int batadv_recv_generic_unicast(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if)
+{
+ struct batadv_unicast_packet *unicast_packet;
+ int to_pull = sizeof(*unicast_packet);
+
+ /* pull only what we need to check the common fields in each unicast
+ * packet
+ */
+ if (batadv_check_unicast_packet(skb, to_pull) < 0)
+ return NET_RX_DROP;
+
+ unicast_packet = (struct batadv_unicast_packet *)skb->data;
+
+ switch (unicast_packet->header.packet_type) {
+ case BATADV_UNICAST:
+ return batadv_recv_unicast_packet(skb, recv_if);
+ case BATADV_UNICAST_FRAG:
+ return batadv_recv_ucast_frag_packet(skb, recv_if);
+ case BATADV_TT_QUERY:
+ return batadv_recv_tt_query(skb, recv_if);
+ case BATADV_ROAM_ADV:
+ return batadv_recv_roam_adv(skb, recv_if);
+ }
+ /* did we get an unknown unicast packet ? */
+ return NET_RX_DROP;
+}
diff --git a/routing.h b/routing.h
index 9262279..2e7e1fe 100644
--- a/routing.h
+++ b/routing.h
@@ -29,18 +29,12 @@ void batadv_update_route(struct batadv_priv *bat_priv,
struct batadv_neigh_node *neigh_node);
int batadv_recv_icmp_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
-int batadv_recv_unicast_packet(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if);
-int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if);
int batadv_recv_bcast_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
int batadv_recv_vis_packet(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
-int batadv_recv_tt_query(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if);
-int batadv_recv_roam_adv(struct sk_buff *skb,
- struct batadv_hard_iface *recv_if);
+int batadv_recv_generic_unicast(struct sk_buff *skb,
+ struct batadv_hard_iface *recv_if);
struct batadv_neigh_node *
batadv_find_router(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
--
1.7.9.4
9 years, 11 months
[B.A.T.M.A.N.] tt log
by Martin Hundebøll
Hi Antonio
I encountered the tt loop in kvm this evening, so I captured some tiny logs for you. The topology is a small chain:
n1 <-> n2 <-> n3 <-> n4
The nodes run clean batman-adv from master (5deb69f60f388055982a1da6dce876049f86841d) with no catwoman or whatever compiled in :)
--
Kind Regards
Martin Hundebøll
Frederiks Allé 99A, 1.th
8000 Aarhus C
Denmark
+45 61 65 54 61
martin(a)hundeboll.net
9 years, 11 months
[B.A.T.M.A.N.] [B.A.T.M.A.N] OGM problem and documentation
by Arthur Lambert
Hi,
I am testing Batman Advance (Batman release 2012 1.0) and I am trying
to measure signaling on some topology of VMs. I have 81 nodes (Debian,
3.0.9) with KVM virtualization. My topology is something like this :
http://imgur.com/Xh1gM
I have a topology with an adjacency matrix of maximum 4 as you can see
on my screenshot. I record on each VM signaling received and sent. On
some VM, my node send OGM at each "orig_interval" but does not receive
any OGM at all.
Is it normal ?
Moreover, I have found a wonderful documention here :
http://gitorious.org/batman-adv-doc. Unfortunatly, it is not maintened
since two years. I have also found some papers which describe your
protocol, but most of the time, the paper are too old or not correct
in the protocol description. At this moment, my first source of
information is the code. Can you advise me a good paper or
documentation on the architecture and features of Batman Advance set
apart your twiki.
Kind regards, my apology for my English.
--
Arthur
9 years, 11 months
[B.A.T.M.A.N.] pull request: batman-adv 2012-07-01
by Antonio Quartulli
Hello David,
this should be our last planned pull request intended for net-next/linux-3.6 :-)
In this batch you have patch 15/16 that fixes a variable declaration
in the ethtool support code; patch 16/16 that fixes a non-critical bug which
makes nodes send unicast packets with an uninitialised header field.
The rest is the last part of our namespace renaming operation plus a couple of
style fixes.
Please let me know if there are problems!
Thank you very much,
Antonio
The following changes since commit a59a4d1921664da63d801ba477950114c71c88c9:
phy: add the EEE support and the way to access to the MMD registers. (2012-07-01 03:34:50 -0700)
are available in the git repository at:
git://git.open-mesh.org/linux-merge.git tags/batman-adv-for-davem
for you to fetch changes up to 162d549c6905485262635fe594db337efb2828b5:
batman-adv: Don't leak information through uninitialized packet fields (2012-07-01 22:47:24 +0200)
----------------------------------------------------------------
Included changes:
- The last batch of patches aimed to clean the batman-adv namespace
- a couple of style fixes
- a fix for the ethtool support
- a fix to prevent sending unicast packets with an uninitialised header
field
----------------------------------------------------------------
Marek Lindner (1):
batman-adv: fix counter summary length
Sven Eckelmann (15):
batman-adv: Prefix gateway enum with BATADV_
batman-adv: Prefix hard-interface enum with BATADV_
batman-adv: Prefix types enum with BATADV_
batman-adv: Prefix packet enum with BATADV_
batman-adv: Prefix main enum with BATADV_
batman-adv: Prefix local debugfs structs with batadv_
batman-adv: Prefix hash struct and typedef with batadv_
batman-adv: Prefix local sysfs struct with batadv_
batman-adv: Prefix packet structs with batadv_
batman-adv: Prefix types structs with batadv_
batman-adv: Transform BATADV_LOG_BUFF(idx) into function
batman-adv: Remove bat_ prefix from bat_{debugfs, sysfs}.{c, h}
batman-adv: Remove space before semicolon
batman-adv: Fix alignment after opened parentheses
batman-adv: Don't leak information through uninitialized packet fields
net/batman-adv/Makefile | 4 +-
net/batman-adv/bat_iv_ogm.c | 459 +++++++--------
net/batman-adv/bitarray.c | 6 +-
net/batman-adv/bridge_loop_avoidance.c | 302 +++++-----
net/batman-adv/bridge_loop_avoidance.h | 48 +-
net/batman-adv/{bat_debugfs.c => debugfs.c} | 76 ++-
net/batman-adv/{bat_debugfs.h => debugfs.h} | 0
net/batman-adv/gateway_client.c | 127 +++--
net/batman-adv/gateway_client.h | 24 +-
net/batman-adv/gateway_common.c | 2 +-
net/batman-adv/gateway_common.h | 8 +-
net/batman-adv/hard-interface.c | 125 +++--
net/batman-adv/hard-interface.h | 28 +-
net/batman-adv/hash.c | 12 +-
net/batman-adv/hash.h | 33 +-
net/batman-adv/icmp_socket.c | 81 +--
net/batman-adv/icmp_socket.h | 4 +-
net/batman-adv/main.c | 82 +--
net/batman-adv/main.h | 63 ++-
net/batman-adv/originator.c | 151 ++---
net/batman-adv/originator.h | 37 +-
net/batman-adv/packet.h | 132 ++---
net/batman-adv/routing.c | 300 +++++-----
net/batman-adv/routing.h | 52 +-
net/batman-adv/send.c | 75 +--
net/batman-adv/send.h | 12 +-
net/batman-adv/soft-interface.c | 55 +-
net/batman-adv/soft-interface.h | 2 +-
net/batman-adv/{bat_sysfs.c => sysfs.c} | 134 +++--
net/batman-adv/{bat_sysfs.h => sysfs.h} | 6 +-
net/batman-adv/translation-table.c | 808 ++++++++++++++-------------
net/batman-adv/translation-table.h | 43 +-
net/batman-adv/types.h | 154 ++---
net/batman-adv/unicast.c | 95 ++--
net/batman-adv/unicast.h | 19 +-
net/batman-adv/vis.c | 284 +++++-----
net/batman-adv/vis.h | 12 +-
37 files changed, 2011 insertions(+), 1844 deletions(-)
rename net/batman-adv/{bat_debugfs.c => debugfs.c} (81%)
rename net/batman-adv/{bat_debugfs.h => debugfs.h} (100%)
rename net/batman-adv/{bat_sysfs.c => sysfs.c} (85%)
rename net/batman-adv/{bat_sysfs.h => sysfs.h} (89%)
9 years, 11 months
[B.A.T.M.A.N.] [PATCHv3 0/3] new feature: Speedy Join 2012-07-01
by Antonio Quartulli
Hello people,
this is the third version of the Speedy Join patchset below
Changes history:
v1 -> v2:
- indentation and style has been fixed taking into consideration Sven's
suggestions
- Old patch 4 has been removed. TT flags do not really need to be carry along
with the tt_entry in a roaming_adv packet. (at least this is not needed for
the purpose of this feature). A roaming client will be marked as ROAM on
the new mesh node and therefore it will be already purged if nobody claims it
v2 -> v3:
- patch 1 and 2 have been merged in 1/3. Changes were all related to the new
refcounting mechanism. ..orig_entry_find() function has been improved as well as
..orig_entry_add() (it does internally check if the orig_entry already exists or
not) and ..has_orig() (now it does use ..orig_entry_find()).
- patch 2/3 has been modified to take into consideration the change above
- temp timeout changed to an absolute value instead of being computed as product
of the local orig_interval times a constant factor.
Thank you,
Antonio
Antonio Quartulli (3):
batman-adv: add reference counting for type batadv_tt_orig_list_entry
batman-adv: detect not yet announced clients
batman-adv: change interface_rx to get orig node
main.h | 1 +
packet.h | 1 +
routing.c | 10 +--
soft-interface.c | 6 +-
soft-interface.h | 5 +-
translation-table.c | 196 +++++++++++++++++++++++++++++++++++++--------------
translation-table.h | 4 +-
types.h | 2 +
8 files changed, 163 insertions(+), 62 deletions(-)
--
1.7.9.4
9 years, 11 months
[B.A.T.M.A.N.] [PATCH 1/2 stable 3.1-3.2] batman-adv: fix skb->data assignment
by Antonio Quartulli
commit 2c995ff892313009e336ecc8ec3411022f5b1c39 upstream.
skb_linearize(skb) possibly rearranges the skb internal data and then changes
the skb->data pointer value. For this reason any other pointer in the code that
was assigned skb->data before invoking skb_linearise(skb) must be re-assigned.
In the current tt_query message handling code this is not done and therefore, in
case of skb linearization, the pointer used to handle the packet header ends up
in pointing to poisoned memory. The packet is then dropped but the
translation-table mechanism is corrupted.
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
Hello,
the patch committed upstream already contains Cc: stable(a)vger.kernel.org but
that patch does apply only on 3.5, 3.4 and 3.3.
This patch is a backport for kernel versions 3.1 and 3.2
Thank you,
Antonio
net/batman-adv/routing.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 0f32c81..55136e5 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -1246,6 +1246,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
/* packet needs to be linearised to access the TT changes */
if (skb_linearize(skb) < 0)
goto out;
+ /* skb_linearize() possibly changed skb->data */
+ tt_query = (struct tt_query_packet *)skb->data;
if (is_my_mac(tt_query->dst))
handle_tt_response(bat_priv, tt_query);
--
1.7.9.4
9 years, 11 months