Commit a207eab1 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

net: nexthop: Add NHA_OP_FLAGS

In order to add per-nexthop statistics, but still not increase netlink
message size for consumers that do not care about them, there needs to be a
toggle through which the user indicates their desire to get the statistics.
To that end, add a new attribute, NHA_OP_FLAGS. The idea is to be able to
use the attribute for carrying of arbitrary operation-specific flags, i.e.
not make it specific for get / dump.

Add the new attribute to get and dump policies, but do not actually allow
any flags yet -- those will come later as the flags themselves are defined.
Add the necessary parsing code.
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2118f939
...@@ -60,6 +60,9 @@ enum { ...@@ -60,6 +60,9 @@ enum {
/* nested; nexthop bucket attributes */ /* nested; nexthop bucket attributes */
NHA_RES_BUCKET, NHA_RES_BUCKET,
/* u32; operation-specific flags */
NHA_OP_FLAGS,
__NHA_MAX, __NHA_MAX,
}; };
......
...@@ -41,6 +41,7 @@ static const struct nla_policy rtm_nh_policy_new[] = { ...@@ -41,6 +41,7 @@ static const struct nla_policy rtm_nh_policy_new[] = {
static const struct nla_policy rtm_nh_policy_get[] = { static const struct nla_policy rtm_nh_policy_get[] = {
[NHA_ID] = { .type = NLA_U32 }, [NHA_ID] = { .type = NLA_U32 },
[NHA_OP_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0),
}; };
static const struct nla_policy rtm_nh_policy_del[] = { static const struct nla_policy rtm_nh_policy_del[] = {
...@@ -52,6 +53,7 @@ static const struct nla_policy rtm_nh_policy_dump[] = { ...@@ -52,6 +53,7 @@ static const struct nla_policy rtm_nh_policy_dump[] = {
[NHA_GROUPS] = { .type = NLA_FLAG }, [NHA_GROUPS] = { .type = NLA_FLAG },
[NHA_MASTER] = { .type = NLA_U32 }, [NHA_MASTER] = { .type = NLA_U32 },
[NHA_FDB] = { .type = NLA_FLAG }, [NHA_FDB] = { .type = NLA_FLAG },
[NHA_OP_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0),
}; };
static const struct nla_policy rtm_nh_res_policy_new[] = { static const struct nla_policy rtm_nh_res_policy_new[] = {
...@@ -2971,7 +2973,7 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -2971,7 +2973,7 @@ static int rtm_new_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
} }
static int nh_valid_get_del_req(const struct nlmsghdr *nlh, static int nh_valid_get_del_req(const struct nlmsghdr *nlh,
struct nlattr **tb, u32 *id, struct nlattr **tb, u32 *id, u32 *op_flags,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nhmsg *nhm = nlmsg_data(nlh); struct nhmsg *nhm = nlmsg_data(nlh);
...@@ -2992,6 +2994,11 @@ static int nh_valid_get_del_req(const struct nlmsghdr *nlh, ...@@ -2992,6 +2994,11 @@ static int nh_valid_get_del_req(const struct nlmsghdr *nlh,
return -EINVAL; return -EINVAL;
} }
if (tb[NHA_OP_FLAGS])
*op_flags = nla_get_u32(tb[NHA_OP_FLAGS]);
else
*op_flags = 0;
return 0; return 0;
} }
...@@ -3007,6 +3014,7 @@ static int rtm_del_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -3007,6 +3014,7 @@ static int rtm_del_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
.portid = NETLINK_CB(skb).portid, .portid = NETLINK_CB(skb).portid,
}; };
struct nexthop *nh; struct nexthop *nh;
u32 op_flags;
int err; int err;
u32 id; u32 id;
...@@ -3015,7 +3023,7 @@ static int rtm_del_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -3015,7 +3023,7 @@ static int rtm_del_nexthop(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err < 0) if (err < 0)
return err; return err;
err = nh_valid_get_del_req(nlh, tb, &id, extack); err = nh_valid_get_del_req(nlh, tb, &id, &op_flags, extack);
if (err) if (err)
return err; return err;
...@@ -3036,6 +3044,7 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -3036,6 +3044,7 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct nlattr *tb[NHA_MAX + 1]; struct nlattr *tb[NHA_MAX + 1];
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct nexthop *nh; struct nexthop *nh;
u32 op_flags;
int err; int err;
u32 id; u32 id;
...@@ -3044,7 +3053,7 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -3044,7 +3053,7 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (err < 0) if (err < 0)
return err; return err;
err = nh_valid_get_del_req(nlh, tb, &id, extack); err = nh_valid_get_del_req(nlh, tb, &id, &op_flags, extack);
if (err) if (err)
return err; return err;
...@@ -3080,6 +3089,7 @@ struct nh_dump_filter { ...@@ -3080,6 +3089,7 @@ struct nh_dump_filter {
bool group_filter; bool group_filter;
bool fdb_filter; bool fdb_filter;
u32 res_bucket_nh_id; u32 res_bucket_nh_id;
u32 op_flags;
}; };
static bool nh_dump_filtered(struct nexthop *nh, static bool nh_dump_filtered(struct nexthop *nh,
...@@ -3151,6 +3161,11 @@ static int __nh_valid_dump_req(const struct nlmsghdr *nlh, struct nlattr **tb, ...@@ -3151,6 +3161,11 @@ static int __nh_valid_dump_req(const struct nlmsghdr *nlh, struct nlattr **tb,
return -EINVAL; return -EINVAL;
} }
if (tb[NHA_OP_FLAGS])
filter->op_flags = nla_get_u32(tb[NHA_OP_FLAGS]);
else
filter->op_flags = 0;
return 0; return 0;
} }
...@@ -3474,6 +3489,7 @@ static int nh_valid_get_bucket_req(const struct nlmsghdr *nlh, ...@@ -3474,6 +3489,7 @@ static int nh_valid_get_bucket_req(const struct nlmsghdr *nlh,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nlattr *tb[NHA_MAX + 1]; struct nlattr *tb[NHA_MAX + 1];
u32 op_flags;
int err; int err;
err = nlmsg_parse(nlh, sizeof(struct nhmsg), tb, NHA_MAX, err = nlmsg_parse(nlh, sizeof(struct nhmsg), tb, NHA_MAX,
...@@ -3481,7 +3497,7 @@ static int nh_valid_get_bucket_req(const struct nlmsghdr *nlh, ...@@ -3481,7 +3497,7 @@ static int nh_valid_get_bucket_req(const struct nlmsghdr *nlh,
if (err < 0) if (err < 0)
return err; return err;
err = nh_valid_get_del_req(nlh, tb, id, extack); err = nh_valid_get_del_req(nlh, tb, id, &op_flags, extack);
if (err) if (err)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment