From: John Fastabend <john.fastabend@gmail.com>
To: tgraf@suug.ch, sfeldma@gmail.com, jiri@resnulli.us,
jhs@mojatatu.com, simon.horman@netronome.com
Cc: netdev@vger.kernel.org, davem@davemloft.net, andy@greyhouse.net
Subject: Re: [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables
Date: Wed, 31 Dec 2014 12:10:01 -0800 [thread overview]
Message-ID: <54A45819.2090206@gmail.com> (raw)
In-Reply-To: <20141231194544.31070.30335.stgit@nitbit.x32>
On 12/31/2014 11:45 AM, John Fastabend wrote:
> Currently, we do not have an interface to query hardware and learn
> the capabilities of the device. This makes it very difficult to use
> hardware flow tables.
>
oops missed a few dev_put calls so at least need a new rev
for this. I'll wait a few days for feedback though.
[...]
> +
> +static int net_flow_cmd_get_actions(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct net_flow_action **a;
> + struct net_device *dev;
> + struct sk_buff *msg;
> +
> + dev = net_flow_get_dev(info);
> + if (!dev)
> + return -EINVAL;
> +
> + if (!dev->netdev_ops->ndo_flow_get_actions) {
> + dev_put(dev);
> + return -EOPNOTSUPP;
> + }
> +
> + a = dev->netdev_ops->ndo_flow_get_actions(dev);
> + if (!a)
missing dev_put(dev) here.
> + return -EBUSY;
> +
> + msg = net_flow_build_actions_msg(a, dev,
> + info->snd_portid,
> + info->snd_seq,
> + NET_FLOW_TABLE_CMD_GET_ACTIONS);
> + dev_put(dev);
> +
> + if (IS_ERR(msg))
> + return PTR_ERR(msg);
> +
> + return genlmsg_reply(msg, info);
> +}
> +
> +static int net_flow_put_table(struct net_device *dev,
> + struct sk_buff *skb,
> + struct net_flow_table *t)
> +{
> + struct nlattr *matches, *actions;
> + int i;
> +
> + if (nla_put_string(skb, NET_FLOW_TABLE_ATTR_NAME, t->name) ||
> + nla_put_u32(skb, NET_FLOW_TABLE_ATTR_UID, t->uid) ||
> + nla_put_u32(skb, NET_FLOW_TABLE_ATTR_SOURCE, t->source) ||
> + nla_put_u32(skb, NET_FLOW_TABLE_ATTR_SIZE, t->size))
> + return -EMSGSIZE;
> +
> + matches = nla_nest_start(skb, NET_FLOW_TABLE_ATTR_MATCHES);
> + if (!matches)
> + return -EMSGSIZE;
> +
> + for (i = 0; t->matches[i].instance; i++)
> + nla_put(skb, NET_FLOW_FIELD_REF,
> + sizeof(struct net_flow_field_ref),
> + &t->matches[i]);
need to check the return codes here.
> + nla_nest_end(skb, matches);
> +
> + actions = nla_nest_start(skb, NET_FLOW_TABLE_ATTR_ACTIONS);
> + if (!actions)
> + return -EMSGSIZE;
> +
> + for (i = 0; t->actions[i]; i++) {
> + if (nla_put_u32(skb,
> + NET_FLOW_ACTION_ATTR_UID,
> + t->actions[i])) {
> + nla_nest_cancel(skb, actions);
> + return -EMSGSIZE;
> + }
remembered to do the check here though ;)
> + }
> + nla_nest_end(skb, actions);
> +
> + return 0;
> +}
> +
[...]
> +
> +static struct sk_buff *net_flow_build_tables_msg(struct net_flow_table **t,
> + struct net_device *dev,
> + u32 portid, int seq, u8 cmd)
> +{
> + struct genlmsghdr *hdr;
> + struct sk_buff *skb;
> + int err = -ENOBUFS;
> +
> + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (!skb)
> + return ERR_PTR(-ENOBUFS);
> +
> + hdr = genlmsg_put(skb, portid, seq, &net_flow_nl_family, 0, cmd);
> + if (!hdr)
> + goto out;
> +
> + if (nla_put_u32(skb,
> + NET_FLOW_IDENTIFIER_TYPE,
> + NET_FLOW_IDENTIFIER_IFINDEX) ||
> + nla_put_u32(skb, NET_FLOW_IDENTIFIER, dev->ifindex)) {
> + err = -ENOBUFS;
> + goto out;
> + }
> +
> + err = net_flow_put_tables(dev, skb, t);
> + if (err < 0)
> + goto out;
> +
> + err = genlmsg_end(skb, hdr);
> + if (err < 0)
> + goto out;
> +
> + return skb;
> +out:
> + nlmsg_free(skb);
> + return ERR_PTR(err);
> +}
> +
> +static int net_flow_cmd_get_tables(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct net_flow_table **tables;
> + struct net_device *dev;
> + struct sk_buff *msg;
> +
> + dev = net_flow_get_dev(info);
> + if (!dev)
> + return -EINVAL;
> +
> + if (!dev->netdev_ops->ndo_flow_get_tables) {
> + dev_put(dev);
> + return -EOPNOTSUPP;
> + }
> +
> + tables = dev->netdev_ops->ndo_flow_get_tables(dev);
> + if (!tables) /* transient failure should always have some table */
need dev_put()
> + return -EBUSY;
> +
> + msg = net_flow_build_tables_msg(tables, dev,
> + info->snd_portid,
> + info->snd_seq,
> + NET_FLOW_TABLE_CMD_GET_TABLES);
> + dev_put(dev);
> +
> + if (IS_ERR(msg))
> + return PTR_ERR(msg);
> +
> + return genlmsg_reply(msg, info);
> +}
> +
[...]
> +
> +static int net_flow_put_headers(struct sk_buff *skb,
> + struct net_flow_header **headers)
> +{
> + struct nlattr *nest, *hdr, *fields;
> + struct net_flow_header *h;
> + int i, err;
> +
> + nest = nla_nest_start(skb, NET_FLOW_HEADERS);
> + if (!nest)
> + return -EMSGSIZE;
> +
> + for (i = 0; headers[i]->uid; i++) {
> + err = -EMSGSIZE;
> + h = headers[i];
> +
> + hdr = nla_nest_start(skb, NET_FLOW_HEADER);
> + if (!hdr)
> + goto hdr_put_failure;
> +
> + if (nla_put_string(skb, NET_FLOW_HEADER_ATTR_NAME, h->name) ||
> + nla_put_u32(skb, NET_FLOW_HEADER_ATTR_UID, h->uid))
> + goto attr_put_failure;
> +
> + fields = nla_nest_start(skb, NET_FLOW_HEADER_ATTR_FIELDS);
> + if (!fields)
> + goto attr_put_failure;
> +
> + err = net_flow_put_fields(skb, h);
> + if (err)
> + goto fields_put_failure;
> +
> + nla_nest_end(skb, fields);
> +
can remove this new line I think it doesn't add much.
> + nla_nest_end(skb, hdr);
> + }
> + nla_nest_end(skb, nest);
> +
> + return 0;
> +fields_put_failure:
> + nla_nest_cancel(skb, fields);
> +attr_put_failure:
> + nla_nest_cancel(skb, hdr);
> +hdr_put_failure:
> + nla_nest_cancel(skb, nest);
> + return err;
> +}
> +
[...]
> +
> +static int net_flow_cmd_get_headers(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct net_flow_header **h;
> + struct net_device *dev;
> + struct sk_buff *msg;
> +
> + dev = net_flow_get_dev(info);
> + if (!dev)
> + return -EINVAL;
> +
> + if (!dev->netdev_ops->ndo_flow_get_headers) {
> + dev_put(dev);
> + return -EOPNOTSUPP;
> + }
> +
> + h = dev->netdev_ops->ndo_flow_get_headers(dev);
> + if (!h)
dev_put again
> + return -EBUSY;
> +
> + msg = net_flow_build_headers_msg(h, dev,
> + info->snd_portid,
> + info->snd_seq,
> + NET_FLOW_TABLE_CMD_GET_HEADERS);
> + dev_put(dev);
> +
> + if (IS_ERR(msg))
> + return PTR_ERR(msg);
> +
> + return genlmsg_reply(msg, info);
> +}
> +
[...]
> +
> +static int net_flow_cmd_get_header_graph(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct net_flow_hdr_node **h;
> + struct net_device *dev;
> + struct sk_buff *msg;
> +
> + dev = net_flow_get_dev(info);
> + if (!dev)
> + return -EINVAL;
> +
> + if (!dev->netdev_ops->ndo_flow_get_hdr_graph) {
> + dev_put(dev);
> + return -EOPNOTSUPP;
> + }
> +
> + h = dev->netdev_ops->ndo_flow_get_hdr_graph(dev);
> + if (!h)
dev_put() seems I copy/pasted the same template for each cmd.
> + return -EBUSY;
> +
> + msg = net_flow_build_header_graph_msg(h, dev,
> + info->snd_portid,
> + info->snd_seq,
> + NET_FLOW_TABLE_CMD_GET_HDR_GRAPH);
> + dev_put(dev);
> +
> + if (IS_ERR(msg))
> + return PTR_ERR(msg);
> +
> + return genlmsg_reply(msg, info);
> +}
> +
[...]
> +
> +static int net_flow_cmd_get_table_graph(struct sk_buff *skb,
> + struct genl_info *info)
> +{
> + struct net_flow_tbl_node **g;
> + struct net_device *dev;
> + struct sk_buff *msg;
> +
> + dev = net_flow_get_dev(info);
> + if (!dev)
> + return -EINVAL;
> +
> + if (!dev->netdev_ops->ndo_flow_get_tbl_graph) {
> + dev_put(dev);
> + return -EOPNOTSUPP;
> + }
> +
> + g = dev->netdev_ops->ndo_flow_get_tbl_graph(dev);
> + if (!g)
dev_put
> + return -EBUSY;
> +
[...]
--
John Fastabend Intel Corporation
next prev parent reply other threads:[~2014-12-31 20:10 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-31 19:45 [net-next PATCH v1 00/11] A flow API John Fastabend
2014-12-31 19:45 ` [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables John Fastabend
2014-12-31 20:10 ` John Fastabend [this message]
2015-01-04 11:12 ` Thomas Graf
2015-01-05 18:59 ` John Fastabend
2015-01-05 21:48 ` Thomas Graf
2015-01-05 23:29 ` John Fastabend
2015-01-06 0:45 ` John Fastabend
2015-01-06 1:09 ` Simon Horman
2015-01-06 1:19 ` John Fastabend
2015-01-06 2:05 ` Simon Horman
2015-01-06 2:54 ` Simon Horman
2015-01-06 3:31 ` John Fastabend
2015-01-07 10:07 ` Or Gerlitz
2015-01-07 16:35 ` John Fastabend
2015-01-06 5:25 ` Scott Feldman
2015-01-06 6:04 ` John Fastabend
2015-01-06 6:40 ` Scott Feldman
2014-12-31 19:46 ` [net-next PATCH v1 02/11] net: flow_table: add flow, delete flow John Fastabend
2015-01-06 6:19 ` Scott Feldman
2015-01-08 17:39 ` Jiri Pirko
2015-01-09 6:21 ` John Fastabend
2014-12-31 19:46 ` [net-next PATCH v1 03/11] net: flow_table: add apply action argument to tables John Fastabend
2015-01-08 17:41 ` Jiri Pirko
2015-01-09 6:17 ` John Fastabend
2014-12-31 19:47 ` [net-next PATCH v1 04/11] rocker: add pipeline model for rocker switch John Fastabend
2015-01-04 8:43 ` Or Gerlitz
2015-01-05 5:18 ` John Fastabend
2015-01-06 7:01 ` Scott Feldman
2015-01-06 17:00 ` John Fastabend
2015-01-06 17:16 ` Scott Feldman
2015-01-06 17:49 ` John Fastabend
2014-12-31 19:47 ` [net-next PATCH v1 05/11] net: rocker: add set flow rules John Fastabend
2015-01-06 7:23 ` Scott Feldman
2015-01-06 15:31 ` John Fastabend
2014-12-31 19:48 ` [net-next PATCH v1 06/11] net: rocker: add group_id slices and drop explicit goto John Fastabend
2014-12-31 19:48 ` [net-next PATCH v1 07/11] net: rocker: add multicast path to bridging John Fastabend
2014-12-31 19:48 ` [net-next PATCH v1 08/11] net: rocker: add get flow API operation John Fastabend
[not found] ` <CAKoUArm4z_i6Su9Q4ODB1QYR_Z098MjT2yN=WR7LbN387AvPsg@mail.gmail.com>
2015-01-02 21:15 ` John Fastabend
2015-01-06 7:40 ` Scott Feldman
2015-01-06 14:59 ` John Fastabend
2015-01-06 16:57 ` Scott Feldman
2015-01-06 17:50 ` John Fastabend
2014-12-31 19:49 ` [net-next PATCH v1 09/11] net: rocker: add cookie to group acls and use flow_id to set cookie John Fastabend
2014-12-31 19:50 ` [net-next PATCH v1 10/11] net: rocker: have flow api calls set cookie value John Fastabend
2014-12-31 19:50 ` [net-next PATCH v1 11/11] net: rocker: implement delete flow routine John Fastabend
2015-01-04 8:30 ` [net-next PATCH v1 00/11] A flow API Or Gerlitz
2015-01-05 5:17 ` John Fastabend
2015-01-06 2:42 ` Scott Feldman
2015-01-06 12:23 ` Jamal Hadi Salim
2015-01-09 18:27 ` John Fastabend
2015-01-14 19:02 ` Thomas Graf
2015-01-08 15:14 ` Or Gerlitz
2015-01-09 17:26 ` John Fastabend
2015-01-08 18:03 ` Jiri Pirko
2015-01-09 18:10 ` John Fastabend
-- strict thread matches above, loose matches on Subject: below --
2015-01-07 1:14 [net-next PATCH v1 01/11] net: flow_table: create interface for hw match/action tables Alexei Starovoitov
2015-01-07 5:37 ` John Fastabend
2015-01-07 21:17 Alexei Starovoitov
2015-01-07 22:00 ` John Fastabend
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=54A45819.2090206@gmail.com \
--to=john.fastabend@gmail.com \
--cc=andy@greyhouse.net \
--cc=davem@davemloft.net \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=netdev@vger.kernel.org \
--cc=sfeldma@gmail.com \
--cc=simon.horman@netronome.com \
--cc=tgraf@suug.ch \
/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.