Lines Matching +full:interface +full:- +full:node
1 // SPDX-License-Identifier: GPL-2.0
7 #include "distributed-arp-table.h"
43 #include "hard-interface.h"
49 #include "translation-table.h"
92 #define BATADV_DHCP_YIADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->yiaddr)
93 #define BATADV_DHCP_CHADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->chaddr)
98 * batadv_dat_start_timer() - initialise the DAT periodic worker
99 * @bat_priv: the bat priv with all the mesh interface information
103 queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, in batadv_dat_start_timer()
108 * batadv_dat_entry_release() - release dat_entry from lists and queue for free
122 * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly
131 kref_put(&dat_entry->refcount, batadv_dat_entry_release); in batadv_dat_entry_put()
135 * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not
142 return batadv_has_timed_out(dat_entry->last_update, in batadv_dat_to_purge()
147 * __batadv_dat_purge() - delete entries from the DAT local storage
148 * @bat_priv: the bat priv with all the mesh interface information
166 if (!bat_priv->dat.hash) in __batadv_dat_purge()
169 for (i = 0; i < bat_priv->dat.hash->size; i++) { in __batadv_dat_purge()
170 head = &bat_priv->dat.hash->table[i]; in __batadv_dat_purge()
171 list_lock = &bat_priv->dat.hash->list_locks[i]; in __batadv_dat_purge()
182 hlist_del_rcu(&dat_entry->hash_entry); in __batadv_dat_purge()
190 * batadv_dat_purge() - periodic task that deletes old entries from the local
209 * batadv_compare_dat() - comparing function used in the local DAT hash table
210 * @node: node in the local table
211 * @data2: second object to compare the node to
215 static bool batadv_compare_dat(const struct hlist_node *node, const void *data2) in batadv_compare_dat() argument
217 const void *data1 = container_of(node, struct batadv_dat_entry, in batadv_compare_dat()
224 * batadv_arp_hw_src() - extract the hw_src field from an ARP packet
234 addr = (u8 *)(skb->data + hdr_size); in batadv_arp_hw_src()
241 * batadv_arp_ip_src() - extract the ip_src field from an ARP packet
253 * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet
265 * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet
279 * batadv_hash_dat() - compute the hash value for an IP address
293 key = (__force const unsigned char *)&dat->ip; in batadv_hash_dat()
294 for (i = 0; i < sizeof(dat->ip); i++) { in batadv_hash_dat()
300 vid = htons(dat->vid); in batadv_hash_dat()
302 for (i = 0; i < sizeof(dat->vid); i++) { in batadv_hash_dat()
316 * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash
318 * @bat_priv: the bat priv with all the mesh interface information
330 struct batadv_hashtable *hash = bat_priv->dat.hash; in batadv_dat_entry_hash_find()
339 index = batadv_hash_dat(&to_find, hash->size); in batadv_dat_entry_hash_find()
340 head = &hash->table[index]; in batadv_dat_entry_hash_find()
344 if (dat_entry->ip != ip) in batadv_dat_entry_hash_find()
347 if (!kref_get_unless_zero(&dat_entry->refcount)) in batadv_dat_entry_hash_find()
359 * batadv_dat_entry_add() - add a new dat entry or update it if already exists
360 * @bat_priv: the bat priv with all the mesh interface information
374 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) in batadv_dat_entry_add()
375 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
376 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
379 &dat_entry->ip, dat_entry->mac_addr, in batadv_dat_entry_add()
388 dat_entry->ip = ip; in batadv_dat_entry_add()
389 dat_entry->vid = vid; in batadv_dat_entry_add()
390 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
391 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
392 kref_init(&dat_entry->refcount); in batadv_dat_entry_add()
394 kref_get(&dat_entry->refcount); in batadv_dat_entry_add()
395 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, in batadv_dat_entry_add()
397 &dat_entry->hash_entry); in batadv_dat_entry_add()
406 &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(vid)); in batadv_dat_entry_add()
415 * batadv_dbg_arp() - print a debug message containing all the ARP packet
417 * @bat_priv: the bat priv with all the mesh interface information
436 "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", in batadv_dbg_arp()
443 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; in batadv_dbg_arp()
445 switch (unicast_4addr_packet->u.packet_type) { in batadv_dbg_arp()
453 unicast_4addr_packet->src); in batadv_dbg_arp()
454 switch (unicast_4addr_packet->subtype) { in batadv_dbg_arp()
470 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
475 orig_addr = bcast_pkt->orig; in batadv_dbg_arp()
483 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
497 * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate
500 * @tmp_max: address of the currently evaluated node
506 * Return: true if the node has been elected as next candidate or false
519 /* check if orig node candidate is running DAT */ in batadv_is_orig_node_eligible()
520 if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) in batadv_is_orig_node_eligible()
523 /* Check if this node has already been selected... */ in batadv_is_orig_node_eligible()
538 /* this is an hash collision with the temporary selected node. Choose in batadv_is_orig_node_eligible()
542 batadv_compare_eth(candidate->orig, max_orig_node->orig)) in batadv_is_orig_node_eligible()
551 * batadv_choose_next_candidate() - select the next DHT candidate
552 * @bat_priv: the bat priv with all the mesh interface information
566 struct batadv_hashtable *hash = bat_priv->orig_hash; in batadv_choose_next_candidate()
570 /* if no node is eligible as candidate, leave the candidate type as in batadv_choose_next_candidate()
575 /* iterate over the originator list and find the node with the closest in batadv_choose_next_candidate()
578 for (i = 0; i < hash->size; i++) { in batadv_choose_next_candidate()
579 head = &hash->table[i]; in batadv_choose_next_candidate()
584 tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + in batadv_choose_next_candidate()
593 if (!kref_get_unless_zero(&orig_node->refcount)) in batadv_choose_next_candidate()
607 select, max_orig_node->orig, max_orig_node->dat_addr, in batadv_choose_next_candidate()
614 * batadv_dat_select_candidates() - select the nodes which the DHT message has
616 * @bat_priv: the bat priv with all the mesh interface information
635 if (!bat_priv->orig_hash) in batadv_dat_select_candidates()
660 * batadv_dat_forward_data() - copy and send payload to the selected candidates
661 * @bat_priv: the bat priv with all the mesh interface information
735 * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat
737 * @bat_priv: the bat priv with all the mesh interface information
743 dat_mode = atomic_read(&bat_priv->distributed_arp_table); in batadv_dat_tvlv_container_update()
757 * batadv_dat_status_update() - update the dat tvlv container after dat
759 * @net_dev: the mesh interface net device
769 * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container
770 * @bat_priv: the bat priv with all the mesh interface information
782 clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
784 set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
788 * batadv_dat_hash_free() - free the local DAT hash table
789 * @bat_priv: the bat priv with all the mesh interface information
793 if (!bat_priv->dat.hash) in batadv_dat_hash_free()
798 batadv_hash_destroy(bat_priv->dat.hash); in batadv_dat_hash_free()
800 bat_priv->dat.hash = NULL; in batadv_dat_hash_free()
804 * batadv_dat_init() - initialise the DAT internals
805 * @bat_priv: the bat priv with all the mesh interface information
811 if (bat_priv->dat.hash) in batadv_dat_init()
814 bat_priv->dat.hash = batadv_hash_new(1024); in batadv_dat_init()
816 if (!bat_priv->dat.hash) in batadv_dat_init()
817 return -ENOMEM; in batadv_dat_init()
819 INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); in batadv_dat_init()
830 * batadv_dat_free() - free the DAT internals
831 * @bat_priv: the bat priv with all the mesh interface information
838 cancel_delayed_work_sync(&bat_priv->dat.work); in batadv_dat_free()
844 * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
861 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_dat_cache_dump_entry()
865 return -ENOBUFS; in batadv_dat_cache_dump_entry()
869 msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); in batadv_dat_cache_dump_entry()
872 dat_entry->ip) || in batadv_dat_cache_dump_entry()
874 dat_entry->mac_addr) || in batadv_dat_cache_dump_entry()
875 nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || in batadv_dat_cache_dump_entry()
878 return -EMSGSIZE; in batadv_dat_cache_dump_entry()
886 * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
906 spin_lock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
907 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_dat_cache_dump_bucket()
909 hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { in batadv_dat_cache_dump_bucket()
914 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
917 return -EMSGSIZE; in batadv_dat_cache_dump_bucket()
923 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
929 * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
938 int portid = NETLINK_CB(cb->skb).portid; in batadv_dat_cache_dump()
942 int bucket = cb->args[0]; in batadv_dat_cache_dump()
943 int idx = cb->args[1]; in batadv_dat_cache_dump()
951 hash = bat_priv->dat.hash; in batadv_dat_cache_dump()
954 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_dat_cache_dump()
955 ret = -ENOENT; in batadv_dat_cache_dump()
959 while (bucket < hash->size) { in batadv_dat_cache_dump()
968 cb->args[0] = bucket; in batadv_dat_cache_dump()
969 cb->args[1] = idx; in batadv_dat_cache_dump()
971 ret = msg->len; in batadv_dat_cache_dump()
982 * batadv_arp_get_type() - parse an ARP packet and gets the type
983 * @bat_priv: the bat priv with all the mesh interface information
1002 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_arp_get_type()
1004 if (ethhdr->h_proto != htons(ETH_P_ARP)) in batadv_arp_get_type()
1009 arp_hdr_len(skb->dev)))) in batadv_arp_get_type()
1012 arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); in batadv_arp_get_type()
1015 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) in batadv_arp_get_type()
1018 if (arphdr->ar_pro != htons(ETH_P_IP)) in batadv_arp_get_type()
1021 if (arphdr->ar_hln != ETH_ALEN) in batadv_arp_get_type()
1024 if (arphdr->ar_pln != 4) in batadv_arp_get_type()
1043 if (arphdr->ar_op != htons(ARPOP_REQUEST)) { in batadv_arp_get_type()
1050 type = ntohs(arphdr->ar_op); in batadv_arp_get_type()
1056 * batadv_dat_get_vid() - extract the VLAN identifier from skb if any
1058 * @hdr_size: the size of the batman-adv header encapsulating the packet
1082 * batadv_dat_arp_create_reply() - create an ARP Reply
1083 * @bat_priv: the bat priv with all the mesh interface information
1102 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->mesh_iface, in batadv_dat_arp_create_reply()
1117 * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
1119 * @bat_priv: the bat priv with all the mesh interface information
1135 struct net_device *mesh_iface = bat_priv->mesh_iface; in batadv_dat_snoop_outgoing_arp_request()
1139 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_request()
1145 /* If the node gets an ARP_REQUEST it has to send a DHT_GET unicast in batadv_dat_snoop_outgoing_arp_request()
1165 * Moreover, if the mesh-interface is enslaved into a bridge, an in batadv_dat_snoop_outgoing_arp_request()
1169 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1180 dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1183 dat_entry->mac_addr); in batadv_dat_snoop_outgoing_arp_request()
1189 dat_entry->mac_addr, in batadv_dat_snoop_outgoing_arp_request()
1194 skb_new->protocol = eth_type_trans(skb_new, mesh_iface); in batadv_dat_snoop_outgoing_arp_request()
1198 skb->len + ETH_HLEN + hdr_size); in batadv_dat_snoop_outgoing_arp_request()
1214 * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to
1216 * @bat_priv: the bat priv with all the mesh interface information
1234 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_request()
1256 dat_entry->mac_addr, hw_src, vid); in batadv_dat_snoop_incoming_arp_request()
1260 /* To preserve backwards compatibility, the node has choose the outgoing in batadv_dat_snoop_incoming_arp_request()
1262 * that a node not using the 4addr packet format doesn't support it. in batadv_dat_snoop_incoming_arp_request()
1283 * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT
1284 * @bat_priv: the bat priv with all the mesh interface information
1296 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_reply()
1316 * the node obtained from the ARP reply in batadv_dat_snoop_outgoing_arp_reply()
1325 * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
1327 * @bat_priv: the bat priv with all the mesh interface information
1332 * packet has to be delivered to the interface
1344 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_reply()
1362 * most probably an ARP reply generated by another node of the DHT. in batadv_dat_snoop_incoming_arp_reply()
1367 if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { in batadv_dat_snoop_incoming_arp_reply()
1368 … bat_priv, "Doubled ARP reply removed: ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]; dat_entry: %pM-%pI… in batadv_dat_snoop_incoming_arp_reply()
1370 dat_entry->mac_addr, &dat_entry->ip); in batadv_dat_snoop_incoming_arp_reply()
1374 /* Update our internal cache with both the IP addresses the node got in batadv_dat_snoop_incoming_arp_reply()
1398 * packet to the interface in batadv_dat_snoop_incoming_arp_reply()
1410 /* if dropped == false -> deliver to the interface */ in batadv_dat_snoop_incoming_arp_reply()
1415 * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP
1433 if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr)) in batadv_dat_check_dhcp_ipudp()
1436 if (iphdr->protocol != IPPROTO_UDP) in batadv_dat_check_dhcp_ipudp()
1439 offset += iphdr->ihl * 4; in batadv_dat_check_dhcp_ipudp()
1443 if (!udphdr || udphdr->source != htons(67)) in batadv_dat_check_dhcp_ipudp()
1446 *ip_src = get_unaligned(&iphdr->saddr); in batadv_dat_check_dhcp_ipudp()
1452 * batadv_dat_check_dhcp() - examine packet for valid DHCP message
1463 * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
1478 return -EINVAL; in batadv_dat_check_dhcp()
1481 return -EINVAL; in batadv_dat_check_dhcp()
1484 if (skb->len < offset + sizeof(struct batadv_dhcp_packet)) in batadv_dat_check_dhcp()
1485 return -EINVAL; in batadv_dat_check_dhcp()
1488 if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET || in batadv_dat_check_dhcp()
1489 dhcp_h->hlen != ETH_ALEN) in batadv_dat_check_dhcp()
1490 return -EINVAL; in batadv_dat_check_dhcp()
1496 return -EINVAL; in batadv_dat_check_dhcp()
1498 return dhcp_h->op; in batadv_dat_check_dhcp()
1502 * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet
1511 * Return: The found DHCP message type value, if found. -EINVAL otherwise.
1525 if (tl->type == BATADV_DHCP_OPT_MSG_TYPE) in batadv_dat_get_dhcp_message_type()
1528 if (tl->type == BATADV_DHCP_OPT_END) in batadv_dat_get_dhcp_message_type()
1531 if (tl->type == BATADV_DHCP_OPT_PAD) in batadv_dat_get_dhcp_message_type()
1534 offset += tl->len + sizeof(_tl); in batadv_dat_get_dhcp_message_type()
1538 if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE || in batadv_dat_get_dhcp_message_type()
1539 tl->len != sizeof(_type)) in batadv_dat_get_dhcp_message_type()
1540 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1546 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1552 * batadv_dat_dhcp_get_yiaddr() - get yiaddr from a DHCP packet
1579 * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
1606 * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
1608 * @bat_priv: the bat priv with all the mesh interface information
1653 * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
1692 * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
1693 * @bat_priv: the bat priv with all the mesh interface information
1714 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_dhcp_ack()
1720 batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source, in batadv_dat_snoop_outgoing_dhcp_ack()
1725 * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache
1726 * @bat_priv: the bat priv with all the mesh interface information
1728 * @hdr_size: header size, up to the tail of the batman-adv header
1744 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_dhcp_ack()
1750 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_dat_snoop_incoming_dhcp_ack()
1752 proto = ethhdr->h_proto; in batadv_dat_snoop_incoming_dhcp_ack()
1757 hw_src = ethhdr->h_source; in batadv_dat_snoop_incoming_dhcp_ack()
1772 * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be
1773 * dropped (because the node has already obtained the reply via DAT) or not
1774 * @bat_priv: the bat priv with all the mesh interface information
1777 * Return: true if the node can drop the packet, false otherwise.
1789 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_drop_broadcast_packet()
1792 /* If this packet is an ARP_REQUEST and the node already has the in batadv_dat_drop_broadcast_packet()
1798 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); in batadv_dat_drop_broadcast_packet()
1800 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()
1804 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()
1806 /* check if the node already got this entry */ in batadv_dat_drop_broadcast_packet()