mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-21 23:16:50 +08:00
We look up a netdev during prep of Netlink ops (pre- callbacks)
and take a ref to it. Then later in the body of the callback
we take its lock or RCU which are the actual protections.
The netdev may get unregistered in between the time we take
the ref and the time we lock it. We may allocate the hierarchy
after flush has already run, which would lead to a leak.
Take the instance lock in pre- already, this saves us from the race
and removes the need for dedicated lock/unlock callbacks completely.
After all, if there's any chance of write happening concurrently
with the flush - we're back to leaking the hierarchy.
We may take the lock for devices which don't support shapers but
we're only dealing with SET operations here, not taking the lock
would be optimizing for an error case.
Fixes: 93954b40f6 ("net-shapers: implement NL set and delete operations")
Link: https://lore.kernel.org/20260309173450.538026-1-p@1g4.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20260317161014.779569-2-kuba@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
51 lines
2.2 KiB
C
51 lines
2.2 KiB
C
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
|
|
/* Do not edit directly, auto-generated from: */
|
|
/* Documentation/netlink/specs/net_shaper.yaml */
|
|
/* YNL-GEN kernel header */
|
|
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
|
|
|
|
#ifndef _LINUX_NET_SHAPER_GEN_H
|
|
#define _LINUX_NET_SHAPER_GEN_H
|
|
|
|
#include <net/netlink.h>
|
|
#include <net/genetlink.h>
|
|
|
|
#include <uapi/linux/net_shaper.h>
|
|
|
|
/* Common nested types */
|
|
extern const struct nla_policy net_shaper_handle_nl_policy[NET_SHAPER_A_HANDLE_ID + 1];
|
|
extern const struct nla_policy net_shaper_leaf_info_nl_policy[NET_SHAPER_A_WEIGHT + 1];
|
|
|
|
int net_shaper_nl_pre_doit(const struct genl_split_ops *ops,
|
|
struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_pre_doit_write(const struct genl_split_ops *ops,
|
|
struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_cap_pre_doit(const struct genl_split_ops *ops,
|
|
struct sk_buff *skb, struct genl_info *info);
|
|
void
|
|
net_shaper_nl_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
|
|
struct genl_info *info);
|
|
void
|
|
net_shaper_nl_post_doit_write(const struct genl_split_ops *ops,
|
|
struct sk_buff *skb, struct genl_info *info);
|
|
void
|
|
net_shaper_nl_cap_post_doit(const struct genl_split_ops *ops,
|
|
struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_pre_dumpit(struct netlink_callback *cb);
|
|
int net_shaper_nl_cap_pre_dumpit(struct netlink_callback *cb);
|
|
int net_shaper_nl_post_dumpit(struct netlink_callback *cb);
|
|
int net_shaper_nl_cap_post_dumpit(struct netlink_callback *cb);
|
|
|
|
int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
|
int net_shaper_nl_set_doit(struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_delete_doit(struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_group_doit(struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_cap_get_doit(struct sk_buff *skb, struct genl_info *info);
|
|
int net_shaper_nl_cap_get_dumpit(struct sk_buff *skb,
|
|
struct netlink_callback *cb);
|
|
|
|
extern struct genl_family net_shaper_nl_family;
|
|
|
|
#endif /* _LINUX_NET_SHAPER_GEN_H */
|