Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28264eb2 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Daniel Borkmann
Browse files

nfp: bpf: parse global BPF ABI version capability



Up until now we only had per-vNIC BPF ABI version capabilities,
which are slightly awkward to use because bulk of the resources
and configuration does not relate to any particular vNIC.  Add
a new capability for global ABI version and check the per-vNIC
version are equal to it.  Assume the ABI version 2 if no explicit
version capability is present.

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent cb86d0f8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum bpf_cap_tlv_type {
	NFP_BPF_CAP_TYPE_RANDOM		= 4,
	NFP_BPF_CAP_TYPE_QUEUE_SELECT	= 5,
	NFP_BPF_CAP_TYPE_ADJUST_TAIL	= 6,
	NFP_BPF_CAP_TYPE_ABI_VERSION	= 7,
};

struct nfp_bpf_cap_tlv_func {
+39 −4
Original line number Diff line number Diff line
@@ -54,11 +54,14 @@ const struct rhashtable_params nfp_bpf_maps_neutral_params = {
static bool nfp_net_ebpf_capable(struct nfp_net *nn)
{
#ifdef __LITTLE_ENDIAN
	if (nn->cap & NFP_NET_CFG_CTRL_BPF &&
	    nn_readb(nn, NFP_NET_CFG_BPF_ABI) == NFP_NET_BPF_ABI)
		return true;
#endif
	struct nfp_app_bpf *bpf = nn->app->priv;

	return nn->cap & NFP_NET_CFG_CTRL_BPF &&
	       bpf->abi_version &&
	       nn_readb(nn, NFP_NET_CFG_BPF_ABI) == bpf->abi_version;
#else
	return false;
#endif
}

static int
@@ -342,6 +345,26 @@ nfp_bpf_parse_cap_adjust_tail(struct nfp_app_bpf *bpf, void __iomem *value,
	return 0;
}

static int
nfp_bpf_parse_cap_abi_version(struct nfp_app_bpf *bpf, void __iomem *value,
			      u32 length)
{
	if (length < 4) {
		nfp_err(bpf->app->cpp, "truncated ABI version TLV: %d\n",
			length);
		return -EINVAL;
	}

	bpf->abi_version = readl(value);
	if (bpf->abi_version != 2) {
		nfp_warn(bpf->app->cpp, "unsupported BPF ABI version: %d\n",
			 bpf->abi_version);
		bpf->abi_version = 0;
	}

	return 0;
}

static int nfp_bpf_parse_capabilities(struct nfp_app *app)
{
	struct nfp_cpp *cpp = app->pf->cpp;
@@ -393,6 +416,11 @@ static int nfp_bpf_parse_capabilities(struct nfp_app *app)
							  length))
				goto err_release_free;
			break;
		case NFP_BPF_CAP_TYPE_ABI_VERSION:
			if (nfp_bpf_parse_cap_abi_version(app->priv, value,
							  length))
				goto err_release_free;
			break;
		default:
			nfp_dbg(cpp, "unknown BPF capability: %d\n", type);
			break;
@@ -414,6 +442,11 @@ static int nfp_bpf_parse_capabilities(struct nfp_app *app)
	return -EINVAL;
}

static void nfp_bpf_init_capabilities(struct nfp_app_bpf *bpf)
{
	bpf->abi_version = 2; /* Original BPF ABI version */
}

static int nfp_bpf_ndo_init(struct nfp_app *app, struct net_device *netdev)
{
	struct nfp_app_bpf *bpf = app->priv;
@@ -447,6 +480,8 @@ static int nfp_bpf_init(struct nfp_app *app)
	if (err)
		goto err_free_bpf;

	nfp_bpf_init_capabilities(bpf);

	err = nfp_bpf_parse_capabilities(app);
	if (err)
		goto err_free_neutral_maps;
+4 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@ enum pkt_vec {
 *
 * @maps_neutral:	hash table of offload-neutral maps (on pointer)
 *
 * @abi_version:	global BPF ABI version
 *
 * @adjust_head:	adjust head capability
 * @adjust_head.flags:		extra flags for adjust head
 * @adjust_head.off_min:	minimal packet offset within buffer required
@@ -170,6 +172,8 @@ struct nfp_app_bpf {

	struct rhashtable maps_neutral;

	u32 abi_version;

	struct nfp_bpf_cap_adjust_head {
		u32 flags;
		int off_min;