net/tls/tls_device.c

Source file repositories/reference/linux-study-clean/net/tls/tls_device.c

File Facts

System
Linux kernel
Corpus path
net/tls/tls_device.c
Extension
.c
Size
38004 bytes
Lines
1443
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration 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

skb_frag_off(frag) + skb_frag_size(frag) == pfrag->offset) {
		skb_frag_size_add(frag, size);
	} else {
		++frag;
		skb_frag_fill_page_desc(frag, pfrag->page, pfrag->offset,
					size);
		++record->num_frags;
		get_page(pfrag->page);
	}

	pfrag->offset += size;
	record->len += size;
}

static int tls_push_record(struct sock *sk,
			   struct tls_context *ctx,
			   struct tls_offload_context_tx *offload_ctx,
			   struct tls_record_info *record,
			   int flags)
{
	struct tls_prot_info *prot = &ctx->prot_info;
	struct tcp_sock *tp = tcp_sk(sk);
	skb_frag_t *frag;
	int i;

	record->end_seq = tp->write_seq + record->len;
	list_add_tail_rcu(&record->list, &offload_ctx->records_list);
	offload_ctx->open_record = NULL;

	if (test_bit(TLS_TX_SYNC_SCHED, &ctx->flags))
		tls_device_resync_tx(sk, ctx, tp->write_seq);

	tls_advance_record_sn(sk, prot, &ctx->tx);

	for (i = 0; i < record->num_frags; i++) {
		frag = &record->frags[i];
		sg_unmark_end(&offload_ctx->sg_tx_data[i]);
		sg_set_page(&offload_ctx->sg_tx_data[i], skb_frag_page(frag),
			    skb_frag_size(frag), skb_frag_off(frag));
		sk_mem_charge(sk, skb_frag_size(frag));
		get_page(skb_frag_page(frag));
	}
	sg_mark_end(&offload_ctx->sg_tx_data[record->num_frags - 1]);

	/* all ready, send */
	return tls_push_sg(sk, ctx, offload_ctx->sg_tx_data, 0, flags);
}

static void tls_device_record_close(struct sock *sk,
				    struct tls_context *ctx,
				    struct tls_record_info *record,
				    struct page_frag *pfrag,
				    unsigned char record_type)
{
	struct tls_prot_info *prot = &ctx->prot_info;
	struct page_frag dummy_tag_frag;

	/* append tag
	 * device will fill in the tag, we just need to append a placeholder
	 * use socket memory to improve coalescing (re-using a single buffer
	 * increases frag count)
	 * if we can't allocate memory now use the dummy page
	 */
	if (unlikely(pfrag->size - pfrag->offset < prot->tag_size) &&
	    !skb_page_frag_refill(prot->tag_size, pfrag, sk->sk_allocation)) {
		dummy_tag_frag.page = dummy_page;
		dummy_tag_frag.offset = 0;
		pfrag = &dummy_tag_frag;
	}
	tls_append_frag(record, pfrag, prot->tag_size);

	/* fill prepend */
	tls_fill_prepend(ctx, skb_frag_address(&record->frags[0]),
			 record->len - prot->overhead_size,
			 record_type);
}

static int tls_create_new_record(struct tls_offload_context_tx *offload_ctx,
				 struct page_frag *pfrag,
				 size_t prepend_size)
{
	struct tls_record_info *record;
	skb_frag_t *frag;

	record = kmalloc_obj(*record);
	if (!record)
		return -ENOMEM;

	frag = &record->frags[0];
	skb_frag_fill_page_desc(frag, pfrag->page, pfrag->offset,

Annotation

Implementation Notes