net/psp/psp_sock.c

Source file repositories/reference/linux-study-clean/net/psp/psp_sock.c

File Facts

System
Linux kernel
Corpus path
net/psp/psp_sock.c
Extension
.c
Size
6619 bytes
Lines
294
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

// SPDX-License-Identifier: GPL-2.0-only

#include <linux/file.h>
#include <linux/net.h>
#include <linux/rcupdate.h>
#include <linux/tcp.h>

#include <net/ip.h>
#include <net/psp.h>
#include "psp.h"

struct psp_dev *psp_dev_get_for_sock(struct sock *sk)
{
	struct psp_dev *psd = NULL;
	struct dst_entry *dst;

	rcu_read_lock();
	dst = __sk_dst_get(sk);
	if (dst) {
		psd = rcu_dereference(dst_dev_rcu(dst)->psp_dev);
		if (psd && !psp_dev_tryget(psd))
			psd = NULL;
	}
	rcu_read_unlock();

	return psd;
}

static struct sk_buff *
psp_validate_xmit(struct sock *sk, struct net_device *dev, struct sk_buff *skb)
{
	struct psp_assoc *pas;
	bool good;

	rcu_read_lock();
	pas = psp_skb_get_assoc_rcu(skb);
	good = !pas || rcu_access_pointer(dev->psp_dev) == pas->psd;
	rcu_read_unlock();
	if (!good) {
		sk_skb_reason_drop(sk, skb, SKB_DROP_REASON_PSP_OUTPUT);
		return NULL;
	}

	return skb;
}

struct psp_assoc *psp_assoc_create(struct psp_dev *psd)
{
	struct psp_assoc *pas;

	lockdep_assert_held(&psd->lock);

	pas = kzalloc_flex(*pas, drv_data, psd->caps->assoc_drv_spc,
			   GFP_KERNEL_ACCOUNT);
	if (!pas)
		return NULL;

	pas->psd = psd;
	pas->dev_id = psd->id;
	pas->generation = psd->generation;
	psp_dev_get(psd);
	refcount_set(&pas->refcnt, 1);

	list_add_tail(&pas->assocs_list, &psd->active_assocs);

	return pas;
}

static struct psp_assoc *psp_assoc_dummy(struct psp_assoc *pas)
{
	struct psp_dev *psd = pas->psd;
	size_t sz;

	lockdep_assert_held(&psd->lock);

	sz = struct_size(pas, drv_data, psd->caps->assoc_drv_spc);
	return kmemdup(pas, sz, GFP_KERNEL);
}

static int psp_dev_tx_key_add(struct psp_dev *psd, struct psp_assoc *pas,
			      struct netlink_ext_ack *extack)
{
	return psd->ops->tx_key_add(psd, pas, extack);
}

void psp_dev_tx_key_del(struct psp_dev *psd, struct psp_assoc *pas)
{
	if (pas->tx.spi)
		psd->ops->tx_key_del(psd, pas);
	list_del(&pas->assocs_list);

Annotation

Implementation Notes