net/core/filter.c

Source file repositories/reference/linux-study-clean/net/core/filter.c

File Facts

System
Linux kernel
Corpus path
net/core/filter.c
Extension
.c
Size
351555 bytes
Lines
12705
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: operation-table or driver-model contract
Status
pattern 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

const struct net_device_ops *ops = dev->netdev_ops;

	if (likely(ops->ndo_get_peer_dev))
		return INDIRECT_CALL_1(ops->ndo_get_peer_dev,
				       netkit_peer_dev, dev);
	return NULL;
}

int skb_do_redirect(struct sk_buff *skb)
{
	struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();
	struct net *net = dev_net(skb->dev);
	struct net_device *dev;
	u32 flags = ri->flags;

	dev = dev_get_by_index_rcu(net, ri->tgt_index);
	ri->tgt_index = 0;
	ri->flags = 0;
	if (unlikely(!dev))
		goto out_drop;
	if (flags & BPF_F_PEER) {
		if (unlikely(!skb_at_tc_ingress(skb)))
			goto out_drop;
		dev = skb_get_peer_dev(dev);
		if (unlikely(!dev ||
			     !(dev->flags & IFF_UP) ||
			     net_eq(net, dev_net(dev))))
			goto out_drop;
		skb->dev = dev;
		dev_sw_netstats_rx_add(dev, skb->len);
		skb_scrub_packet(skb, false);
		return -EAGAIN;
	}
	return flags & BPF_F_NEIGH ?
	       __bpf_redirect_neigh(skb, dev, flags & BPF_F_NEXTHOP ?
				    &ri->nh : NULL) :
	       __bpf_redirect(skb, dev, flags);
out_drop:
	kfree_skb(skb);
	return -EINVAL;
}

BPF_CALL_2(bpf_redirect, u32, ifindex, u64, flags)
{
	struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();

	if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL)))
		return TC_ACT_SHOT;

	ri->flags = flags;
	ri->tgt_index = ifindex;

	return TC_ACT_REDIRECT;
}

static const struct bpf_func_proto bpf_redirect_proto = {
	.func           = bpf_redirect,
	.gpl_only       = false,
	.ret_type       = RET_INTEGER,
	.arg1_type      = ARG_ANYTHING,
	.arg2_type      = ARG_ANYTHING,
};

BPF_CALL_2(bpf_redirect_peer, u32, ifindex, u64, flags)
{
	struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();

	if (unlikely(flags))
		return TC_ACT_SHOT;

	ri->flags = BPF_F_PEER;
	ri->tgt_index = ifindex;

	return TC_ACT_REDIRECT;
}

static const struct bpf_func_proto bpf_redirect_peer_proto = {
	.func           = bpf_redirect_peer,
	.gpl_only       = false,
	.ret_type       = RET_INTEGER,
	.arg1_type      = ARG_ANYTHING,
	.arg2_type      = ARG_ANYTHING,
};

BPF_CALL_4(bpf_redirect_neigh, u32, ifindex, struct bpf_redir_neigh *, params,
	   int, plen, u64, flags)
{
	struct bpf_redirect_info *ri = bpf_net_ctx_get_ri();

	if (unlikely((plen && plen < sizeof(*params)) || flags))

Annotation

Implementation Notes