mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-11 08:38:04 +07:00
[NET] rules: Unified rules dumping
Implements a unified, protocol independant rules dumping function which is capable of both, dumping a specific protocol family or all of them. This speeds up dumping as less lookups are required. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
687ad8cc64
commit
c454673da7
@ -98,7 +98,4 @@ extern int fib_rules_unregister(struct fib_rules_ops *);
|
|||||||
extern int fib_rules_lookup(struct fib_rules_ops *,
|
extern int fib_rules_lookup(struct fib_rules_ops *,
|
||||||
struct flowi *, int flags,
|
struct flowi *, int flags,
|
||||||
struct fib_lookup_arg *);
|
struct fib_lookup_arg *);
|
||||||
|
|
||||||
extern int fib_rules_dump(struct sk_buff *,
|
|
||||||
struct netlink_callback *, int);
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,4 +15,12 @@ extern int rtnl_unregister(int protocol, int msgtype);
|
|||||||
extern void rtnl_unregister_all(int protocol);
|
extern void rtnl_unregister_all(int protocol);
|
||||||
extern int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb);
|
extern int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb);
|
||||||
|
|
||||||
|
static inline int rtnl_msg_family(struct nlmsghdr *nlh)
|
||||||
|
{
|
||||||
|
if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))
|
||||||
|
return ((struct rtgenmsg *) nlmsg_data(nlh))->rtgen_family;
|
||||||
|
else
|
||||||
|
return AF_UNSPEC;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -393,19 +393,15 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
|
|||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
|
static int dump_rules(struct sk_buff *skb, struct netlink_callback *cb,
|
||||||
|
struct fib_rules_ops *ops)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
struct fib_rule *rule;
|
struct fib_rule *rule;
|
||||||
struct fib_rules_ops *ops;
|
|
||||||
|
|
||||||
ops = lookup_rules_ops(family);
|
|
||||||
if (ops == NULL)
|
|
||||||
return -EAFNOSUPPORT;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(rule, ops->rules_list, list) {
|
list_for_each_entry_rcu(rule, ops->rules_list, list) {
|
||||||
if (idx < cb->args[0])
|
if (idx < cb->args[1])
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
|
if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
|
||||||
@ -416,13 +412,44 @@ int fib_rules_dump(struct sk_buff *skb, struct netlink_callback *cb, int family)
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
cb->args[0] = idx;
|
cb->args[1] = idx;
|
||||||
rules_ops_put(ops);
|
rules_ops_put(ops);
|
||||||
|
|
||||||
return skb->len;
|
return skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(fib_rules_dump);
|
static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct fib_rules_ops *ops;
|
||||||
|
int idx = 0, family;
|
||||||
|
|
||||||
|
family = rtnl_msg_family(cb->nlh);
|
||||||
|
if (family != AF_UNSPEC) {
|
||||||
|
/* Protocol specific dump request */
|
||||||
|
ops = lookup_rules_ops(family);
|
||||||
|
if (ops == NULL)
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
|
||||||
|
return dump_rules(skb, cb, ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
list_for_each_entry_rcu(ops, &rules_ops, list) {
|
||||||
|
if (idx < cb->args[0] || !try_module_get(ops->owner))
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
if (dump_rules(skb, cb, ops) < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cb->args[1] = 0;
|
||||||
|
skip:
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
cb->args[0] = idx;
|
||||||
|
|
||||||
|
return skb->len;
|
||||||
|
}
|
||||||
|
|
||||||
static void notify_rule_change(int event, struct fib_rule *rule,
|
static void notify_rule_change(int event, struct fib_rule *rule,
|
||||||
struct fib_rules_ops *ops, struct nlmsghdr *nlh,
|
struct fib_rules_ops *ops, struct nlmsghdr *nlh,
|
||||||
@ -503,7 +530,7 @@ static int __init fib_rules_init(void)
|
|||||||
{
|
{
|
||||||
rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
|
rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
|
||||||
rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
|
rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
|
||||||
rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, rtnl_dump_all);
|
rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
|
||||||
|
|
||||||
return register_netdevice_notifier(&fib_rules_notifier);
|
return register_netdevice_notifier(&fib_rules_notifier);
|
||||||
}
|
}
|
||||||
|
@ -239,11 +239,6 @@ static u32 dn_fib_rule_default_pref(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
|
|
||||||
{
|
|
||||||
return fib_rules_dump(skb, cb, AF_DECnet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct fib_rules_ops dn_fib_rules_ops = {
|
static struct fib_rules_ops dn_fib_rules_ops = {
|
||||||
.family = AF_DECnet,
|
.family = AF_DECnet,
|
||||||
.rule_size = sizeof(struct dn_fib_rule),
|
.rule_size = sizeof(struct dn_fib_rule),
|
||||||
@ -264,12 +259,10 @@ void __init dn_fib_rules_init(void)
|
|||||||
{
|
{
|
||||||
list_add_tail(&default_rule.common.list, &dn_fib_rules);
|
list_add_tail(&default_rule.common.list, &dn_fib_rules);
|
||||||
fib_rules_register(&dn_fib_rules_ops);
|
fib_rules_register(&dn_fib_rules_ops);
|
||||||
rtnl_register(PF_DECnet, RTM_GETRULE, NULL, dn_fib_dump_rules);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __exit dn_fib_rules_cleanup(void)
|
void __exit dn_fib_rules_cleanup(void)
|
||||||
{
|
{
|
||||||
rtnl_unregister(PF_DECnet, RTM_GETRULE);
|
|
||||||
fib_rules_unregister(&dn_fib_rules_ops);
|
fib_rules_unregister(&dn_fib_rules_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,11 +274,6 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
|
|||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fib4_rule_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|
||||||
{
|
|
||||||
return fib_rules_dump(skb, cb, AF_INET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 fib4_rule_default_pref(void)
|
static u32 fib4_rule_default_pref(void)
|
||||||
{
|
{
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
@ -327,6 +322,4 @@ void __init fib4_rules_init(void)
|
|||||||
list_add_tail(&default_rule.common.list, &fib4_rules);
|
list_add_tail(&default_rule.common.list, &fib4_rules);
|
||||||
|
|
||||||
fib_rules_register(&fib4_rules_ops);
|
fib_rules_register(&fib4_rules_ops);
|
||||||
|
|
||||||
rtnl_register(PF_INET, RTM_GETRULE, NULL, fib4_rule_dump);
|
|
||||||
}
|
}
|
||||||
|
@ -216,11 +216,6 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
|
|||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fib6_rules_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|
||||||
{
|
|
||||||
return fib_rules_dump(skb, cb, AF_INET6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 fib6_rule_default_pref(void)
|
static u32 fib6_rule_default_pref(void)
|
||||||
{
|
{
|
||||||
return 0x3FFF;
|
return 0x3FFF;
|
||||||
@ -255,11 +250,9 @@ void __init fib6_rules_init(void)
|
|||||||
list_add_tail(&main_rule.common.list, &fib6_rules);
|
list_add_tail(&main_rule.common.list, &fib6_rules);
|
||||||
|
|
||||||
fib_rules_register(&fib6_rules_ops);
|
fib_rules_register(&fib6_rules_ops);
|
||||||
__rtnl_register(PF_INET6, RTM_GETRULE, NULL, fib6_rules_dump);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fib6_rules_cleanup(void)
|
void fib6_rules_cleanup(void)
|
||||||
{
|
{
|
||||||
rtnl_unregister(PF_INET6, RTM_GETRULE);
|
|
||||||
fib_rules_unregister(&fib6_rules_ops);
|
fib_rules_unregister(&fib6_rules_ops);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user