All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Justin Iurman <justin.iurman@uliege.be>
Cc: netdev@vger.kernel.org, davem@davemloft.net, tom@herbertland.com
Subject: Re: [PATCH net-next v4 3/5] ipv6: ioam: IOAM Generic Netlink API
Date: Sat, 29 May 2021 14:06:01 -0700	[thread overview]
Message-ID: <20210529140601.1ab9d40e@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net> (raw)
In-Reply-To: <20210527151652.16074-4-justin.iurman@uliege.be>

On Thu, 27 May 2021 17:16:50 +0200 Justin Iurman wrote:
> Add Generic Netlink commands to allow userspace to configure IOAM
> namespaces and schemas. The target is iproute2 and the patch is ready.
> It will be posted as soon as this patchset is merged. Here is an overview:
> 
> $ ip ioam
> Usage:	ip ioam { COMMAND | help }
> 	ip ioam namespace show
> 	ip ioam namespace add ID [ DATA ]
> 	ip ioam namespace del ID
> 	ip ioam schema show
> 	ip ioam schema add ID DATA
> 	ip ioam schema del ID
> 	ip ioam namespace set ID schema { ID | none }
> 
> Signed-off-by: Justin Iurman <justin.iurman@uliege.be>

> +static int ioam6_genl_addns(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct ioam6_pernet_data *nsdata;
> +	struct ioam6_namespace *ns;
> +	__be16 ns_id;
> +	int err;
> +
> +	if (!info->attrs[IOAM6_ATTR_NS_ID])
> +		return -EINVAL;
> +
> +	ns_id = cpu_to_be16(nla_get_u16(info->attrs[IOAM6_ATTR_NS_ID]));
> +	nsdata = ioam6_pernet(genl_info_net(info));
> +
> +	mutex_lock(&nsdata->lock);
> +
> +	ns = rhashtable_lookup_fast(&nsdata->namespaces, &ns_id, rht_ns_params);
> +	if (ns) {
> +		err = -EEXIST;
> +		goto out_unlock;
> +	}
> +
> +	ns = kzalloc(sizeof(*ns), GFP_KERNEL);
> +	if (!ns) {
> +		err = -ENOMEM;
> +		goto out_unlock;
> +	}
> +
> +	ns->id = ns_id;
> +
> +	if (!info->attrs[IOAM6_ATTR_NS_DATA]) {
> +		ns->data = cpu_to_be64(IOAM6_EMPTY_u64);
> +	} else {
> +		ns->data = cpu_to_be64(
> +				nla_get_u64(info->attrs[IOAM6_ATTR_NS_DATA]));

Store data in a temporary variable to avoid this long line.

> +	}

braces unnecessary

> +	err = rhashtable_lookup_insert_fast(&nsdata->namespaces, &ns->head,
> +					    rht_ns_params);
> +	if (err)
> +		kfree(ns);
> +
> +out_unlock:
> +	mutex_unlock(&nsdata->lock);
> +	return err;
> +}
> +
> +static int ioam6_genl_delns(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct ioam6_pernet_data *nsdata;
> +	struct ioam6_namespace *ns;
> +	struct ioam6_schema *sc;
> +	__be16 ns_id;
> +	int err;
> +
> +	if (!info->attrs[IOAM6_ATTR_NS_ID])
> +		return -EINVAL;
> +
> +	ns_id = cpu_to_be16(nla_get_u16(info->attrs[IOAM6_ATTR_NS_ID]));
> +	nsdata = ioam6_pernet(genl_info_net(info));
> +
> +	mutex_lock(&nsdata->lock);
> +
> +	ns = rhashtable_lookup_fast(&nsdata->namespaces, &ns_id, rht_ns_params);
> +	if (!ns) {
> +		err = -ENOENT;
> +		goto out_unlock;
> +	}
> +
> +	sc = ns->schema;
> +	err = rhashtable_remove_fast(&nsdata->namespaces, &ns->head,
> +				     rht_ns_params);
> +	if (err)
> +		goto out_unlock;
> +
> +	if (sc)
> +		sc->ns = NULL;

the sc <> ns pointers should be annotated with __rcu, and appropriate
accessors used. At the very least the need READ/WRITE_ONCE().

> +	ioam6_ns_release(ns);
> +
> +out_unlock:
> +	mutex_unlock(&nsdata->lock);
> +	return err;
> +}
> +
> +static int ioam6_genl_addsc(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct ioam6_pernet_data *nsdata;
> +	int len, len_aligned, err;
> +	struct ioam6_schema *sc;
> +	u32 sc_id;
> +
> +	if (!info->attrs[IOAM6_ATTR_SC_ID] || !info->attrs[IOAM6_ATTR_SC_DATA])
> +		return -EINVAL;
> +
> +	sc_id = nla_get_u32(info->attrs[IOAM6_ATTR_SC_ID]);
> +	nsdata = ioam6_pernet(genl_info_net(info));
> +
> +	mutex_lock(&nsdata->lock);
> +
> +	sc = rhashtable_lookup_fast(&nsdata->schemas, &sc_id, rht_sc_params);
> +	if (sc) {
> +		err = -EEXIST;
> +		goto out_unlock;
> +	}
> +
> +	sc = kzalloc(sizeof(*sc), GFP_KERNEL);
> +	if (!sc) {
> +		err = -ENOMEM;
> +		goto out_unlock;
> +	}

Why not store the data after the sc structure?

u8 data[] + struct_size()?

> +	len = nla_len(info->attrs[IOAM6_ATTR_SC_DATA]);
> +	len_aligned = ALIGN(len, 4);
> +
> +	sc->data = kzalloc(len_aligned, GFP_KERNEL);
> +	if (!sc->data) {
> +		err = -ENOMEM;
> +		goto free_sc;
> +	}
> +
> +	sc->id = sc_id;
> +	sc->len = len_aligned;
> +	sc->hdr = cpu_to_be32(sc->id | ((u8)(sc->len / 4) << 24));
> +
> +	nla_memcpy(sc->data, info->attrs[IOAM6_ATTR_SC_DATA], len);
> +
> +	err = rhashtable_lookup_insert_fast(&nsdata->schemas, &sc->head,
> +					    rht_sc_params);
> +	if (err)
> +		goto free_data;
> +
> +out_unlock:
> +	mutex_unlock(&nsdata->lock);
> +	return err;
> +free_data:
> +	kfree(sc->data);
> +free_sc:
> +	kfree(sc);
> +	goto out_unlock;
> +}
> +
> +static int ioam6_genl_ns_set_schema(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct ioam6_pernet_data *nsdata;
> +	struct ioam6_namespace *ns;
> +	struct ioam6_schema *sc;
> +	__be16 ns_id;
> +	int err = 0;

No need to init.

> +	u32 sc_id;
> +
> +	if (!info->attrs[IOAM6_ATTR_NS_ID] ||
> +	    (!info->attrs[IOAM6_ATTR_SC_ID] &&
> +	     !info->attrs[IOAM6_ATTR_SC_NONE]))
> +		return -EINVAL;
> +
> +	ns_id = cpu_to_be16(nla_get_u16(info->attrs[IOAM6_ATTR_NS_ID]));
> +	nsdata = ioam6_pernet(genl_info_net(info));
> +
> +	mutex_lock(&nsdata->lock);
> +
> +	ns = rhashtable_lookup_fast(&nsdata->namespaces, &ns_id, rht_ns_params);
> +	if (!ns) {
> +		err = -ENOENT;
> +		goto out_unlock;
> +	}
> +
> +	if (info->attrs[IOAM6_ATTR_SC_NONE]) {
> +		sc = NULL;
> +	} else {
> +		sc_id = nla_get_u32(info->attrs[IOAM6_ATTR_SC_ID]);
> +		sc = rhashtable_lookup_fast(&nsdata->schemas, &sc_id,
> +					    rht_sc_params);
> +		if (!sc) {
> +			err = -ENOENT;
> +			goto out_unlock;
> +		}
> +	}
> +
> +	if (ns->schema)
> +		ns->schema->ns = NULL;
> +	ns->schema = sc;
> +
> +	if (sc) {
> +		if (sc->ns)
> +			sc->ns->schema = NULL;
> +		sc->ns = ns;
> +	}
> +
> +out_unlock:
> +	mutex_unlock(&nsdata->lock);
> +	return err;
> +}
> +
> +static const struct genl_ops ioam6_genl_ops[] = {
> +	{
> +		.cmd	= IOAM6_CMD_ADD_NAMESPACE,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.doit	= ioam6_genl_addns,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_DEL_NAMESPACE,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.doit	= ioam6_genl_delns,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_DUMP_NAMESPACES,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.start	= ioam6_genl_dumpns_start,
> +		.dumpit	= ioam6_genl_dumpns,
> +		.done	= ioam6_genl_dumpns_done,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_ADD_SCHEMA,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.doit	= ioam6_genl_addsc,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_DEL_SCHEMA,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.doit	= ioam6_genl_delsc,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_DUMP_SCHEMAS,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.start	= ioam6_genl_dumpsc_start,
> +		.dumpit	= ioam6_genl_dumpsc,
> +		.done	= ioam6_genl_dumpsc_done,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +	{
> +		.cmd	= IOAM6_CMD_NS_SET_SCHEMA,
> +		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
> +		.doit	= ioam6_genl_ns_set_schema,
> +		.flags	= GENL_ADMIN_PERM,
> +	},
> +};

These days I think we should use policy tailored to each op, rather
than a single policy per family. That way we don't ignore any
attributes user may specify but kernel doesn't expect.

  reply	other threads:[~2021-05-29 21:06 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-27 15:16 [PATCH net-next v4 0/5] Support for the IOAM Pre-allocated Trace with IPv6 Justin Iurman
2021-05-27 15:16 ` [PATCH net-next v4 1/5] uapi: IPv6 IOAM headers definition Justin Iurman
2021-05-27 15:16 ` [PATCH net-next v4 2/5] ipv6: ioam: Data plane support for Pre-allocated Trace Justin Iurman
2021-05-29 21:05   ` Jakub Kicinski
2021-05-30 10:36     ` Justin Iurman
2021-05-30 14:50       ` Justin Iurman
2021-05-30 20:05         ` Jakub Kicinski
2021-05-31 11:50           ` Justin Iurman
2021-06-01  4:20             ` Jakub Kicinski
2021-05-30 20:02       ` Jakub Kicinski
2021-05-31 11:43         ` Justin Iurman
2021-06-01  4:21           ` Jakub Kicinski
2021-05-27 15:16 ` [PATCH net-next v4 3/5] ipv6: ioam: IOAM Generic Netlink API Justin Iurman
2021-05-29 21:06   ` Jakub Kicinski [this message]
2021-05-30 11:18     ` Justin Iurman
2021-05-30 20:13       ` Jakub Kicinski
2021-05-27 15:16 ` [PATCH net-next v4 4/5] ipv6: ioam: Support for IOAM injection with lwtunnels Justin Iurman
2021-05-29 21:06   ` Jakub Kicinski
2021-05-30 10:48     ` Justin Iurman
2021-05-27 15:16 ` [PATCH net-next v4 5/5] ipv6: ioam: Documentation for new IOAM sysctls Justin Iurman
2021-05-29 15:58 ` [PATCH net-next v4 0/5] Support for the IOAM Pre-allocated Trace with IPv6 David Ahern
2021-05-29 16:24   ` Justin Iurman
2021-05-31  1:24     ` David Ahern
2021-05-31 12:04       ` Justin Iurman
2021-06-03  3:31         ` David Ahern
2021-05-29 21:10 ` Jakub Kicinski
2021-05-30 10:49   ` Justin Iurman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210529140601.1ab9d40e@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net \
    --to=kuba@kernel.org \
    --cc=davem@davemloft.net \
    --cc=justin.iurman@uliege.be \
    --cc=netdev@vger.kernel.org \
    --cc=tom@herbertland.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.