Lines Matching +full:magic +full:- +full:packet
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"
89 __be32 magic; member
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 queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work, in batadv_dat_start_timer()
109 * batadv_dat_entry_release() - release dat_entry from lists and queue for free
123 * batadv_dat_entry_put() - decrement the dat_entry refcounter and possibly
132 kref_put(&dat_entry->refcount, batadv_dat_entry_release); in batadv_dat_entry_put()
136 * batadv_dat_to_purge() - check whether a dat_entry has to be purged or not
143 return batadv_has_timed_out(dat_entry->last_update, in batadv_dat_to_purge()
148 * __batadv_dat_purge() - delete entries from the DAT local storage
167 if (!bat_priv->dat.hash) in __batadv_dat_purge()
170 for (i = 0; i < bat_priv->dat.hash->size; i++) { in __batadv_dat_purge()
171 head = &bat_priv->dat.hash->table[i]; in __batadv_dat_purge()
172 list_lock = &bat_priv->dat.hash->list_locks[i]; in __batadv_dat_purge()
183 hlist_del_rcu(&dat_entry->hash_entry); in __batadv_dat_purge()
191 * batadv_dat_purge() - periodic task that deletes old entries from the local
210 * batadv_compare_dat() - comparing function used in the local DAT hash table
225 * batadv_arp_hw_src() - extract the hw_src field from an ARP packet
226 * @skb: ARP packet
227 * @hdr_size: size of the possible header before the ARP packet
229 * Return: the value of the hw_src field in the ARP packet.
235 addr = (u8 *)(skb->data + hdr_size); in batadv_arp_hw_src()
242 * batadv_arp_ip_src() - extract the ip_src field from an ARP packet
243 * @skb: ARP packet
244 * @hdr_size: size of the possible header before the ARP packet
246 * Return: the value of the ip_src field in the ARP packet.
254 * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet
255 * @skb: ARP packet
256 * @hdr_size: size of the possible header before the ARP packet
258 * Return: the value of the hw_dst field in the ARP packet.
266 * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet
267 * @skb: ARP packet
268 * @hdr_size: size of the possible header before the ARP packet
270 * Return: the value of the ip_dst field in the ARP packet.
280 * batadv_hash_dat() - compute the hash value for an IP address
294 key = (__force const unsigned char *)&dat->ip; in batadv_hash_dat()
295 for (i = 0; i < sizeof(dat->ip); i++) { in batadv_hash_dat()
301 vid = htons(dat->vid); in batadv_hash_dat()
303 for (i = 0; i < sizeof(dat->vid); i++) { in batadv_hash_dat()
317 * batadv_dat_entry_hash_find() - look for a given dat_entry in the local hash
331 struct batadv_hashtable *hash = bat_priv->dat.hash; in batadv_dat_entry_hash_find()
340 index = batadv_hash_dat(&to_find, hash->size); in batadv_dat_entry_hash_find()
341 head = &hash->table[index]; in batadv_dat_entry_hash_find()
345 if (dat_entry->ip != ip) in batadv_dat_entry_hash_find()
348 if (!kref_get_unless_zero(&dat_entry->refcount)) in batadv_dat_entry_hash_find()
360 * batadv_dat_entry_add() - add a new dat entry or update it if already exists
375 if (!batadv_compare_eth(dat_entry->mac_addr, mac_addr)) in batadv_dat_entry_add()
376 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
377 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
380 &dat_entry->ip, dat_entry->mac_addr, in batadv_dat_entry_add()
389 dat_entry->ip = ip; in batadv_dat_entry_add()
390 dat_entry->vid = vid; in batadv_dat_entry_add()
391 ether_addr_copy(dat_entry->mac_addr, mac_addr); in batadv_dat_entry_add()
392 dat_entry->last_update = jiffies; in batadv_dat_entry_add()
393 kref_init(&dat_entry->refcount); in batadv_dat_entry_add()
395 kref_get(&dat_entry->refcount); in batadv_dat_entry_add()
396 hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat, in batadv_dat_entry_add()
398 &dat_entry->hash_entry); in batadv_dat_entry_add()
407 &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
419 * @skb: ARP packet
420 * @hdr_size: size of the possible header before 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()
449 "* encapsulated within a UNICAST packet\n"); in batadv_dbg_arp()
453 "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n", 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()
478 "* encapsulated within a BCAST packet (src: %pM)\n", in batadv_dbg_arp()
483 "* encapsulated within an unknown packet type (0x%x)\n", 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
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()
608 select, max_orig_node->orig, max_orig_node->dat_addr, in batadv_choose_next_candidate()
615 * batadv_dat_select_candidates() - select the nodes which the DHT message has
636 if (!bat_priv->orig_hash) in batadv_dat_select_candidates()
661 * batadv_dat_forward_data() - copy and send payload to the selected candidates
666 * @packet_subtype: unicast4addr packet subtype to use
668 * This function copies the skb with pskb_copy() and is sent as a unicast packet
671 * Return: true if the packet is sent to at least one candidate, false
710 /* count the sent packet */ in batadv_dat_forward_data()
722 /* packet sent to a candidate: return true */ in batadv_dat_forward_data()
736 * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat
744 dat_mode = atomic_read(&bat_priv->distributed_arp_table); in batadv_dat_tvlv_container_update()
758 * batadv_dat_status_update() - update the dat tvlv container after dat
770 * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container
783 clear_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
785 set_bit(BATADV_ORIG_CAPA_HAS_DAT, &orig->capabilities); in batadv_dat_tvlv_ogm_handler_v1()
789 * batadv_dat_hash_free() - free the local DAT hash table
794 if (!bat_priv->dat.hash) in batadv_dat_hash_free()
799 batadv_hash_destroy(bat_priv->dat.hash); in batadv_dat_hash_free()
801 bat_priv->dat.hash = NULL; in batadv_dat_hash_free()
805 * batadv_dat_init() - initialise the DAT internals
812 if (bat_priv->dat.hash) in batadv_dat_init()
815 bat_priv->dat.hash = batadv_hash_new(1024); in batadv_dat_init()
817 if (!bat_priv->dat.hash) in batadv_dat_init()
818 return -ENOMEM; in batadv_dat_init()
820 INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge); in batadv_dat_init()
831 * batadv_dat_free() - free the DAT internals
839 cancel_delayed_work_sync(&bat_priv->dat.work); in batadv_dat_free()
845 * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a
862 hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq, in batadv_dat_cache_dump_entry()
866 return -ENOBUFS; in batadv_dat_cache_dump_entry()
870 msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); in batadv_dat_cache_dump_entry()
873 dat_entry->ip) || in batadv_dat_cache_dump_entry()
875 dat_entry->mac_addr) || in batadv_dat_cache_dump_entry()
876 nla_put_u16(msg, BATADV_ATTR_DAT_CACHE_VID, dat_entry->vid) || in batadv_dat_cache_dump_entry()
879 return -EMSGSIZE; in batadv_dat_cache_dump_entry()
887 * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to
907 spin_lock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
908 cb->seq = atomic_read(&hash->generation) << 1 | 1; in batadv_dat_cache_dump_bucket()
910 hlist_for_each_entry(dat_entry, &hash->table[bucket], hash_entry) { in batadv_dat_cache_dump_bucket()
915 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
918 return -EMSGSIZE; in batadv_dat_cache_dump_bucket()
924 spin_unlock_bh(&hash->list_locks[bucket]); in batadv_dat_cache_dump_bucket()
930 * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket
939 int portid = NETLINK_CB(cb->skb).portid; in batadv_dat_cache_dump()
940 struct net *net = sock_net(cb->skb->sk); in batadv_dat_cache_dump()
944 int bucket = cb->args[0]; in batadv_dat_cache_dump()
945 int idx = cb->args[1]; in batadv_dat_cache_dump()
949 ifindex = batadv_netlink_get_ifindex(cb->nlh, in batadv_dat_cache_dump()
952 return -EINVAL; in batadv_dat_cache_dump()
956 ret = -ENODEV; in batadv_dat_cache_dump()
961 hash = bat_priv->dat.hash; in batadv_dat_cache_dump()
964 if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { in batadv_dat_cache_dump()
965 ret = -ENOENT; in batadv_dat_cache_dump()
969 while (bucket < hash->size) { in batadv_dat_cache_dump()
978 cb->args[0] = bucket; in batadv_dat_cache_dump()
979 cb->args[1] = idx; in batadv_dat_cache_dump()
981 ret = msg->len; in batadv_dat_cache_dump()
992 * batadv_arp_get_type() - parse an ARP packet and gets the type
994 * @skb: packet to analyse
995 * @hdr_size: size of the possible header before the ARP packet in the skb
997 * Return: the ARP type if the skb contains a valid ARP packet, 0 otherwise.
1012 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_arp_get_type()
1014 if (ethhdr->h_proto != htons(ETH_P_ARP)) in batadv_arp_get_type()
1019 arp_hdr_len(skb->dev)))) in batadv_arp_get_type()
1022 arphdr = (struct arphdr *)(skb->data + hdr_size + ETH_HLEN); in batadv_arp_get_type()
1024 /* check whether the ARP packet carries a valid IP information */ in batadv_arp_get_type()
1025 if (arphdr->ar_hrd != htons(ARPHRD_ETHER)) in batadv_arp_get_type()
1028 if (arphdr->ar_pro != htons(ETH_P_IP)) in batadv_arp_get_type()
1031 if (arphdr->ar_hln != ETH_ALEN) in batadv_arp_get_type()
1034 if (arphdr->ar_pln != 4) in batadv_arp_get_type()
1053 if (arphdr->ar_op != htons(ARPOP_REQUEST)) { in batadv_arp_get_type()
1060 type = ntohs(arphdr->ar_op); in batadv_arp_get_type()
1066 * batadv_dat_get_vid() - extract the VLAN identifier from skb if any
1067 * @skb: the buffer containing the packet to extract the VID from
1068 * @hdr_size: the size of the batman-adv header encapsulating the packet
1070 * Return: If the packet embedded in the skb is vlan tagged this function
1081 * If the header contained in the packet is a VLAN one (which is longer) in batadv_dat_get_vid()
1092 * batadv_dat_arp_create_reply() - create an ARP Reply
1112 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, in batadv_dat_arp_create_reply()
1127 * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
1130 * @skb: packet to check
1145 struct net_device *soft_iface = bat_priv->soft_iface; in batadv_dat_snoop_outgoing_arp_request()
1149 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_request()
1173 * duplicate packet. in batadv_dat_snoop_outgoing_arp_request()
1175 * Moreover, if the soft-interface is enslaved into a bridge, an in batadv_dat_snoop_outgoing_arp_request()
1177 * a packet coming from the wrong port. in batadv_dat_snoop_outgoing_arp_request()
1179 if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1190 dat_entry->mac_addr, vid)) { in batadv_dat_snoop_outgoing_arp_request()
1193 dat_entry->mac_addr); in batadv_dat_snoop_outgoing_arp_request()
1199 dat_entry->mac_addr, in batadv_dat_snoop_outgoing_arp_request()
1204 skb_new->protocol = eth_type_trans(skb_new, soft_iface); in batadv_dat_snoop_outgoing_arp_request()
1208 skb->len + ETH_HLEN + hdr_size); in batadv_dat_snoop_outgoing_arp_request()
1224 * batadv_dat_snoop_incoming_arp_request() - snoop the ARP request and try to
1227 * @skb: packet to check
1244 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_request()
1266 dat_entry->mac_addr, hw_src, vid); in batadv_dat_snoop_incoming_arp_request()
1271 * format based on the incoming request packet type. The assumption is in batadv_dat_snoop_incoming_arp_request()
1272 * that a node not using the 4addr packet format doesn't support it. in batadv_dat_snoop_incoming_arp_request()
1293 * batadv_dat_snoop_outgoing_arp_reply() - snoop the ARP reply and fill the DHT
1295 * @skb: packet to check
1306 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_reply()
1335 * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
1338 * @skb: packet to check
1341 * Return: true if the packet was snooped and consumed by DAT. False if the
1342 * packet has to be delivered to the interface
1354 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_arp_reply()
1377 if (dat_entry && batadv_compare_eth(hw_src, dat_entry->mac_addr)) { in batadv_dat_snoop_incoming_arp_reply()
1378 … 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()
1380 dat_entry->mac_addr, &dat_entry->ip); in batadv_dat_snoop_incoming_arp_reply()
1408 * packet to the interface in batadv_dat_snoop_incoming_arp_reply()
1413 * packet because the client will reply by itself in batadv_dat_snoop_incoming_arp_reply()
1420 /* if dropped == false -> deliver to the interface */ in batadv_dat_snoop_incoming_arp_reply()
1425 * batadv_dat_check_dhcp_ipudp() - check skb for IP+UDP headers valid for DHCP
1426 * @skb: the packet to check
1443 if (!iphdr || iphdr->version != 4 || iphdr->ihl * 4 < sizeof(_iphdr)) in batadv_dat_check_dhcp_ipudp()
1446 if (iphdr->protocol != IPPROTO_UDP) in batadv_dat_check_dhcp_ipudp()
1449 offset += iphdr->ihl * 4; in batadv_dat_check_dhcp_ipudp()
1453 if (!udphdr || udphdr->source != htons(67)) in batadv_dat_check_dhcp_ipudp()
1456 *ip_src = get_unaligned(&iphdr->saddr); in batadv_dat_check_dhcp_ipudp()
1462 * batadv_dat_check_dhcp() - examine packet for valid DHCP message
1463 * @skb: the packet to check
1467 * Checks whether the given skb is a valid DHCP packet. And if so, stores the
1472 * Return: If skb is a valid DHCP packet, then returns its op code
1473 * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
1478 __be32 *magic, _magic; in batadv_dat_check_dhcp() local
1488 return -EINVAL; in batadv_dat_check_dhcp()
1491 return -EINVAL; in batadv_dat_check_dhcp()
1494 if (skb->len < offset + sizeof(struct batadv_dhcp_packet)) in batadv_dat_check_dhcp()
1495 return -EINVAL; in batadv_dat_check_dhcp()
1498 if (!dhcp_h || dhcp_h->htype != BATADV_HTYPE_ETHERNET || in batadv_dat_check_dhcp()
1499 dhcp_h->hlen != ETH_ALEN) in batadv_dat_check_dhcp()
1500 return -EINVAL; in batadv_dat_check_dhcp()
1502 offset += offsetof(struct batadv_dhcp_packet, magic); in batadv_dat_check_dhcp()
1504 magic = skb_header_pointer(skb, offset, sizeof(_magic), &_magic); in batadv_dat_check_dhcp()
1505 if (!magic || get_unaligned(magic) != htonl(BATADV_DHCP_MAGIC)) in batadv_dat_check_dhcp()
1506 return -EINVAL; in batadv_dat_check_dhcp()
1508 return dhcp_h->op; in batadv_dat_check_dhcp()
1512 * batadv_dat_get_dhcp_message_type() - get message type of a DHCP packet
1513 * @skb: the DHCP packet to parse
1515 * Iterates over the DHCP options of the given DHCP packet to find a
1518 * Caller needs to ensure that the given skb is a valid DHCP packet and
1521 * Return: The found DHCP message type value, if found. -EINVAL otherwise.
1535 if (tl->type == BATADV_DHCP_OPT_MSG_TYPE) in batadv_dat_get_dhcp_message_type()
1538 if (tl->type == BATADV_DHCP_OPT_END) in batadv_dat_get_dhcp_message_type()
1541 if (tl->type == BATADV_DHCP_OPT_PAD) in batadv_dat_get_dhcp_message_type()
1544 offset += tl->len + sizeof(_tl); in batadv_dat_get_dhcp_message_type()
1548 if (!tl || tl->type != BATADV_DHCP_OPT_MSG_TYPE || in batadv_dat_get_dhcp_message_type()
1549 tl->len != sizeof(_type)) in batadv_dat_get_dhcp_message_type()
1550 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1556 return -EINVAL; in batadv_dat_get_dhcp_message_type()
1562 * batadv_dat_dhcp_get_yiaddr() - get yiaddr from a DHCP packet
1563 * @skb: the DHCP packet to parse
1566 * Caller needs to ensure that the given skb is a valid DHCP packet and
1589 * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
1590 * @skb: the DHCP packet to parse
1593 * Caller needs to ensure that the given skb is a valid DHCP packet and
1616 * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
1663 * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
1664 * @skb: the packet to check
1702 * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
1704 * @skb: the packet to snoop
1724 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_dhcp_ack()
1730 batadv_dat_put_dhcp(bat_priv, chaddr, yiaddr, eth_hdr(skb)->h_source, in batadv_dat_snoop_outgoing_dhcp_ack()
1735 * batadv_dat_snoop_incoming_dhcp_ack() - snoop DHCPACK and fill DAT cache
1737 * @skb: the packet to snoop
1738 * @hdr_size: header size, up to the tail of the batman-adv header
1754 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_incoming_dhcp_ack()
1760 ethhdr = (struct ethhdr *)(skb->data + hdr_size); in batadv_dat_snoop_incoming_dhcp_ack()
1762 proto = ethhdr->h_proto; in batadv_dat_snoop_incoming_dhcp_ack()
1767 hw_src = ethhdr->h_source; in batadv_dat_snoop_incoming_dhcp_ack()
1782 * batadv_dat_drop_broadcast_packet() - check if an ARP request has to be
1785 * @forw_packet: the broadcast packet
1787 * Return: true if the node can drop the packet, false otherwise.
1799 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_drop_broadcast_packet()
1802 /* If this packet is an ARP_REQUEST and the node already has the in batadv_dat_drop_broadcast_packet()
1803 * information that it is going to ask, then the packet can be dropped in batadv_dat_drop_broadcast_packet()
1808 vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size); in batadv_dat_drop_broadcast_packet()
1810 type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()
1814 ip_dst = batadv_arp_ip_dst(forw_packet->skb, hdr_size); in batadv_dat_drop_broadcast_packet()