Lines Matching +full:pull +full:- +full:up +full:- +full:adv

1 // SPDX-License-Identifier: GPL-2.0
7 #include "distributed-arp-table.h"
43 #include "hard-interface.h"
49 #include "soft-interface.h"
50 #include "translation-table.h"
93 #define BATADV_DHCP_YIADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->yiaddr)
94 #define BATADV_DHCP_CHADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->chaddr)
99 * batadv_dat_start_timer() - initialise the DAT periodic worker
104 INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); in batadv_dat_start_timer()
105 queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, in batadv_dat_start_timer()
110 * batadv_dat_entry_release() - release dat_entry from lists and queue for free
124 * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly
133 kref_put(&dat_entry->refcount, batadv_dat_entry_release); in batadv_dat_entry_put()
137 * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not
144 return batadv_has_timed_out(dat_entry->last_update, in batadv_dat_to_purge()
149 * __batadv_dat_purge() - delete entries from the DAT local storage
168 if (!bat_priv->dat.hash) in __batadv_dat_purge()
171 for (i = 0; i < bat_priv->dat.hash->size; i++) { in __batadv_dat_purge()
172 head = &bat_priv->dat.hash->table[i]; in __batadv_dat_purge()
173 list_lock = &bat_priv->dat.hash->list_locks[i]; in __batadv_dat_purge()
184 hlist_del_rcu(&dat_entry->hash_entry); in __batadv_dat_purge()
192 * batadv_dat_purge() - periodic task that deletes old entries from the local
211 * batadv_compare_dat() - comparing function used in the local DAT hash table
226 * batadv_arp_hw_src() - extract the hw_src field from an ARP packet
236 addr = (u8 *)(skb->data + hdr_size); in batadv_arp_hw_src()
243 * batadv_arp_ip_src() - extract the ip_src field from an ARP packet
255 * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet
267 * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet
281 * batadv_hash_dat() - compute the hash value for an IP address
295 key = (__force const unsigned char *)&dat->ip; in batadv_hash_dat()
296 for (i = 0; i < sizeof(dat->ip); i++) { in batadv_hash_dat()
302 vid = htons(dat->vid); in batadv_hash_dat()
304 for (i = 0; i < sizeof(dat->vid); i++) { in batadv_hash_dat()
318 * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash
332 struct batadv_hashtable *hash = bat_priv->dat.hash; in batadv_dat_entry_hash_find()
341 index = batadv_hash_dat(&to_find, hash->size); in batadv_dat_entry_hash_find()
342 head = &hash->table[index]; in batadv_dat_entry_hash_find()
346 if (dat_entry->ip != ip) in batadv_dat_entry_hash_find()
349 if (!kref_get_unless_zero(&dat_entry->refcount)) in batadv_dat_entry_hash_find()
361 * batadv_dat_entry_add() - add a new dat entry or update it if already exists
376 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) in batadv_dat_entry_add()
377 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
378 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
381 &dat_entry->ip, dat_entry->mac_addr, in batadv_dat_entry_add()
390 dat_entry->ip = ip; in batadv_dat_entry_add()
391 dat_entry->vid = vid; in batadv_dat_entry_add()
392 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
393 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
394 kref_init(&dat_entry->refcount); in batadv_dat_entry_add()
396 kref_get(&dat_entry->refcount); in batadv_dat_entry_add()
397 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, in batadv_dat_entry_add()
399 &dat_entry->hash_entry); in batadv_dat_entry_add()
408 &dat_entry->ip, dat_entry->mac_addr, batadv_print_vid(vid)); in batadv_dat_entry_add()
417 * batadv_dbg_arp() - print a debug message containing all the ARP packet
438 "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", in batadv_dbg_arp()
445 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; in batadv_dbg_arp()
447 switch (unicast_4addr_packet->u.packet_type) { in batadv_dbg_arp()
455 unicast_4addr_packet->src); in batadv_dbg_arp()
456 switch (unicast_4addr_packet->subtype) { in batadv_dbg_arp()
472 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
477 orig_addr = bcast_pkt->orig; in batadv_dbg_arp()
485 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
499 * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate
522 if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) in batadv_is_orig_node_eligible()
544 batadv_compare_eth(candidate->orig, max_orig_node->orig)) in batadv_is_orig_node_eligible()
553 * batadv_choose_next_candidate() - select the next DHT candidate
557 * @ip_key: key to look up in the DHT
568 struct batadv_hashtable *hash = bat_priv->orig_hash; in batadv_choose_next_candidate()
580 for (i = 0; i < hash->size; i++) { in batadv_choose_next_candidate()
581 head = &hash->table[i]; in batadv_choose_next_candidate()
586 tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + in batadv_choose_next_candidate()
595 if (!kref_get_unless_zero(&orig_node->refcount)) in batadv_choose_next_candidate()
609 select, max_orig_node->orig, max_orig_node->dat_addr, in batadv_choose_next_candidate()
616 * batadv_dat_select_candidates() - select the nodes which the DHT message has
619 * @ip_dst: ipv4 to look up in the DHT
637 if (!bat_priv->orig_hash) in batadv_dat_select_candidates()
662 * batadv_dat_forward_data() - copy and send payload to the selected candidates
738 * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat
746 dat_mode = atomic_read(&bat_priv->distributed_arp_table); in batadv_dat_tvlv_container_update()
760 * batadv_dat_status_update() - update the dat tvlv container after dat
772 * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container
785 clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
787 set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
791 * batadv_dat_hash_free() - free the local DAT hash table
796 if (!bat_priv->dat.hash) in batadv_dat_hash_free()
801 batadv_hash_destroy(bat_priv->dat.hash); in batadv_dat_hash_free()
803 bat_priv->dat.hash = NULL; in batadv_dat_hash_free()
807 * batadv_dat_init() - initialise the DAT internals
814 if (bat_priv->dat.hash) in batadv_dat_init()
817 bat_priv->dat.hash = batadv_hash_new(1024); in batadv_dat_init()
819 if (!bat_priv->dat.hash) in batadv_dat_init()
820 return -ENOMEM; in batadv_dat_init()
832 * batadv_dat_free() - free the DAT internals
840 cancel_delayed_work_sync(&bat_priv->dat.work); in batadv_dat_free()
846 * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
863 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_dat_cache_dump_entry()
867 return -ENOBUFS; in batadv_dat_cache_dump_entry()
871 msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); in batadv_dat_cache_dump_entry()
874 dat_entry->ip) || in batadv_dat_cache_dump_entry()
876 dat_entry->mac_addr) || in batadv_dat_cache_dump_entry()
877 nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || in batadv_dat_cache_dump_entry()
880 return -EMSGSIZE; in batadv_dat_cache_dump_entry()
888 * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
908 spin_lock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
909 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_dat_cache_dump_bucket()
911 hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { in batadv_dat_cache_dump_bucket()
916 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
919 return -EMSGSIZE; in batadv_dat_cache_dump_bucket()
925 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
931 * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
940 int portid = NETLINK_CB(cb->skb).portid; in batadv_dat_cache_dump()
941 struct net *net = sock_net(cb->skb->sk); in batadv_dat_cache_dump()
945 int bucket = cb->args[0]; in batadv_dat_cache_dump()
946 int idx = cb->args[1]; in batadv_dat_cache_dump()
950 ifindex = batadv_netlink_get_ifindex(cb->nlh, in batadv_dat_cache_dump()
953 return -EINVAL; in batadv_dat_cache_dump()
957 ret = -ENODEV; in batadv_dat_cache_dump()
962 hash = bat_priv->dat.hash; in batadv_dat_cache_dump()
965 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_dat_cache_dump()
966 ret = -ENOENT; in batadv_dat_cache_dump()
970 while (bucket < hash->size) { in batadv_dat_cache_dump()
979 cb->args[0] = bucket; in batadv_dat_cache_dump()
980 cb->args[1] = idx; in batadv_dat_cache_dump()
982 ret = msg->len; in batadv_dat_cache_dump()
993 * batadv_arp_get_type() - parse an ARP packet and gets the type
1009 /* pull the ethernet header */ in batadv_arp_get_type()
1013 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_arp_get_type()
1015 if (ethhdr->h_proto != htons(ETH_P_ARP)) in batadv_arp_get_type()
1018 /* pull the ARP payload */ in batadv_arp_get_type()
1020 arp_hdr_len(skb->dev)))) in batadv_arp_get_type()
1023 arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); in batadv_arp_get_type()
1026 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) in batadv_arp_get_type()
1029 if (arphdr->ar_pro != htons(ETH_P_IP)) in batadv_arp_get_type()
1032 if (arphdr->ar_hln != ETH_ALEN) in batadv_arp_get_type()
1035 if (arphdr->ar_pln != 4) in batadv_arp_get_type()
1054 if (arphdr->ar_op != htons(ARPOP_REQUEST)) { in batadv_arp_get_type()
1061 type = ntohs(arphdr->ar_op); in batadv_arp_get_type()
1067 * batadv_dat_get_vid() - extract the VLAN identifier from skb if any
1069 * @hdr_size: the size of the batman-adv header encapsulating the packet
1093 * batadv_dat_arp_create_reply() - create an ARP Reply
1113 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, in batadv_dat_arp_create_reply()
1128 * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
1146 struct net_device *soft_iface = bat_priv->soft_iface; in batadv_dat_snoop_outgoing_arp_request()
1150 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_request()
1176 * Moreover, if the soft-interface is enslaved into a bridge, an in batadv_dat_snoop_outgoing_arp_request()
1180 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1191 dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1194 dat_entry->mac_addr); in batadv_dat_snoop_outgoing_arp_request()
1200 dat_entry->mac_addr, in batadv_dat_snoop_outgoing_arp_request()
1205 skb_new->protocol = eth_type_trans(skb_new, soft_iface); in batadv_dat_snoop_outgoing_arp_request()
1209 skb->len + ETH_HLEN + hdr_size); in batadv_dat_snoop_outgoing_arp_request()
1225 * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to
1245 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_request()
1267 dat_entry->mac_addr, hw_src, vid); in batadv_dat_snoop_incoming_arp_request()
1294 * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT
1307 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_reply()
1336 * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
1355 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_reply()
1378 if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { in batadv_dat_snoop_incoming_arp_reply()
1379 … 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()
1381 dat_entry->mac_addr, &dat_entry->ip); in batadv_dat_snoop_incoming_arp_reply()
1421 /* if dropped == false -> deliver to the interface */ in batadv_dat_snoop_incoming_arp_reply()
1426 * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP
1444 if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr)) in batadv_dat_check_dhcp_ipudp()
1447 if (iphdr->protocol != IPPROTO_UDP) in batadv_dat_check_dhcp_ipudp()
1450 offset += iphdr->ihl * 4; in batadv_dat_check_dhcp_ipudp()
1454 if (!udphdr || udphdr->source != htons(67)) in batadv_dat_check_dhcp_ipudp()
1457 *ip_src = get_unaligned(&iphdr->saddr); in batadv_dat_check_dhcp_ipudp()
1463 * batadv_dat_check_dhcp() - examine packet for valid DHCP message
1474 * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
1489 return -EINVAL; in batadv_dat_check_dhcp()
1492 return -EINVAL; in batadv_dat_check_dhcp()
1495 if (skb->len < offset + sizeof(struct batadv_dhcp_packet)) in batadv_dat_check_dhcp()
1496 return -EINVAL; in batadv_dat_check_dhcp()
1499 if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET || in batadv_dat_check_dhcp()
1500 dhcp_h->hlen != ETH_ALEN) in batadv_dat_check_dhcp()
1501 return -EINVAL; in batadv_dat_check_dhcp()
1507 return -EINVAL; in batadv_dat_check_dhcp()
1509 return dhcp_h->op; in batadv_dat_check_dhcp()
1513 * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet
1522 * Return: The found DHCP message type value, if found. -EINVAL otherwise.
1536 if (tl->type == BATADV_DHCP_OPT_MSG_TYPE) in batadv_dat_get_dhcp_message_type()
1539 if (tl->type == BATADV_DHCP_OPT_END) in batadv_dat_get_dhcp_message_type()
1542 if (tl->type == BATADV_DHCP_OPT_PAD) in batadv_dat_get_dhcp_message_type()
1545 offset += tl->len + sizeof(_tl); in batadv_dat_get_dhcp_message_type()
1549 if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE || in batadv_dat_get_dhcp_message_type()
1550 tl->len != sizeof(_type)) in batadv_dat_get_dhcp_message_type()
1551 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1557 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1563 * batadv_dat_dhcp_get_yiaddr() - get yiaddr from a DHCP packet
1590 * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
1617 * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
1664 * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
1703 * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
1725 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_dhcp_ack()
1731 batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source, in batadv_dat_snoop_outgoing_dhcp_ack()
1736 * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache
1739 * @hdr_size: header size, up to the tail of the batman-adv header
1755 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_dhcp_ack()
1761 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_dat_snoop_incoming_dhcp_ack()
1763 proto = ethhdr->h_proto; in batadv_dat_snoop_incoming_dhcp_ack()
1768 hw_src = ethhdr->h_source; in batadv_dat_snoop_incoming_dhcp_ack()
1783 * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be
1800 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_drop_broadcast_packet()
1809 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); in batadv_dat_drop_broadcast_packet()
1811 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()
1815 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()