net/ipv4/udp_tunnel_nic.c

Source file repositories/reference/linux-study-clean/net/ipv4/udp_tunnel_nic.c

File Facts

System
Linux kernel
Corpus path
net/ipv4/udp_tunnel_nic.c
Extension
.c
Size
25397 bytes
Lines
1011
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

struct udp_tunnel_nic_table_entry {
	__be16 port;
	u8 type;
	u8 flags;
	u16 use_cnt;
#define UDP_TUNNEL_NIC_USE_CNT_MAX	U16_MAX
	u8 hw_priv;
};

/**
 * struct udp_tunnel_nic - UDP tunnel port offload state
 * @work:	async work for talking to hardware from process context
 * @dev:	netdev pointer
 * @lock:	protects all fields
 * @need_sync:	at least one port start changed
 * @need_replay: space was freed, we need a replay of all ports
 * @work_pending: @work is currently scheduled
 * @n_tables:	number of tables under @entries
 * @missed:	bitmap of tables which overflown
 * @entries:	table of tables of ports currently offloaded
 */
struct udp_tunnel_nic {
	struct work_struct work;

	struct net_device *dev;

	struct mutex lock;

	u8 need_sync:1;
	u8 need_replay:1;
	u8 work_pending:1;

	unsigned int n_tables;
	unsigned long missed;
	struct udp_tunnel_nic_table_entry *entries[] __counted_by(n_tables);
};

/* We ensure all work structs are done using driver state, but not the code.
 * We need a workqueue we can flush before module gets removed.
 */
static struct workqueue_struct *udp_tunnel_nic_workqueue;

static const char *udp_tunnel_nic_tunnel_type_name(unsigned int type)
{
	switch (type) {
	case UDP_TUNNEL_TYPE_VXLAN:
		return "vxlan";
	case UDP_TUNNEL_TYPE_GENEVE:
		return "geneve";
	case UDP_TUNNEL_TYPE_VXLAN_GPE:
		return "vxlan-gpe";
	default:
		return "unknown";
	}
}

static bool
udp_tunnel_nic_entry_is_free(struct udp_tunnel_nic_table_entry *entry)
{
	return entry->use_cnt == 0 && !entry->flags;
}

static bool
udp_tunnel_nic_entry_is_present(struct udp_tunnel_nic_table_entry *entry)
{
	return entry->use_cnt && !(entry->flags & ~UDP_TUNNEL_NIC_ENTRY_FROZEN);
}

static bool
udp_tunnel_nic_entry_is_frozen(struct udp_tunnel_nic_table_entry *entry)
{
	return entry->flags & UDP_TUNNEL_NIC_ENTRY_FROZEN;
}

static void
udp_tunnel_nic_entry_freeze_used(struct udp_tunnel_nic_table_entry *entry)
{
	if (!udp_tunnel_nic_entry_is_free(entry))
		entry->flags |= UDP_TUNNEL_NIC_ENTRY_FROZEN;
}

static void
udp_tunnel_nic_entry_unfreeze(struct udp_tunnel_nic_table_entry *entry)
{
	entry->flags &= ~UDP_TUNNEL_NIC_ENTRY_FROZEN;
}

static bool
udp_tunnel_nic_entry_is_queued(struct udp_tunnel_nic_table_entry *entry)
{

Annotation

Implementation Notes