net/batman-adv/multicast_forw.c

Source file repositories/reference/linux-study-clean/net/batman-adv/multicast_forw.c

File Facts

System
Linux kernel
Corpus path
net/batman-adv/multicast_forw.c
Extension
.c
Size
37035 bytes
Lines
1179
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (is_multicast_ether_addr(next_dest)) {
			eth_zero_addr(dest);
			eth_zero_addr(next_dest);
			continue;
		}

		next_neigh = batadv_orig_to_router(bat_priv, next_dest, NULL);
		if (!next_neigh) {
			eth_zero_addr(next_dest);
			continue;
		}

		if (!batadv_compare_eth(next_neigh->addr, comp_neigh->addr)) {
			eth_zero_addr(next_dest);
			batadv_neigh_node_put(next_neigh);
			continue;
		}

		/* found an entry for our next packet to transmit, so remove it
		 * from the original packet
		 */
		eth_zero_addr(dest);
		batadv_neigh_node_put(next_neigh);
	}
}

/**
 * batadv_mcast_forw_shrink_fill() - swap slot with next non-zero destination
 * @slot: the to be filled zero-MAC destination entry in a tracker TVLV
 * @num_dests_slot: remaining entries in tracker TVLV from/including slot
 *
 * Searches for the next non-zero-MAC destination entry in a tracker TVLV after
 * the given slot pointer. And if found, swaps it with the zero-MAC destination
 * entry which the slot points to.
 *
 * Return: true if slot was swapped/filled successfully, false otherwise.
 */
static bool batadv_mcast_forw_shrink_fill(u8 *slot, u16 num_dests_slot)
{
	u16 num_dests_filler;
	u8 *filler;

	/* sanity check, should not happen */
	if (!num_dests_slot)
		return false;

	num_dests_filler = num_dests_slot - 1;
	filler = slot + ETH_ALEN;

	/* find a candidate to fill the empty slot */
	batadv_mcast_forw_tracker_for_each_dest(filler, num_dests_filler) {
		if (is_zero_ether_addr(filler))
			continue;

		ether_addr_copy(slot, filler);
		eth_zero_addr(filler);
		return true;
	}

	return false;
}

/**
 * batadv_mcast_forw_shrink_pack_dests() - pack destinations of a tracker TVLV
 * @skb: the batman-adv multicast packet to compact destinations in
 *
 * Compacts the originator destination MAC addresses in the multicast tracker
 * TVLV of the given multicast packet. This is done by moving all non-zero
 * MAC addresses in direction of the skb head and all zero MAC addresses in skb
 * tail direction, within the multicast tracker TVLV.
 *
 * Return: The number of consecutive zero MAC address destinations which are
 * now at the end of the multicast tracker TVLV.
 */
static int batadv_mcast_forw_shrink_pack_dests(struct sk_buff *skb)
{
	struct batadv_tvlv_mcast_tracker *mcast_tracker;
	unsigned char *skb_net_hdr;
	u16 num_dests_slot;
	u8 *slot;

	skb_net_hdr = skb_network_header(skb);
	mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb_net_hdr;
	num_dests_slot = ntohs(mcast_tracker->num_dests);

	slot = (u8 *)mcast_tracker + sizeof(*mcast_tracker);

	batadv_mcast_forw_tracker_for_each_dest(slot, num_dests_slot) {
		/* find an empty slot */
		if (!is_zero_ether_addr(slot))

Annotation

Implementation Notes