batman-adv: Distributed ARP Table - add snooping functions for ARP messages
In case of an ARP message going in or out the soft_iface, it is intercepted and a special action is performed. In particular the DHT helper functions previously implemented are used to store all the ARP entries belonging to the network in order to provide a fast and unicast lookup instead of the classic broadcast flooding mechanism. Each node stores the entries it is responsible for (following the DHT rules) in its soft_iface ARP table. This makes it possible to reuse the kernel data structures and functions for ARP management. Signed-off-by: Antonio Quartulli <ordex@autistici.org>
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "vis.h"
|
||||
#include "unicast.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
|
||||
static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if);
|
||||
@@ -985,11 +986,13 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
||||
struct batadv_unicast_packet *unicast_packet;
|
||||
int hdr_size = sizeof(*unicast_packet);
|
||||
bool is4addr;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
|
||||
is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR;
|
||||
/* the caller function should have already pulled 2 bytes */
|
||||
if (unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR)
|
||||
if (is4addr)
|
||||
hdr_size = sizeof(struct batadv_unicast_4addr_packet);
|
||||
|
||||
if (batadv_check_unicast_packet(skb, hdr_size) < 0)
|
||||
@@ -1000,9 +1003,17 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||
|
||||
/* packet for me */
|
||||
if (batadv_is_my_mac(unicast_packet->dest)) {
|
||||
if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb,
|
||||
hdr_size))
|
||||
goto rx_success;
|
||||
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb,
|
||||
hdr_size))
|
||||
goto rx_success;
|
||||
|
||||
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
||||
NULL);
|
||||
|
||||
rx_success:
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1038,8 +1049,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
|
||||
if (!new_skb)
|
||||
return NET_RX_SUCCESS;
|
||||
|
||||
if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb,
|
||||
hdr_size))
|
||||
goto rx_success;
|
||||
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb,
|
||||
hdr_size))
|
||||
goto rx_success;
|
||||
|
||||
batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if,
|
||||
sizeof(struct batadv_unicast_packet), NULL);
|
||||
|
||||
rx_success:
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1131,9 +1151,16 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||
if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size))
|
||||
goto out;
|
||||
|
||||
if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size))
|
||||
goto rx_success;
|
||||
if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size))
|
||||
goto rx_success;
|
||||
|
||||
/* broadcast for me */
|
||||
batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size,
|
||||
orig_node);
|
||||
|
||||
rx_success:
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto out;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user