Commit a3fd7cee authored by Jakub Sitnicki's avatar Jakub Sitnicki Committed by Alexei Starovoitov
Browse files

net: Introduce netns_bpf for BPF programs attached to netns



In order to:

 (1) attach more than one BPF program type to netns, or
 (2) support attaching BPF programs to netns with bpf_link, or
 (3) support multi-prog attach points for netns

we will need to keep more state per netns than a single pointer like we
have now for BPF flow dissector program.

Prepare for the above by extracting netns_bpf that is part of struct net,
for storing all state related to BPF programs attached to netns.

Turn flow dissector callbacks for querying/attaching/detaching a program
into generic ones that operate on netns_bpf. Next patch will move the
generic callbacks into their own module.

This is similar to how it is organized for cgroup with cgroup_bpf.

Signed-off-by: default avatarJakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Cc: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/20200531082846.2117903-3-jakub@cloudflare.com
parent 171526f6
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BPF_NETNS_H
#define _BPF_NETNS_H

#include <linux/mutex.h>
#include <uapi/linux/bpf.h>

enum netns_bpf_attach_type {
	NETNS_BPF_INVALID = -1,
	NETNS_BPF_FLOW_DISSECTOR = 0,
	MAX_NETNS_BPF_ATTACH_TYPE
};

static inline enum netns_bpf_attach_type
to_netns_bpf_attach_type(enum bpf_attach_type attach_type)
{
	switch (attach_type) {
	case BPF_FLOW_DISSECTOR:
		return NETNS_BPF_FLOW_DISSECTOR;
	default:
		return NETNS_BPF_INVALID;
	}
}

/* Protects updates to netns_bpf */
extern struct mutex netns_bpf_mutex;

union bpf_attr;
struct bpf_prog;

#ifdef CONFIG_NET
int netns_bpf_prog_query(const union bpf_attr *attr,
			 union bpf_attr __user *uattr);
int netns_bpf_prog_attach(const union bpf_attr *attr,
			  struct bpf_prog *prog);
int netns_bpf_prog_detach(const union bpf_attr *attr);
#else
static inline int netns_bpf_prog_query(const union bpf_attr *attr,
				       union bpf_attr __user *uattr)
{
	return -EOPNOTSUPP;
}

static inline int netns_bpf_prog_attach(const union bpf_attr *attr,
					struct bpf_prog *prog)
{
	return -EOPNOTSUPP;
}

static inline int netns_bpf_prog_detach(const union bpf_attr *attr)
{
	return -EOPNOTSUPP;
}
#endif

#endif /* _BPF_NETNS_H */
+0 −26
Original line number Diff line number Diff line
@@ -1283,32 +1283,6 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
			     const struct flow_dissector_key *key,
			     unsigned int key_count);

#ifdef CONFIG_NET
int skb_flow_dissector_prog_query(const union bpf_attr *attr,
				  union bpf_attr __user *uattr);
int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
				       struct bpf_prog *prog);

int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr);
#else
static inline int skb_flow_dissector_prog_query(const union bpf_attr *attr,
						union bpf_attr __user *uattr)
{
	return -EOPNOTSUPP;
}

static inline int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
						     struct bpf_prog *prog)
{
	return -EOPNOTSUPP;
}

static inline int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
{
	return -EOPNOTSUPP;
}
#endif

struct bpf_flow_dissector;
bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
		      __be16 proto, int nhoff, int hlen, unsigned int flags);
+3 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <net/netns/mpls.h>
#include <net/netns/can.h>
#include <net/netns/xdp.h>
#include <net/netns/bpf.h>
#include <linux/ns_common.h>
#include <linux/idr.h>
#include <linux/skbuff.h>
@@ -162,7 +163,8 @@ struct net {
#endif
	struct net_generic __rcu	*gen;

	struct bpf_prog __rcu	*flow_dissector_prog;
	/* Used to store attached BPF programs */
	struct netns_bpf	bpf;

	/* Note : following structs are cache line aligned */
#ifdef CONFIG_XFRM
+17 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * BPF programs attached to network namespace
 */

#ifndef __NETNS_BPF_H__
#define __NETNS_BPF_H__

#include <linux/bpf-netns.h>

struct bpf_prog;

struct netns_bpf {
	struct bpf_prog __rcu *progs[MAX_NETNS_BPF_ATTACH_TYPE];
};

#endif /* __NETNS_BPF_H__ */
+4 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <uapi/linux/btf.h>
#include <linux/bpf_lsm.h>
#include <linux/poll.h>
#include <linux/bpf-netns.h>

#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
			  (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
@@ -2868,7 +2869,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
		ret = lirc_prog_attach(attr, prog);
		break;
	case BPF_PROG_TYPE_FLOW_DISSECTOR:
		ret = skb_flow_dissector_bpf_prog_attach(attr, prog);
		ret = netns_bpf_prog_attach(attr, prog);
		break;
	case BPF_PROG_TYPE_CGROUP_DEVICE:
	case BPF_PROG_TYPE_CGROUP_SKB:
@@ -2908,7 +2909,7 @@ static int bpf_prog_detach(const union bpf_attr *attr)
	case BPF_PROG_TYPE_FLOW_DISSECTOR:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		return skb_flow_dissector_bpf_prog_detach(attr);
		return netns_bpf_prog_detach(attr);
	case BPF_PROG_TYPE_CGROUP_DEVICE:
	case BPF_PROG_TYPE_CGROUP_SKB:
	case BPF_PROG_TYPE_CGROUP_SOCK:
@@ -2961,7 +2962,7 @@ static int bpf_prog_query(const union bpf_attr *attr,
	case BPF_LIRC_MODE2:
		return lirc_prog_query(attr, uattr);
	case BPF_FLOW_DISSECTOR:
		return skb_flow_dissector_prog_query(attr, uattr);
		return netns_bpf_prog_query(attr, uattr);
	default:
		return -EINVAL;
	}
Loading