netlink: policy: refactor per-attr policy writing
Refactor the per-attribute policy writing into a new helper function, to be used later for dumping out the policy of a rejected attribute. v2: - fix some indentation v3: - change variable order in netlink_policy_dump_write() Reviewed-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:

committed by
Jakub Kicinski

parent
c4cc0b9c77
commit
d2681e93b0
@@ -196,49 +196,33 @@ bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state)
|
|||||||
return !netlink_policy_dump_finished(state);
|
return !netlink_policy_dump_finished(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static int
|
||||||
* netlink_policy_dump_write - write current policy dump attributes
|
__netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state,
|
||||||
* @skb: the message skb to write to
|
struct sk_buff *skb,
|
||||||
* @state: the policy dump state
|
const struct nla_policy *pt,
|
||||||
*
|
int nestattr)
|
||||||
* Returns: 0 on success, an error code otherwise
|
|
||||||
*/
|
|
||||||
int netlink_policy_dump_write(struct sk_buff *skb,
|
|
||||||
struct netlink_policy_dump_state *state)
|
|
||||||
{
|
{
|
||||||
const struct nla_policy *pt;
|
|
||||||
struct nlattr *policy, *attr;
|
|
||||||
enum netlink_attribute_type type;
|
enum netlink_attribute_type type;
|
||||||
bool again;
|
struct nlattr *attr;
|
||||||
|
|
||||||
send_attribute:
|
attr = nla_nest_start(skb, nestattr);
|
||||||
again = false;
|
|
||||||
|
|
||||||
pt = &state->policies[state->policy_idx].policy[state->attr_idx];
|
|
||||||
|
|
||||||
policy = nla_nest_start(skb, state->policy_idx);
|
|
||||||
if (!policy)
|
|
||||||
return -ENOBUFS;
|
|
||||||
|
|
||||||
attr = nla_nest_start(skb, state->attr_idx);
|
|
||||||
if (!attr)
|
if (!attr)
|
||||||
goto nla_put_failure;
|
return -ENOBUFS;
|
||||||
|
|
||||||
switch (pt->type) {
|
switch (pt->type) {
|
||||||
default:
|
default:
|
||||||
case NLA_UNSPEC:
|
case NLA_UNSPEC:
|
||||||
case NLA_REJECT:
|
case NLA_REJECT:
|
||||||
/* skip - use NLA_MIN_LEN to advertise such */
|
/* skip - use NLA_MIN_LEN to advertise such */
|
||||||
nla_nest_cancel(skb, policy);
|
nla_nest_cancel(skb, attr);
|
||||||
again = true;
|
return -ENODATA;
|
||||||
goto next;
|
|
||||||
case NLA_NESTED:
|
case NLA_NESTED:
|
||||||
type = NL_ATTR_TYPE_NESTED;
|
type = NL_ATTR_TYPE_NESTED;
|
||||||
fallthrough;
|
fallthrough;
|
||||||
case NLA_NESTED_ARRAY:
|
case NLA_NESTED_ARRAY:
|
||||||
if (pt->type == NLA_NESTED_ARRAY)
|
if (pt->type == NLA_NESTED_ARRAY)
|
||||||
type = NL_ATTR_TYPE_NESTED_ARRAY;
|
type = NL_ATTR_TYPE_NESTED_ARRAY;
|
||||||
if (pt->nested_policy && pt->len &&
|
if (state && pt->nested_policy && pt->len &&
|
||||||
(nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX,
|
(nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX,
|
||||||
netlink_policy_dump_get_policy_idx(state,
|
netlink_policy_dump_get_policy_idx(state,
|
||||||
pt->nested_policy,
|
pt->nested_policy,
|
||||||
@@ -349,8 +333,47 @@ send_attribute:
|
|||||||
if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type))
|
if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
/* finish and move state to next attribute */
|
|
||||||
nla_nest_end(skb, attr);
|
nla_nest_end(skb, attr);
|
||||||
|
return 0;
|
||||||
|
nla_put_failure:
|
||||||
|
nla_nest_cancel(skb, attr);
|
||||||
|
return -ENOBUFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netlink_policy_dump_write - write current policy dump attributes
|
||||||
|
* @skb: the message skb to write to
|
||||||
|
* @state: the policy dump state
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, an error code otherwise
|
||||||
|
*/
|
||||||
|
int netlink_policy_dump_write(struct sk_buff *skb,
|
||||||
|
struct netlink_policy_dump_state *state)
|
||||||
|
{
|
||||||
|
const struct nla_policy *pt;
|
||||||
|
struct nlattr *policy;
|
||||||
|
bool again;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
send_attribute:
|
||||||
|
again = false;
|
||||||
|
|
||||||
|
pt = &state->policies[state->policy_idx].policy[state->attr_idx];
|
||||||
|
|
||||||
|
policy = nla_nest_start(skb, state->policy_idx);
|
||||||
|
if (!policy)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
err = __netlink_policy_dump_write_attr(state, skb, pt, state->attr_idx);
|
||||||
|
if (err == -ENODATA) {
|
||||||
|
nla_nest_cancel(skb, policy);
|
||||||
|
again = true;
|
||||||
|
goto next;
|
||||||
|
} else if (err) {
|
||||||
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finish and move state to next attribute */
|
||||||
nla_nest_end(skb, policy);
|
nla_nest_end(skb, policy);
|
||||||
|
|
||||||
next:
|
next:
|
||||||
|
Reference in New Issue
Block a user