net/batman-adv/tp_meter.c

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

File Facts

System
Linux kernel
Corpus path
net/batman-adv/tp_meter.c
Extension
.c
Size
50897 bytes
Lines
1735
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 (batadv_seq_before(recv_ack, tp_vars->cc.recover)) {
			/* this is another hole in the window. React
			 * immediately as specified by NewReno (see
			 * Section 3.2 of RFC6582 for details)
			 */
			reaction = BATADV_TP_ACK_REACTION_RESEND_WAKEUP;
			tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.cwnd,
							  mss, mss);
		} else {
			tp_vars->cc.fast_recovery = false;
			/* set cwnd to the value of ss_threshold at the
			 * moment that Fast Recovery was entered.
			 * RFC6582, Section 3.2, step 3
			 */
			tp_vars->cc.cwnd = batadv_tp_cwnd(tp_vars->cc.ss_threshold,
							  0, mss);
			reaction = BATADV_TP_ACK_REACTION_WAKEUP;
		}
	} else {
		if (recv_ack - tp_vars->cc.last_acked >= mss)
			batadv_tp_update_cwnd(tp_vars, mss);

		reaction = BATADV_TP_ACK_REACTION_WAKEUP;
	}

	/* move the Transmit Window */
	WRITE_ONCE(tp_vars->cc.last_acked, recv_ack);

	return reaction;
}

/**
 * batadv_tp_recv_ack() - ACK receiving function
 * @bat_priv: the bat priv with all the mesh interface information
 * @skb: the buffer containing the received packet
 *
 * Process a received TP ACK packet
 */
static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
			       const struct sk_buff *skb)
{
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_orig_node *orig_node = NULL;
	const struct batadv_icmp_tp_packet *icmp;
	enum batadv_tp_ack_reaction reaction;
	struct batadv_tp_sender *tp_vars;
	size_t packet_len;
	u32 recv_ack;
	size_t mss;
	u32 rtt;

	packet_len = BATADV_TP_PLEN;
	mss = BATADV_TP_PLEN;
	packet_len += sizeof(struct batadv_unicast_packet);

	icmp = (struct batadv_icmp_tp_packet *)skb->data;
	recv_ack = ntohl(icmp->seqno);

	/* find the tp_vars */
	tp_vars = batadv_tp_list_find_sender_session(bat_priv, icmp->orig,
						     icmp->session);
	if (unlikely(!tp_vars))
		return;

	if (unlikely(batadv_tp_sender_stopped(tp_vars)))
		goto out;

	/* old ACK? silently drop it.. */
	if (batadv_seq_before(recv_ack, READ_ONCE(tp_vars->cc.last_acked)))
		goto out;

	primary_if = batadv_primary_if_get_selected(bat_priv);
	if (unlikely(!primary_if))
		goto out;

	orig_node = batadv_orig_hash_find(bat_priv, icmp->orig);
	if (unlikely(!orig_node))
		goto out;

	spin_lock_bh(&tp_vars->cc_lock);
	/* update RTO with the new sampled RTT, if any */
	rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp);
	if (icmp->timestamp && rtt)
		batadv_tp_update_rto(tp_vars, rtt);

	reaction = batadv_tp_handle_ack(bat_priv, tp_vars, recv_ack, mss);
	spin_unlock_bh(&tp_vars->cc_lock);

	if (reaction == BATADV_TP_ACK_REACTION_OLD_ACK)
		goto out;

Annotation

Implementation Notes