30 #include <linux/if_arp.h>
32 #include <linux/if_vlan.h>
34 static const uint8_t batadv_announce_mac[4] = {0x43, 0x05, 0x43, 0x05};
37 static void batadv_bla_send_announce(
struct batadv_priv *bat_priv,
38 struct batadv_backbone_gw *backbone_gw);
43 const unsigned char *
key =
data;
61 static inline uint32_t batadv_choose_backbone_gw(
const void *data,
64 const unsigned char *key =
data;
83 static int batadv_compare_backbone_gw(
const struct hlist_node *
node,
89 return (
memcmp(data1, data2,
ETH_ALEN +
sizeof(
short)) == 0 ? 1 : 0);
93 static int batadv_compare_claim(
const struct hlist_node *node,
96 const void *data1 =
container_of(node,
struct batadv_claim,
99 return (
memcmp(data1, data2,
ETH_ALEN +
sizeof(
short)) == 0 ? 1 : 0);
103 static void batadv_backbone_gw_free_ref(
struct batadv_backbone_gw *backbone_gw)
110 static void batadv_claim_free_rcu(
struct rcu_head *rcu)
112 struct batadv_claim *claim;
116 batadv_backbone_gw_free_ref(claim->backbone_gw);
121 static void batadv_claim_free_ref(
struct batadv_claim *claim)
124 call_rcu(&claim->rcu, batadv_claim_free_rcu);
133 static struct batadv_claim *batadv_claim_hash_find(
struct batadv_priv *bat_priv,
134 struct batadv_claim *data)
139 struct batadv_claim *claim;
140 struct batadv_claim *claim_tmp =
NULL;
146 index = batadv_choose_claim(data, hash->
size);
150 hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
151 if (!batadv_compare_claim(&claim->hash_entry, data))
173 static struct batadv_backbone_gw *
174 batadv_backbone_hash_find(
struct batadv_priv *bat_priv,
180 struct batadv_backbone_gw search_entry, *backbone_gw;
181 struct batadv_backbone_gw *backbone_gw_tmp =
NULL;
188 search_entry.vid =
vid;
190 index = batadv_choose_backbone_gw(&search_entry, hash->
size);
194 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
195 if (!batadv_compare_backbone_gw(&backbone_gw->hash_entry,
202 backbone_gw_tmp = backbone_gw;
207 return backbone_gw_tmp;
212 batadv_bla_del_backbone_claims(
struct batadv_backbone_gw *backbone_gw)
217 struct batadv_claim *claim;
221 hash = backbone_gw->bat_priv->bla.claim_hash;
225 for (i = 0; i < hash->
size; i++) {
229 spin_lock_bh(list_lock);
233 if (claim->backbone_gw != backbone_gw)
236 batadv_claim_free_ref(claim);
239 spin_unlock_bh(list_lock);
243 backbone_gw->crc = BATADV_BLA_CRC_INIT;
254 short vid,
int claimtype)
264 primary_if = batadv_primary_if_get_selected(bat_priv);
268 memcpy(&local_claim_dest, &bat_priv->bla.claim_dest,
269 sizeof(local_claim_dest));
270 local_claim_dest.type = claimtype;
293 ethhdr = (
struct ethhdr *)skb->
data;
304 "bla_send_claim(): CLAIM %pM on vid %d\n", mac, vid);
312 "bla_send_claim(): UNCLAIM %pM on vid %d\n", mac,
321 "bla_send_claim(): ANNOUNCE of %pM on vid %d\n",
332 "bla_send_claim(): REQUEST of %pM to %pMon vid %d\n",
339 skb = vlan_insert_tag(skb, vid);
341 skb_reset_mac_header(skb);
351 batadv_hardif_free_ref(primary_if);
363 static struct batadv_backbone_gw *
367 struct batadv_backbone_gw *
entry;
371 entry = batadv_backbone_hash_find(bat_priv, orig, vid);
377 "bla_get_backbone_gw(): not found (%pM, %d), creating new entry\n",
386 entry->crc = BATADV_BLA_CRC_INIT;
394 hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
395 batadv_compare_backbone_gw,
396 batadv_choose_backbone_gw, entry,
406 orig_node = batadv_orig_hash_find(bat_priv, orig);
409 "became a backbone gateway");
419 batadv_bla_update_own_backbone_gw(
struct batadv_priv *bat_priv,
423 struct batadv_backbone_gw *backbone_gw;
425 backbone_gw = batadv_bla_get_backbone_gw(bat_priv,
431 backbone_gw->lasttime =
jiffies;
432 batadv_backbone_gw_free_ref(backbone_gw);
441 static void batadv_bla_answer_request(
struct batadv_priv *bat_priv,
448 struct batadv_claim *claim;
449 struct batadv_backbone_gw *backbone_gw;
453 "bla_answer_request(): received a claim request, send all of our own claims again\n");
455 backbone_gw = batadv_backbone_hash_find(bat_priv,
461 hash = bat_priv->bla.claim_hash;
462 for (i = 0; i < hash->
size; i++) {
466 hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
468 if (claim->backbone_gw != backbone_gw)
471 batadv_bla_send_claim(bat_priv, claim->addr, claim->vid,
478 batadv_bla_send_announce(bat_priv, backbone_gw);
479 batadv_backbone_gw_free_ref(backbone_gw);
488 static void batadv_bla_send_request(
struct batadv_backbone_gw *backbone_gw)
491 batadv_bla_del_backbone_claims(backbone_gw);
494 "Sending REQUEST to %pM\n", backbone_gw->orig);
497 batadv_bla_send_claim(backbone_gw->bat_priv, backbone_gw->orig,
502 atomic_inc(&backbone_gw->bat_priv->bla.num_requests);
513 static void batadv_bla_send_announce(
struct batadv_priv *bat_priv,
514 struct batadv_backbone_gw *backbone_gw)
519 memcpy(mac, batadv_announce_mac, 4);
520 crc =
htons(backbone_gw->crc);
523 batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
535 static void batadv_bla_add_claim(
struct batadv_priv *bat_priv,
536 const uint8_t *mac,
const short vid,
537 struct batadv_backbone_gw *backbone_gw)
539 struct batadv_claim *claim;
540 struct batadv_claim search_claim;
544 search_claim.vid =
vid;
545 claim = batadv_claim_hash_find(bat_priv, &search_claim);
556 claim->backbone_gw = backbone_gw;
560 "bla_add_claim(): adding new entry %pM, vid %d to hash ...\n",
562 hash_added = batadv_hash_add(bat_priv->bla.claim_hash,
563 batadv_compare_claim,
564 batadv_choose_claim, claim,
574 if (claim->backbone_gw == backbone_gw)
579 "bla_add_claim(): changing ownership for %pM, vid %d\n",
583 batadv_backbone_gw_free_ref(claim->backbone_gw);
588 claim->backbone_gw = backbone_gw;
591 backbone_gw->lasttime =
jiffies;
594 batadv_claim_free_ref(claim);
600 static void batadv_bla_del_claim(
struct batadv_priv *bat_priv,
601 const uint8_t *mac,
const short vid)
603 struct batadv_claim search_claim, *claim;
606 search_claim.vid =
vid;
607 claim = batadv_claim_hash_find(bat_priv, &search_claim);
611 batadv_dbg(
BATADV_DBG_BLA, bat_priv,
"bla_del_claim(): %pM, vid %d\n",
614 batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
615 batadv_choose_claim, claim);
616 batadv_claim_free_ref(claim);
621 batadv_claim_free_ref(claim);
625 static int batadv_handle_announce(
struct batadv_priv *bat_priv,
629 struct batadv_backbone_gw *backbone_gw;
632 if (
memcmp(an_addr, batadv_announce_mac, 4) != 0)
635 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
642 backbone_gw->lasttime =
jiffies;
646 "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %04x\n",
647 vid, backbone_gw->orig, crc);
649 if (backbone_gw->crc != crc) {
651 "handle_announce(): CRC FAILED for %pM/%d (my = %04x, sent = %04x)\n",
652 backbone_gw->orig, backbone_gw->vid,
653 backbone_gw->crc, crc);
655 batadv_bla_send_request(backbone_gw);
661 atomic_dec(&backbone_gw->bat_priv->bla.num_requests);
666 batadv_backbone_gw_free_ref(backbone_gw);
671 static int batadv_handle_request(
struct batadv_priv *bat_priv,
674 struct ethhdr *ethhdr,
short vid)
677 if (!batadv_compare_eth(backbone_addr, ethhdr->
h_dest))
683 if (!batadv_compare_eth(ethhdr->
h_dest, primary_if->
net_dev->dev_addr))
687 "handle_request(): REQUEST vid %d (sent by %pM)...\n",
690 batadv_bla_answer_request(bat_priv, primary_if, vid);
695 static int batadv_handle_unclaim(
struct batadv_priv *bat_priv,
698 uint8_t *claim_addr,
short vid)
700 struct batadv_backbone_gw *backbone_gw;
703 if (primary_if && batadv_compare_eth(backbone_addr,
704 primary_if->
net_dev->dev_addr))
705 batadv_bla_send_claim(bat_priv, claim_addr, vid,
708 backbone_gw = batadv_backbone_hash_find(bat_priv, backbone_addr, vid);
715 "handle_unclaim(): UNCLAIM %pM on vid %d (sent by %pM)...\n",
716 claim_addr, vid, backbone_gw->orig);
718 batadv_bla_del_claim(bat_priv, claim_addr, vid);
719 batadv_backbone_gw_free_ref(backbone_gw);
724 static int batadv_handle_claim(
struct batadv_priv *bat_priv,
729 struct batadv_backbone_gw *backbone_gw;
733 backbone_gw = batadv_bla_get_backbone_gw(bat_priv, backbone_addr, vid);
739 batadv_bla_add_claim(bat_priv, claim_addr, vid, backbone_gw);
740 if (batadv_compare_eth(backbone_addr, primary_if->
net_dev->dev_addr))
741 batadv_bla_send_claim(bat_priv, claim_addr, vid,
746 batadv_backbone_gw_free_ref(backbone_gw);
766 static int batadv_check_claim_group(
struct batadv_priv *bat_priv,
769 struct ethhdr *ethhdr)
776 bla_dst_own = &bat_priv->bla.claim_dest;
780 sizeof(bla_dst->
magic)) != 0)
786 switch (bla_dst->
type) {
800 if (batadv_compare_eth(backbone_addr, primary_if->
net_dev->dev_addr))
808 orig_node = batadv_orig_hash_find(bat_priv, backbone_addr);
819 "taking other backbones claim group: %04x\n",
838 static int batadv_bla_process_claim(
struct batadv_priv *bat_priv,
842 struct ethhdr *ethhdr;
852 ethhdr = (
struct ethhdr *)skb_mac_header(skb);
858 headlen =
sizeof(*vhdr);
869 if (
unlikely(!pskb_may_pull(skb, headlen + arp_hdr_len(skb->
dev))))
873 ethhdr = (
struct ethhdr *)skb_mac_header(skb);
874 arphdr = (
struct arphdr *)((
uint8_t *)ethhdr + headlen);
888 hw_src = (
uint8_t *)arphdr +
sizeof(
struct arphdr);
893 ret = batadv_check_claim_group(bat_priv, primary_if, hw_src, hw_dst,
897 "bla_process_claim(): received a claim frame from another group. From: %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
898 ethhdr->
h_source, vid, hw_src, hw_dst);
904 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
907 switch (bla_dst->
type) {
909 if (batadv_handle_claim(bat_priv, primary_if, hw_src,
914 if (batadv_handle_unclaim(bat_priv, primary_if,
920 if (batadv_handle_announce(bat_priv, hw_src, ethhdr->
h_source,
925 if (batadv_handle_request(bat_priv, primary_if, hw_src, ethhdr,
932 "bla_process_claim(): ERROR - this looks like a claim frame, but is useless. eth src %pM on vid %d ...(hw_src %pM, hw_dst %pM)\n",
933 ethhdr->
h_source, vid, hw_src, hw_dst);
940 static void batadv_bla_purge_backbone_gw(
struct batadv_priv *bat_priv,
int now)
942 struct batadv_backbone_gw *backbone_gw;
949 hash = bat_priv->bla.backbone_hash;
953 for (i = 0; i < hash->
size; i++) {
957 spin_lock_bh(list_lock);
962 if (!batadv_has_timed_out(backbone_gw->lasttime,
967 "bla_purge_backbone_gw(): backbone gw %pM timed out\n",
975 batadv_bla_del_backbone_claims(backbone_gw);
978 batadv_backbone_gw_free_ref(backbone_gw);
980 spin_unlock_bh(list_lock);
993 static void batadv_bla_purge_claims(
struct batadv_priv *bat_priv,
997 struct batadv_claim *claim;
1003 hash = bat_priv->bla.claim_hash;
1007 for (i = 0; i < hash->
size; i++) {
1011 hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
1014 if (!batadv_compare_eth(claim->backbone_gw->orig,
1015 primary_if->
net_dev->dev_addr))
1017 if (!batadv_has_timed_out(claim->lasttime,
1022 "bla_purge_claims(): %pM, vid %d, time out\n",
1023 claim->addr, claim->vid);
1026 batadv_handle_unclaim(bat_priv, primary_if,
1027 claim->backbone_gw->orig,
1028 claim->addr, claim->vid);
1046 struct batadv_backbone_gw *backbone_gw;
1055 bat_priv->bla.claim_dest.group =
group;
1058 batadv_bla_purge_claims(bat_priv,
NULL, 1);
1059 batadv_bla_purge_backbone_gw(bat_priv, 1);
1063 hash = bat_priv->bla.backbone_hash;
1067 for (i = 0; i < hash->
size; i++) {
1071 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1073 if (!batadv_compare_eth(backbone_gw->orig,
1077 memcpy(backbone_gw->orig,
1078 primary_if->
net_dev->dev_addr, ETH_ALEN);
1082 batadv_bla_send_announce(bat_priv, backbone_gw);
1091 static void batadv_bla_start_timer(
struct batadv_priv *bat_priv)
1106 struct batadv_priv_bla *priv_bla;
1109 struct batadv_backbone_gw *backbone_gw;
1114 delayed_work =
container_of(work,
struct delayed_work, work);
1115 priv_bla =
container_of(delayed_work,
struct batadv_priv_bla, work);
1117 primary_if = batadv_primary_if_get_selected(bat_priv);
1121 batadv_bla_purge_claims(bat_priv, primary_if, 0);
1122 batadv_bla_purge_backbone_gw(bat_priv, 0);
1127 hash = bat_priv->bla.backbone_hash;
1131 for (i = 0; i < hash->
size; i++) {
1135 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1136 if (!batadv_compare_eth(backbone_gw->orig,
1137 primary_if->
net_dev->dev_addr))
1140 backbone_gw->lasttime =
jiffies;
1142 batadv_bla_send_announce(bat_priv, backbone_gw);
1148 batadv_hardif_free_ref(primary_if);
1150 batadv_bla_start_timer(bat_priv);
1159 static struct lock_class_key batadv_backbone_hash_lock_class_key;
1168 unsigned long entrytime;
1175 memcpy(&bat_priv->bla.claim_dest.magic, claim_dest, 3);
1176 bat_priv->bla.claim_dest.type = 0;
1177 primary_if = batadv_primary_if_get_selected(bat_priv);
1179 crc =
crc16(0, primary_if->
net_dev->dev_addr, ETH_ALEN);
1180 bat_priv->bla.claim_dest.group =
htons(crc);
1181 batadv_hardif_free_ref(primary_if);
1183 bat_priv->bla.claim_dest.group = 0;
1189 bat_priv->bla.bcast_duplist[i].entrytime = entrytime;
1190 bat_priv->bla.bcast_duplist_curr = 0;
1192 if (bat_priv->bla.claim_hash)
1198 if (!bat_priv->bla.claim_hash || !bat_priv->bla.backbone_hash)
1202 &batadv_claim_hash_lock_class_key);
1204 &batadv_backbone_hash_lock_class_key);
1206 batadv_dbg(
BATADV_DBG_BLA, bat_priv,
"bla hashes initialized\n");
1208 batadv_bla_start_timer(bat_priv);
1229 int bcast_packet_len)
1234 struct batadv_bcast_duplist_entry *
entry;
1236 length = bcast_packet_len -
sizeof(*bcast_packet);
1237 content = (
uint8_t *)bcast_packet;
1238 content +=
sizeof(*bcast_packet);
1241 crc =
crc16(0, content, length);
1243 spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
1246 curr = (bat_priv->bla.bcast_duplist_curr +
i);
1248 entry = &bat_priv->bla.bcast_duplist[
curr];
1253 if (batadv_has_timed_out(entry->entrytime,
1257 if (entry->crc != crc)
1260 if (batadv_compare_eth(entry->orig, bcast_packet->orig))
1272 curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1);
1274 entry = &bat_priv->bla.bcast_duplist[
curr];
1277 memcpy(entry->orig, bcast_packet->orig, ETH_ALEN);
1278 bat_priv->bla.bcast_duplist_curr =
curr;
1281 spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock);
1300 struct batadv_backbone_gw *backbone_gw;
1309 for (i = 0; i < hash->
size; i++) {
1313 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1314 if (batadv_compare_eth(backbone_gw->orig, orig)) {
1339 struct ethhdr *ethhdr;
1341 struct batadv_backbone_gw *backbone_gw;
1348 if (!pskb_may_pull(skb, hdr_size +
ETH_HLEN))
1354 if (!pskb_may_pull(skb, hdr_size +
sizeof(
struct vlan_ethhdr)))
1362 backbone_gw = batadv_backbone_hash_find(orig_node->
bat_priv,
1363 orig_node->
orig, vid);
1367 batadv_backbone_gw_free_ref(backbone_gw);
1377 primary_if = batadv_primary_if_get_selected(bat_priv);
1379 if (bat_priv->bla.claim_hash) {
1380 batadv_bla_purge_claims(bat_priv, primary_if, 1);
1382 bat_priv->bla.claim_hash =
NULL;
1384 if (bat_priv->bla.backbone_hash) {
1385 batadv_bla_purge_backbone_gw(bat_priv, 1);
1387 bat_priv->bla.backbone_hash =
NULL;
1390 batadv_hardif_free_ref(primary_if);
1411 struct ethhdr *ethhdr;
1412 struct batadv_claim search_claim, *claim =
NULL;
1416 ethhdr = (
struct ethhdr *)skb_mac_header(skb);
1418 primary_if = batadv_primary_if_get_selected(bat_priv);
1428 if (is_multicast_ether_addr(ethhdr->
h_dest) && is_bcast)
1432 search_claim.vid =
vid;
1433 claim = batadv_claim_hash_find(bat_priv, &search_claim);
1439 batadv_handle_claim(bat_priv, primary_if,
1440 primary_if->
net_dev->dev_addr,
1446 if (batadv_compare_eth(claim->backbone_gw->orig,
1447 primary_if->
net_dev->dev_addr)) {
1454 if (is_multicast_ether_addr(ethhdr->
h_dest) && is_bcast) {
1467 batadv_handle_claim(bat_priv, primary_if,
1468 primary_if->
net_dev->dev_addr,
1473 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1483 batadv_hardif_free_ref(primary_if);
1485 batadv_claim_free_ref(claim);
1505 struct ethhdr *ethhdr;
1506 struct batadv_claim search_claim, *claim =
NULL;
1510 primary_if = batadv_primary_if_get_selected(bat_priv);
1518 skb_reset_mac_header(skb);
1520 if (batadv_bla_process_claim(bat_priv, primary_if, skb))
1523 ethhdr = (
struct ethhdr *)skb_mac_header(skb);
1527 if (is_multicast_ether_addr(ethhdr->
h_dest))
1531 search_claim.vid =
vid;
1533 claim = batadv_claim_hash_find(bat_priv, &search_claim);
1540 if (batadv_compare_eth(claim->backbone_gw->orig,
1541 primary_if->
net_dev->dev_addr)) {
1545 batadv_handle_unclaim(bat_priv, primary_if,
1546 primary_if->
net_dev->dev_addr,
1552 if (is_multicast_ether_addr(ethhdr->
h_dest)) {
1564 batadv_bla_update_own_backbone_gw(bat_priv, primary_if, vid);
1571 batadv_hardif_free_ref(primary_if);
1573 batadv_claim_free_ref(claim);
1580 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1582 struct batadv_claim *claim;
1591 primary_if = batadv_primary_if_get_selected(bat_priv);
1594 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1601 "BATMAN mesh %s disabled - primary interface not active\n",
1606 primary_addr = primary_if->
net_dev->dev_addr;
1608 "Claims announced for the mesh %s (orig %pM, group id %04x)\n",
1609 net_dev->
name, primary_addr,
1610 ntohs(bat_priv->bla.claim_dest.group));
1611 seq_printf(seq,
" %-17s %-5s %-17s [o] (%-4s)\n",
1612 "Client",
"VID",
"Originator",
"CRC");
1613 for (i = 0; i < hash->
size; i++) {
1617 hlist_for_each_entry_rcu(claim, node, head, hash_entry) {
1618 is_own = batadv_compare_eth(claim->backbone_gw->orig,
1620 seq_printf(seq,
" * %pM on % 5d by %pM [%c] (%04x)\n",
1621 claim->addr, claim->vid,
1622 claim->backbone_gw->orig,
1623 (is_own ?
'x' :
' '),
1624 claim->backbone_gw->crc);
1630 batadv_hardif_free_ref(primary_if);
1637 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1639 struct batadv_backbone_gw *backbone_gw;
1649 primary_if = batadv_primary_if_get_selected(bat_priv);
1652 "BATMAN mesh %s disabled - please specify interfaces to enable it\n",
1659 "BATMAN mesh %s disabled - primary interface not active\n",
1664 primary_addr = primary_if->
net_dev->dev_addr;
1666 "Backbones announced for the mesh %s (orig %pM, group id %04x)\n",
1667 net_dev->
name, primary_addr,
1668 ntohs(bat_priv->bla.claim_dest.group));
1670 "Originator",
"VID",
"last seen",
"CRC");
1671 for (i = 0; i < hash->
size; i++) {
1675 hlist_for_each_entry_rcu(backbone_gw, node, head, hash_entry) {
1677 backbone_gw->lasttime);
1678 secs = msecs / 1000;
1679 msecs = msecs % 1000;
1681 is_own = batadv_compare_eth(backbone_gw->orig,
1687 " * %pM on % 5d % 4i.%03is (%04x)\n",
1688 backbone_gw->orig, backbone_gw->vid,
1689 secs, msecs, backbone_gw->crc);
1695 batadv_hardif_free_ref(primary_if);