[1/3] batman-adv: Allow promiscuous reception of unicast packets
Commit Message
From: Linus Lüssing <linus.luessing@ascom.ch>
A very mobile node may want to enable this to increase the probability
of unicast data reception on the last hop, especially when such a mobile
node moves towards the sender.
The mobile node needs to place its hard-interfaces utilized by
batman-adv into promisc-mode to let this optimization take effect. Be
aware, that doing so will cost your devices more processing power.
It also increases the probability of succesful reception a lot, if there
are (multiple) shorter, alternate but slightly "worse" paths, too. As
WiFi is a broadcast medium, there can be a quite good chance to receive
a packet from one of the nodes on the path to the receiver already.
Luckily batman-adv is running in kernelspace, therefore it does not make
much of a performance difference, even on embedded devices.
To let this feature take effect, place your WiFi interface in
promiscuous mode (e.g. 'ip link set wlan0 promisc on'/'ifconfig wlan0
promisc').
Signed-off-by: Linus Lüssing <linus.luessing@ascom.ch>
---
routing.c | 17 +++++++++++++----
1 files changed, 13 insertions(+), 4 deletions(-)
@@ -1124,7 +1124,7 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size)
/* not for me */
if (!is_my_mac(ethhdr->h_dest))
- return -1;
+ return 1;
return 0;
}
@@ -1214,8 +1214,10 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
{
struct unicast_packet *unicast_packet;
int hdr_size = sizeof(struct unicast_packet);
+ int check_ret;
- if (check_unicast_packet(skb, hdr_size) < 0)
+ check_ret = check_unicast_packet(skb, hdr_size);
+ if (check_ret < 0)
return NET_RX_DROP;
unicast_packet = (struct unicast_packet *)skb->data;
@@ -1226,6 +1228,9 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if)
return NET_RX_SUCCESS;
}
+ if (check_ret)
+ return NET_RX_DROP;
+
return route_unicast_packet(skb, recv_if, hdr_size);
}
@@ -1235,9 +1240,10 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
struct unicast_frag_packet *unicast_packet;
int hdr_size = sizeof(struct unicast_frag_packet);
struct sk_buff *new_skb = NULL;
- int ret;
+ int ret, check_ret;
- if (check_unicast_packet(skb, hdr_size) < 0)
+ check_ret = check_unicast_packet(skb, hdr_size);
+ if (check_ret < 0)
return NET_RX_DROP;
unicast_packet = (struct unicast_frag_packet *)skb->data;
@@ -1259,6 +1265,9 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if)
return NET_RX_SUCCESS;
}
+ if (check_ret)
+ return NET_RX_DROP;
+
return route_unicast_packet(skb, recv_if, hdr_size);
}