include/net/tcp_ecn.h

Source file repositories/reference/linux-study-clean/include/net/tcp_ecn.h

File Facts

System
Linux kernel
Corpus path
include/net/tcp_ecn.h
Extension
.h
Size
20322 bytes
Lines
676
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

tcp_accecn_validate_syn_feedback(sk, ace, sent_ect)) {
			if ((tcp_accecn_extract_syn_ect(ace) == INET_ECN_CE) &&
			    !tp->delivered_ce)
				WRITE_ONCE(tp->delivered_ce, 1);
		}
		break;
	}
}

/* Demand the minimum # to send AccECN optnio */
static inline void tcp_accecn_opt_demand_min(struct sock *sk,
					     u8 opt_demand_min)
{
	struct tcp_sock *tp = tcp_sk(sk);
	u8 opt_demand;

	opt_demand = max_t(u8, opt_demand_min, tp->accecn_opt_demand);
	tp->accecn_opt_demand = opt_demand;
}

/* Maps IP ECN field ECT/CE code point to AccECN option field number, given
 * we are sending fields with Accurate ECN Order 1: ECT(1), CE, ECT(0).
 */
static inline u8 tcp_ecnfield_to_accecn_optfield(u8 ecnfield)
{
	switch (ecnfield & INET_ECN_MASK) {
	case INET_ECN_NOT_ECT:
		return 0;	/* AccECN does not send counts of NOT_ECT */
	case INET_ECN_ECT_1:
		return 1;
	case INET_ECN_CE:
		return 2;
	case INET_ECN_ECT_0:
		return 3;
	}
	return 0;
}

/* Maps IP ECN field ECT/CE code point to AccECN option field value offset.
 * Some fields do not start from zero, to detect zeroing by middleboxes.
 */
static inline u32 tcp_accecn_field_init_offset(u8 ecnfield)
{
	switch (ecnfield & INET_ECN_MASK) {
	case INET_ECN_NOT_ECT:
		return 0;	/* AccECN does not send counts of NOT_ECT */
	case INET_ECN_ECT_1:
		return TCP_ACCECN_E1B_INIT_OFFSET;
	case INET_ECN_CE:
		return TCP_ACCECN_CEB_INIT_OFFSET;
	case INET_ECN_ECT_0:
		return TCP_ACCECN_E0B_INIT_OFFSET;
	}
	return 0;
}

/* Maps AccECN option field #nr to IP ECN field ECT/CE bits */
static inline unsigned int tcp_accecn_optfield_to_ecnfield(unsigned int option,
							   bool order)
{
	/* Based on Table 5 of the AccECN spec to map (option, order) to
	 * the corresponding ECN conuters (ECT-1, ECT-0, or CE).
	 */
	static const u8 optfield_lookup[2][3] = {
		/* order = 0: 1st field ECT-0, 2nd field CE, 3rd field ECT-1 */
		{ INET_ECN_ECT_0, INET_ECN_CE, INET_ECN_ECT_1 },
		/* order = 1: 1st field ECT-1, 2nd field CE, 3rd field ECT-0 */
		{ INET_ECN_ECT_1, INET_ECN_CE, INET_ECN_ECT_0 }
	};

	return optfield_lookup[order][option % 3];
}

/* Handles AccECN option ECT and CE 24-bit byte counters update into
 * the u32 value in tcp_sock. As we're processing TCP options, it is
 * safe to access from - 1.
 */
static inline s32 tcp_update_ecn_bytes(u32 *cnt, const char *from,
				       u32 init_offset)
{
	u32 truncated = (get_unaligned_be32(from - 1) - init_offset) &
			0xFFFFFFU;
	u32 delta = (truncated - *cnt) & 0xFFFFFFU;

	/* If delta has the highest bit set (24th bit) indicating
	 * negative, sign extend to correct an estimation using
	 * sign_extend32(delta, 24 - 1)
	 */
	delta = sign_extend32(delta, 23);
	*cnt += delta;

Annotation

Implementation Notes