net/batman-adv/tvlv.c

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

File Facts

System
Linux kernel
Corpus path
net/batman-adv/tvlv.c
Extension
.c
Size
20387 bytes
Lines
689
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 (newlen <= ogm_buff->capacity) {
			ogm_buff->len = newlen;
			return true;
		}

		return false;
	}

	memcpy(new_buff, ogm_buff->buf, ogm_buff->header_length);
	kfree(ogm_buff->buf);

	ogm_buff->buf = new_buff;
	ogm_buff->len = newlen;
	ogm_buff->capacity = newcapacity;

	return true;
}

/**
 * batadv_tvlv_container_ogm_append() - append tvlv container content to given
 *  OGM packet buffer
 * @bat_priv: the bat priv with all the mesh interface information
 * @ogm_buff: ogm packet buffer
 *
 * The ogm packet might be enlarged or shrunk depending on the current size
 * and the size of the to-be-appended tvlv containers.
 *
 * Return: size of all appended tvlv containers in bytes (max U16_MAX), negative
 *  if operation failed
 */
int batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
				     struct batadv_ogm_buf *ogm_buff)
{
	struct batadv_tvlv_container *tvlv;
	struct batadv_tvlv_hdr *tvlv_hdr;
	size_t tvlv_value_len;
	void *tvlv_value;
	int tvlv_len_ret;
	bool ret;

	spin_lock_bh(&bat_priv->tvlv.container_list_lock);
	tvlv_value_len = batadv_tvlv_container_list_size(bat_priv);
	if (tvlv_value_len > U16_MAX) {
		tvlv_len_ret = -E2BIG;
		goto end;
	}

	ret = batadv_tvlv_realloc_packet_buff(ogm_buff, tvlv_value_len);
	if (!ret) {
		tvlv_len_ret = -ENOMEM;
		goto end;
	}

	tvlv_len_ret = tvlv_value_len;

	if (!tvlv_value_len)
		goto end;

	tvlv_value = (u8 *)ogm_buff->buf + ogm_buff->header_length;

	hlist_for_each_entry(tvlv, &bat_priv->tvlv.container_list, list) {
		tvlv_hdr = tvlv_value;
		tvlv_hdr->type = tvlv->tvlv_hdr.type;
		tvlv_hdr->version = tvlv->tvlv_hdr.version;
		tvlv_hdr->len = tvlv->tvlv_hdr.len;
		tvlv_value = tvlv_hdr + 1;
		memcpy(tvlv_value, tvlv + 1, ntohs(tvlv->tvlv_hdr.len));
		tvlv_value = (u8 *)tvlv_value + ntohs(tvlv->tvlv_hdr.len);
	}

end:
	spin_unlock_bh(&bat_priv->tvlv.container_list_lock);

	return tvlv_len_ret;
}

/**
 * batadv_tvlv_call_handler() - parse the given tvlv buffer to call the
 *  appropriate handlers
 * @bat_priv: the bat priv with all the mesh interface information
 * @tvlv_handler: tvlv callback function handling the tvlv content
 * @packet_type: indicates for which packet type the TVLV handler is called
 * @orig_node: orig node emitting the ogm packet
 * @skb: the skb the TVLV handler is called for
 * @tvlv_value: tvlv content
 * @tvlv_value_len: tvlv content length
 *
 * Return: success if the handler was not found or the return value of the
 * handler callback.
 */

Annotation

Implementation Notes