Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Johannes Berg and committed by
Jakub Kicinski
d2681e93 c4cc0b9c

+51 -28
+51 -28
net/netlink/policy.c
··· 196 196 return !netlink_policy_dump_finished(state); 197 197 } 198 198 199 - /** 200 - * netlink_policy_dump_write - write current policy dump attributes 201 - * @skb: the message skb to write to 202 - * @state: the policy dump state 203 - * 204 - * Returns: 0 on success, an error code otherwise 205 - */ 206 - int netlink_policy_dump_write(struct sk_buff *skb, 207 - struct netlink_policy_dump_state *state) 199 + static int 200 + __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state, 201 + struct sk_buff *skb, 202 + const struct nla_policy *pt, 203 + int nestattr) 208 204 { 209 - const struct nla_policy *pt; 210 - struct nlattr *policy, *attr; 211 205 enum netlink_attribute_type type; 212 - bool again; 206 + struct nlattr *attr; 213 207 214 - send_attribute: 215 - again = false; 216 - 217 - pt = &state->policies[state->policy_idx].policy[state->attr_idx]; 218 - 219 - policy = nla_nest_start(skb, state->policy_idx); 220 - if (!policy) 221 - return -ENOBUFS; 222 - 223 - attr = nla_nest_start(skb, state->attr_idx); 208 + attr = nla_nest_start(skb, nestattr); 224 209 if (!attr) 225 - goto nla_put_failure; 210 + return -ENOBUFS; 226 211 227 212 switch (pt->type) { 228 213 default: 229 214 case NLA_UNSPEC: 230 215 case NLA_REJECT: 231 216 /* skip - use NLA_MIN_LEN to advertise such */ 232 - nla_nest_cancel(skb, policy); 233 - again = true; 234 - goto next; 217 + nla_nest_cancel(skb, attr); 218 + return -ENODATA; 235 219 case NLA_NESTED: 236 220 type = NL_ATTR_TYPE_NESTED; 237 221 fallthrough; 238 222 case NLA_NESTED_ARRAY: 239 223 if (pt->type == NLA_NESTED_ARRAY) 240 224 type = NL_ATTR_TYPE_NESTED_ARRAY; 241 - if (pt->nested_policy && pt->len && 225 + if (state && pt->nested_policy && pt->len && 242 226 (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX, 243 227 netlink_policy_dump_get_policy_idx(state, 244 228 pt->nested_policy, ··· 333 349 if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type)) 334 350 goto nla_put_failure; 335 351 336 - /* finish and move state to next attribute */ 337 352 nla_nest_end(skb, attr); 353 + return 0; 354 + nla_put_failure: 355 + nla_nest_cancel(skb, attr); 356 + return -ENOBUFS; 357 + } 358 + 359 + /** 360 + * netlink_policy_dump_write - write current policy dump attributes 361 + * @skb: the message skb to write to 362 + * @state: the policy dump state 363 + * 364 + * Returns: 0 on success, an error code otherwise 365 + */ 366 + int netlink_policy_dump_write(struct sk_buff *skb, 367 + struct netlink_policy_dump_state *state) 368 + { 369 + const struct nla_policy *pt; 370 + struct nlattr *policy; 371 + bool again; 372 + int err; 373 + 374 + send_attribute: 375 + again = false; 376 + 377 + pt = &state->policies[state->policy_idx].policy[state->attr_idx]; 378 + 379 + policy = nla_nest_start(skb, state->policy_idx); 380 + if (!policy) 381 + return -ENOBUFS; 382 + 383 + err = __netlink_policy_dump_write_attr(state, skb, pt, state->attr_idx); 384 + if (err == -ENODATA) { 385 + nla_nest_cancel(skb, policy); 386 + again = true; 387 + goto next; 388 + } else if (err) { 389 + goto nla_put_failure; 390 + } 391 + 392 + /* finish and move state to next attribute */ 338 393 nla_nest_end(skb, policy); 339 394 340 395 next: