net/batman-adv/bat_iv_ogm.c

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

File Facts

System
Linux kernel
Corpus path
net/batman-adv/bat_iv_ogm.c
Extension
.c
Size
77754 bytes
Lines
2637
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 (*ptr != 0) {
			count++;
			sum += *ptr;
		}

		i++;
		ptr++;
	}

	if (count == 0)
		return 0;

	return (u8)(sum / count);
}

/**
 * batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
 *  originator
 * @bat_priv: the bat priv with all the mesh interface information
 * @addr: mac address of the originator
 *
 * Return: the originator object corresponding to the passed mac address or NULL
 * on failure.
 * If the object does not exist, it is created and initialised.
 */
static struct batadv_orig_node *
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
{
	struct batadv_orig_node *orig_node;
	int hash_added;

	orig_node = batadv_orig_hash_find(bat_priv, addr);
	if (orig_node)
		return orig_node;

	orig_node = batadv_orig_node_new(bat_priv, addr);
	if (!orig_node)
		return NULL;

	spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);

	kref_get(&orig_node->refcount);
	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
				     batadv_choose_orig, orig_node,
				     &orig_node->hash_entry);
	if (hash_added != 0)
		goto free_orig_node_hash;

	return orig_node;

free_orig_node_hash:
	/* reference for batadv_hash_add */
	batadv_orig_node_put(orig_node);
	/* reference from batadv_orig_node_new */
	batadv_orig_node_put(orig_node);

	return NULL;
}

static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
			const u8 *neigh_addr,
			struct batadv_orig_node *orig_node)
{
	struct batadv_neigh_node *neigh_node;

	neigh_node = batadv_neigh_node_get_or_create(orig_node,
						     hard_iface, neigh_addr);
	return neigh_node;
}

static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
{
	struct batadv_ogm_packet *batadv_ogm_packet;
	unsigned char *ogm_buff;
	u32 random_seqno;

	mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);

	/* randomize initial seqno to avoid collision */
	get_random_bytes(&random_seqno, sizeof(random_seqno));
	atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);

	hard_iface->bat_iv.ogm_buff.len = BATADV_OGM_HLEN;
	hard_iface->bat_iv.ogm_buff.capacity = BATADV_OGM_HLEN;
	hard_iface->bat_iv.ogm_buff.header_length = BATADV_OGM_HLEN;

	ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff.capacity, GFP_ATOMIC);
	if (!ogm_buff) {
		mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);

Annotation

Implementation Notes