Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c454673d authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller
Browse files

[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: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 687ad8cc
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -98,7 +98,4 @@ extern int fib_rules_unregister(struct fib_rules_ops *);
extern int			fib_rules_lookup(struct fib_rules_ops *,
						 struct flowi *, int flags,
						 struct fib_lookup_arg *);

extern int			fib_rules_dump(struct sk_buff *,
					       struct netlink_callback *, int);
#endif
+8 −0
Original line number Diff line number Diff line
@@ -15,4 +15,12 @@ extern int rtnl_unregister(int protocol, int msgtype);
extern void	rtnl_unregister_all(int protocol);
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
+37 −10
Original line number Diff line number Diff line
@@ -393,19 +393,15 @@ nla_put_failure:
	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;
	struct fib_rule *rule;
	struct fib_rules_ops *ops;

	ops = lookup_rules_ops(family);
	if (ops == NULL)
		return -EAFNOSUPPORT;

	rcu_read_lock();
	list_for_each_entry_rcu(rule, ops->rules_list, list) {
		if (idx < cb->args[0])
		if (idx < cb->args[1])
			goto skip;

		if (fib_nl_fill_rule(skb, rule, NETLINK_CB(cb->skb).pid,
@@ -416,13 +412,44 @@ skip:
		idx++;
	}
	rcu_read_unlock();
	cb->args[0] = idx;
	cb->args[1] = idx;
	rules_ops_put(ops);

	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,
			       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_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);
}
+0 −7
Original line number Diff line number Diff line
@@ -239,11 +239,6 @@ static u32 dn_fib_rule_default_pref(void)
	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 = {
	.family		= AF_DECnet,
	.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);
	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)
{
	rtnl_unregister(PF_DECnet, RTM_GETRULE);
	fib_rules_unregister(&dn_fib_rules_ops);
}

+0 −7
Original line number Diff line number Diff line
@@ -274,11 +274,6 @@ nla_put_failure:
	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)
{
	struct list_head *pos;
@@ -327,6 +322,4 @@ void __init fib4_rules_init(void)
	list_add_tail(&default_rule.common.list, &fib4_rules);

	fib_rules_register(&fib4_rules_ops);

	rtnl_register(PF_INET, RTM_GETRULE, NULL, fib4_rule_dump);
}
Loading