diff options
author | Antonio Quartulli <ordex@autistici.org> | 2011-06-25 21:37:18 -0400 |
---|---|---|
committer | Antonio Quartulli <ordex@autistici.org> | 2012-11-07 14:00:21 -0500 |
commit | c384ea3ec930ef11060a7308fbbd02b4871384f9 (patch) | |
tree | 14764f1a722c0a5633aa9dc5cebc19081703d446 /net/batman-adv/routing.c | |
parent | 5c3a0e5535933349a5d6e6bc8b704e0611f21d3f (diff) |
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>
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r-- | net/batman-adv/routing.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 859679b08286..1826699314b7 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "vis.h" | 28 | #include "vis.h" |
29 | #include "unicast.h" | 29 | #include "unicast.h" |
30 | #include "bridge_loop_avoidance.h" | 30 | #include "bridge_loop_avoidance.h" |
31 | #include "distributed-arp-table.h" | ||
31 | 32 | ||
32 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 33 | static int batadv_route_unicast_packet(struct sk_buff *skb, |
33 | struct batadv_hard_iface *recv_if); | 34 | struct batadv_hard_iface *recv_if); |
@@ -985,11 +986,13 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
985 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); | 986 | struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface); |
986 | struct batadv_unicast_packet *unicast_packet; | 987 | struct batadv_unicast_packet *unicast_packet; |
987 | int hdr_size = sizeof(*unicast_packet); | 988 | int hdr_size = sizeof(*unicast_packet); |
989 | bool is4addr; | ||
988 | 990 | ||
989 | unicast_packet = (struct batadv_unicast_packet *)skb->data; | 991 | unicast_packet = (struct batadv_unicast_packet *)skb->data; |
990 | 992 | ||
993 | is4addr = unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR; | ||
991 | /* the caller function should have already pulled 2 bytes */ | 994 | /* the caller function should have already pulled 2 bytes */ |
992 | if (unicast_packet->header.packet_type == BATADV_UNICAST_4ADDR) | 995 | if (is4addr) |
993 | hdr_size = sizeof(struct batadv_unicast_4addr_packet); | 996 | hdr_size = sizeof(struct batadv_unicast_4addr_packet); |
994 | 997 | ||
995 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) | 998 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) |
@@ -1000,9 +1003,17 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
1000 | 1003 | ||
1001 | /* packet for me */ | 1004 | /* packet for me */ |
1002 | if (batadv_is_my_mac(unicast_packet->dest)) { | 1005 | if (batadv_is_my_mac(unicast_packet->dest)) { |
1006 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, | ||
1007 | hdr_size)) | ||
1008 | goto rx_success; | ||
1009 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, | ||
1010 | hdr_size)) | ||
1011 | goto rx_success; | ||
1012 | |||
1003 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 1013 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, |
1004 | NULL); | 1014 | NULL); |
1005 | 1015 | ||
1016 | rx_success: | ||
1006 | return NET_RX_SUCCESS; | 1017 | return NET_RX_SUCCESS; |
1007 | } | 1018 | } |
1008 | 1019 | ||
@@ -1038,8 +1049,17 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, | |||
1038 | if (!new_skb) | 1049 | if (!new_skb) |
1039 | return NET_RX_SUCCESS; | 1050 | return NET_RX_SUCCESS; |
1040 | 1051 | ||
1052 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, new_skb, | ||
1053 | hdr_size)) | ||
1054 | goto rx_success; | ||
1055 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, new_skb, | ||
1056 | hdr_size)) | ||
1057 | goto rx_success; | ||
1058 | |||
1041 | batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, | 1059 | batadv_interface_rx(recv_if->soft_iface, new_skb, recv_if, |
1042 | sizeof(struct batadv_unicast_packet), NULL); | 1060 | sizeof(struct batadv_unicast_packet), NULL); |
1061 | |||
1062 | rx_success: | ||
1043 | return NET_RX_SUCCESS; | 1063 | return NET_RX_SUCCESS; |
1044 | } | 1064 | } |
1045 | 1065 | ||
@@ -1131,9 +1151,16 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1131 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) | 1151 | if (batadv_bla_is_backbone_gw(skb, orig_node, hdr_size)) |
1132 | goto out; | 1152 | goto out; |
1133 | 1153 | ||
1154 | if (batadv_dat_snoop_incoming_arp_request(bat_priv, skb, hdr_size)) | ||
1155 | goto rx_success; | ||
1156 | if (batadv_dat_snoop_incoming_arp_reply(bat_priv, skb, hdr_size)) | ||
1157 | goto rx_success; | ||
1158 | |||
1134 | /* broadcast for me */ | 1159 | /* broadcast for me */ |
1135 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, | 1160 | batadv_interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size, |
1136 | orig_node); | 1161 | orig_node); |
1162 | |||
1163 | rx_success: | ||
1137 | ret = NET_RX_SUCCESS; | 1164 | ret = NET_RX_SUCCESS; |
1138 | goto out; | 1165 | goto out; |
1139 | 1166 | ||