Lines Matching +full:pull +full:- +full:up +full:- +full:adv
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2011-2020 B.A.T.M.A.N. contributors:
7 #include "distributed-arp-table.h"
44 #include "hard-interface.h"
50 #include "soft-interface.h"
51 #include "translation-table.h"
94 #define BATADV_DHCP_YIADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->yiaddr)
95 #define BATADV_DHCP_CHADDR_LEN sizeof(((struct batadv_dhcp_packet *)0)->chaddr)
100 * batadv_dat_start_timer() - initialise the DAT periodic worker
105 INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); in batadv_dat_start_timer()
106 queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, in batadv_dat_start_timer()
111 * batadv_dat_entry_release() - release dat_entry from lists and queue for free
125 * 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
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
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
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
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()
416 * batadv_dbg_arp() - print a debug message containing all the ARP packet
437 "ARP MSG = [src: %pM-%pI4 dst: %pM-%pI4]\n", in batadv_dbg_arp()
444 unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; in batadv_dbg_arp()
446 switch (unicast_4addr_packet->u.packet_type) { in batadv_dbg_arp()
454 unicast_4addr_packet->src); in batadv_dbg_arp()
455 switch (unicast_4addr_packet->subtype) { in batadv_dbg_arp()
471 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
476 orig_addr = bcast_pkt->orig; in batadv_dbg_arp()
484 unicast_4addr_packet->u.packet_type); in batadv_dbg_arp()
498 * batadv_is_orig_node_eligible() - check whether a node can be a DHT candidate
521 if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) in batadv_is_orig_node_eligible()
543 batadv_compare_eth(candidate->orig, max_orig_node->orig)) in batadv_is_orig_node_eligible()
552 * batadv_choose_next_candidate() - select the next DHT candidate
556 * @ip_key: key to look up in the DHT
567 struct batadv_hashtable *hash = bat_priv->orig_hash; in batadv_choose_next_candidate()
579 for (i = 0; i < hash->size; i++) { in batadv_choose_next_candidate()
580 head = &hash->table[i]; in batadv_choose_next_candidate()
585 tmp_max = BATADV_DAT_ADDR_MAX - orig_node->dat_addr + in batadv_choose_next_candidate()
594 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()
847 * batadv_dat_cache_seq_print_text() - print the local DAT hash table
855 struct net_device *net_dev = (struct net_device *)seq->private; in batadv_dat_cache_seq_print_text()
857 struct batadv_hashtable *hash = bat_priv->dat.hash; in batadv_dat_cache_seq_print_text()
869 seq_printf(seq, "Distributed ARP Table (%s):\n", net_dev->name); in batadv_dat_cache_seq_print_text()
871 " IPv4 MAC VID last-seen\n"); in batadv_dat_cache_seq_print_text()
873 for (i = 0; i < hash->size; i++) { in batadv_dat_cache_seq_print_text()
874 head = &hash->table[i]; in batadv_dat_cache_seq_print_text()
878 last_seen_jiffies = jiffies - dat_entry->last_update; in batadv_dat_cache_seq_print_text()
885 &dat_entry->ip, dat_entry->mac_addr, in batadv_dat_cache_seq_print_text()
886 batadv_print_vid(dat_entry->vid), in batadv_dat_cache_seq_print_text()
900 * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
917 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_dat_cache_dump_entry()
921 return -ENOBUFS; in batadv_dat_cache_dump_entry()
925 msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); in batadv_dat_cache_dump_entry()
928 dat_entry->ip) || in batadv_dat_cache_dump_entry()
930 dat_entry->mac_addr) || in batadv_dat_cache_dump_entry()
931 nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || in batadv_dat_cache_dump_entry()
934 return -EMSGSIZE; in batadv_dat_cache_dump_entry()
942 * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
962 spin_lock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
963 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_dat_cache_dump_bucket()
965 hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { in batadv_dat_cache_dump_bucket()
970 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
973 return -EMSGSIZE; in batadv_dat_cache_dump_bucket()
979 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
985 * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
994 int portid = NETLINK_CB(cb->skb).portid; in batadv_dat_cache_dump()
995 struct net *net = sock_net(cb->skb->sk); in batadv_dat_cache_dump()
999 int bucket = cb->args[0]; in batadv_dat_cache_dump()
1000 int idx = cb->args[1]; in batadv_dat_cache_dump()
1004 ifindex = batadv_netlink_get_ifindex(cb->nlh, in batadv_dat_cache_dump()
1007 return -EINVAL; in batadv_dat_cache_dump()
1011 ret = -ENODEV; in batadv_dat_cache_dump()
1016 hash = bat_priv->dat.hash; in batadv_dat_cache_dump()
1019 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_dat_cache_dump()
1020 ret = -ENOENT; in batadv_dat_cache_dump()
1024 while (bucket < hash->size) { in batadv_dat_cache_dump()
1033 cb->args[0] = bucket; in batadv_dat_cache_dump()
1034 cb->args[1] = idx; in batadv_dat_cache_dump()
1036 ret = msg->len; in batadv_dat_cache_dump()
1049 * batadv_arp_get_type() - parse an ARP packet and gets the type
1065 /* pull the ethernet header */ in batadv_arp_get_type()
1069 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_arp_get_type()
1071 if (ethhdr->h_proto != htons(ETH_P_ARP)) in batadv_arp_get_type()
1074 /* pull the ARP payload */ in batadv_arp_get_type()
1076 arp_hdr_len(skb->dev)))) in batadv_arp_get_type()
1079 arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); in batadv_arp_get_type()
1082 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) in batadv_arp_get_type()
1085 if (arphdr->ar_pro != htons(ETH_P_IP)) in batadv_arp_get_type()
1088 if (arphdr->ar_hln != ETH_ALEN) in batadv_arp_get_type()
1091 if (arphdr->ar_pln != 4) in batadv_arp_get_type()
1110 if (arphdr->ar_op != htons(ARPOP_REQUEST)) { in batadv_arp_get_type()
1117 type = ntohs(arphdr->ar_op); in batadv_arp_get_type()
1123 * batadv_dat_get_vid() - extract the VLAN identifier from skb if any
1125 * @hdr_size: the size of the batman-adv header encapsulating the packet
1149 * batadv_dat_arp_create_reply() - create an ARP Reply
1169 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, in batadv_dat_arp_create_reply()
1184 * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
1202 struct net_device *soft_iface = bat_priv->soft_iface; in batadv_dat_snoop_outgoing_arp_request()
1206 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_request()
1232 * Moreover, if the soft-interface is enslaved into a bridge, an in batadv_dat_snoop_outgoing_arp_request()
1236 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1247 dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1250 dat_entry->mac_addr); in batadv_dat_snoop_outgoing_arp_request()
1256 dat_entry->mac_addr, in batadv_dat_snoop_outgoing_arp_request()
1261 skb_new->protocol = eth_type_trans(skb_new, soft_iface); in batadv_dat_snoop_outgoing_arp_request()
1265 skb->len + ETH_HLEN + hdr_size); in batadv_dat_snoop_outgoing_arp_request()
1282 * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to
1302 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_request()
1324 dat_entry->mac_addr, hw_src, vid); in batadv_dat_snoop_incoming_arp_request()
1352 * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT
1365 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_reply()
1394 * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
1413 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_reply()
1436 if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { in batadv_dat_snoop_incoming_arp_reply()
1437 … 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()
1439 dat_entry->mac_addr, &dat_entry->ip); in batadv_dat_snoop_incoming_arp_reply()
1480 /* if dropped == false -> deliver to the interface */ in batadv_dat_snoop_incoming_arp_reply()
1485 * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP
1503 if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr)) in batadv_dat_check_dhcp_ipudp()
1506 if (iphdr->protocol != IPPROTO_UDP) in batadv_dat_check_dhcp_ipudp()
1509 offset += iphdr->ihl * 4; in batadv_dat_check_dhcp_ipudp()
1513 if (!udphdr || udphdr->source != htons(67)) in batadv_dat_check_dhcp_ipudp()
1516 *ip_src = get_unaligned(&iphdr->saddr); in batadv_dat_check_dhcp_ipudp()
1522 * batadv_dat_check_dhcp() - examine packet for valid DHCP message
1533 * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
1548 return -EINVAL; in batadv_dat_check_dhcp()
1551 return -EINVAL; in batadv_dat_check_dhcp()
1554 if (skb->len < offset + sizeof(struct batadv_dhcp_packet)) in batadv_dat_check_dhcp()
1555 return -EINVAL; in batadv_dat_check_dhcp()
1558 if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET || in batadv_dat_check_dhcp()
1559 dhcp_h->hlen != ETH_ALEN) in batadv_dat_check_dhcp()
1560 return -EINVAL; in batadv_dat_check_dhcp()
1566 return -EINVAL; in batadv_dat_check_dhcp()
1568 return dhcp_h->op; in batadv_dat_check_dhcp()
1572 * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet
1581 * Return: The found DHCP message type value, if found. -EINVAL otherwise.
1595 if (tl->type == BATADV_DHCP_OPT_MSG_TYPE) in batadv_dat_get_dhcp_message_type()
1598 if (tl->type == BATADV_DHCP_OPT_END) in batadv_dat_get_dhcp_message_type()
1601 if (tl->type == BATADV_DHCP_OPT_PAD) in batadv_dat_get_dhcp_message_type()
1604 offset += tl->len + sizeof(_tl); in batadv_dat_get_dhcp_message_type()
1608 if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE || in batadv_dat_get_dhcp_message_type()
1609 tl->len != sizeof(_type)) in batadv_dat_get_dhcp_message_type()
1610 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1616 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1622 * batadv_dat_get_dhcp_yiaddr() - get yiaddr from a DHCP packet
1649 * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
1676 * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
1723 * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
1762 * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
1784 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_dhcp_ack()
1790 batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source, in batadv_dat_snoop_outgoing_dhcp_ack()
1795 * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache
1798 * @hdr_size: header size, up to the tail of the batman-adv header
1814 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_dhcp_ack()
1820 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_dat_snoop_incoming_dhcp_ack()
1822 proto = ethhdr->h_proto; in batadv_dat_snoop_incoming_dhcp_ack()
1827 hw_src = ethhdr->h_source; in batadv_dat_snoop_incoming_dhcp_ack()
1842 * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be
1859 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_drop_broadcast_packet()
1868 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); in batadv_dat_drop_broadcast_packet()
1870 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()
1874 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()