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 "translation-table.h"
88 __be32 magic; member
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
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
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
225 * @skb: ARP packet
226 * @hdr_size: size of the possible header before the ARP packet
228 * Return: the value of the hw_src field in the 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
242 * @skb: ARP packet
243 * @hdr_size: size of the possible header before the ARP packet
245 * Return: the value of the ip_src field in the ARP packet.
253 * batadv_arp_hw_dst() - extract the hw_dst field from an ARP packet
254 * @skb: ARP packet
255 * @hdr_size: size of the possible header before the ARP packet
257 * Return: the value of the hw_dst field in the ARP packet.
265 * batadv_arp_ip_dst() - extract the ip_dst field from an ARP packet
266 * @skb: ARP packet
267 * @hdr_size: size of the possible header before the ARP packet
269 * Return: the value of the ip_dst field in the 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()
415 * batadv_dbg_arp() - print a debug message containing all the ARP packet
418 * @skb: ARP packet
419 * @hdr_size: size of the possible header before the ARP packet
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()
448 "* encapsulated within a UNICAST packet\n"); in batadv_dbg_arp()
452 "* encapsulated within a UNICAST_4ADDR packet (src: %pM)\n", 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()
477 "* encapsulated within a BCAST packet (src: %pM)\n", in batadv_dbg_arp()
482 "* encapsulated within an unknown packet type (0x%x)\n", 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
520 if (!test_bit(BATADV_ORIG_CAPA_HAS_DAT, &candidate->capabilities)) 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
566 struct batadv_hashtable *hash = bat_priv->orig_hash; 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
635 if (!bat_priv->orig_hash) in batadv_dat_select_candidates()
660 * batadv_dat_forward_data() - copy and send payload to the selected candidates
665 * @packet_subtype: unicast4addr packet subtype to use
667 * This function copies the skb with pskb_copy() and is sent as a unicast packet
670 * Return: true if the packet is sent to at least one candidate, false
709 /* count the sent packet */ in batadv_dat_forward_data()
721 /* packet sent to a candidate: return true */ in batadv_dat_forward_data()
735 * batadv_dat_tvlv_container_update() - update the dat tvlv container after dat
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
769 * batadv_dat_tvlv_ogm_handler_v1() - process incoming dat tvlv container
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
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
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
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
984 * @skb: packet to analyse
985 * @hdr_size: size of the possible header before the ARP packet in the skb
987 * Return: the ARP type if the skb contains a valid ARP packet, 0 otherwise.
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()
1014 /* check whether the ARP packet carries a valid IP information */ 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
1057 * @skb: the buffer containing the packet to extract the VID from
1058 * @hdr_size: the size of the batman-adv header encapsulating the packet
1060 * Return: If the packet embedded in the skb is vlan tagged this function
1071 * If the header contained in the packet is a VLAN one (which is longer) in batadv_dat_get_vid()
1082 * batadv_dat_arp_create_reply() - create an ARP Reply
1102 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_dst, bat_priv->soft_iface, in batadv_dat_arp_create_reply()
1117 * batadv_dat_snoop_outgoing_arp_request() - snoop the ARP request and try to
1120 * @skb: packet to check
1135 struct net_device *soft_iface = bat_priv->soft_iface; in batadv_dat_snoop_outgoing_arp_request()
1139 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_request()
1163 * duplicate packet. in batadv_dat_snoop_outgoing_arp_request()
1165 * Moreover, if the soft-interface is enslaved into a bridge, an in batadv_dat_snoop_outgoing_arp_request()
1167 * a packet coming from the wrong port. 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, soft_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
1217 * @skb: packet to check
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()
1261 * format based on the incoming request packet type. The assumption is 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
1285 * @skb: packet to check
1296 if (!atomic_read(&bat_priv->distributed_arp_table)) in batadv_dat_snoop_outgoing_arp_reply()
1325 * batadv_dat_snoop_incoming_arp_reply() - snoop the ARP reply and fill the
1328 * @skb: packet to check
1331 * Return: true if the packet was snooped and consumed by DAT. False if the
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()
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()
1398 * packet to the interface in batadv_dat_snoop_incoming_arp_reply()
1403 * packet because the client will reply by itself 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
1416 * @skb: the packet to check
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
1453 * @skb: the packet to check
1457 * Checks whether the given skb is a valid DHCP packet. And if so, stores the
1462 * Return: If skb is a valid DHCP packet, then returns its op code
1463 * (e.g. BOOTREPLY vs. BOOTREQUEST). Otherwise returns -EINVAL.
1468 __be32 *magic, _magic; in batadv_dat_check_dhcp() local
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()
1492 offset += offsetof(struct batadv_dhcp_packet, magic); in batadv_dat_check_dhcp()
1494 magic = skb_header_pointer(skb, offset, sizeof(_magic), &_magic); in batadv_dat_check_dhcp()
1495 if (!magic || get_unaligned(magic) != htonl(BATADV_DHCP_MAGIC)) 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
1503 * @skb: the DHCP packet to parse
1505 * Iterates over the DHCP options of the given DHCP packet to find a
1508 * Caller needs to ensure that the given skb is a valid DHCP packet and
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
1553 * @skb: the DHCP packet to parse
1556 * Caller needs to ensure that the given skb is a valid DHCP packet and
1579 * batadv_dat_get_dhcp_chaddr() - get chaddr from a DHCP packet
1580 * @skb: the DHCP packet to parse
1583 * Caller needs to ensure that the given skb is a valid DHCP packet and
1606 * batadv_dat_put_dhcp() - puts addresses from a DHCP packet into the DHT and
1653 * batadv_dat_check_dhcp_ack() - examine packet for valid DHCP message
1654 * @skb: the packet to check
1692 * batadv_dat_snoop_outgoing_dhcp_ack() - snoop DHCPACK and fill DAT with it
1694 * @skb: the packet to snoop
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
1727 * @skb: the packet to snoop
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
1775 * @forw_packet: the broadcast packet
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()
1793 * information that it is going to ask, then the packet can be dropped 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()